EKG

(Schuljahr 2013) Im ersten Schuljahr der Techniker-Ausbildung entstand dieses EKG-Projekt im Rahmen zweier Module. Da in dem unten angehängten *.pdf alles genau beschrieben ist, verzichte ich hier weiter darauf einzugehen.
Es handelt sich um ein gemeinsames Projekt mit meinem Projektpartner: Steffen Sieberger (sieberger.steffen@gmail.com)

Ausarbeitung

PC-Software (benötigt LabView-Runtime)

/*
 * EKG.c
 *
 * Created: 12.11.2013 13:38:26
 *  Author: Simon Kappes, Steffen Sieberger
 */ 

//==============================Bibliotheken + CPU-Takt Definition==============================
#define F_CPU 3686400		//µC-Takt definiern
#include <avr\io.h>			//Registernamen
#include <avr/interrupt.h>	//Interrupts
#include <stdint.h>			//Datentypen

//==============================Globale Vaiablen==============================
unsigned char UARTDatenEmpfangen = 1;	//1 = String wurde vom PC komplett empfangen + 0 = Freigabe zum Empfang eines weiteren Strings
volatile uint8_t SteuerbitsSend = 0;	//zu sendende Steuerbits
/*	Bit0 (Betriebmodus)
		0 = LiveView-Modus
		1 = EEPROM-Modus
	Bit1 (Watchdog)
	Bit2 (Übertragung aus EEPROM)
		0 = keine Übertragung
		1 = Übertragung läuft*/
volatile uint8_t SteuerbitsEmpf = 0;	//empfangene Steuerbits
/*	Bit0 (Anforderung von Daten aus dem EEPROM)
		0 = keine Daten angefordert
		1 = Daten angefordert
	Bit1 (Watchdog)
	Bit2 (Alarm/Puls)
		0 = nichts ausgeben
		1 = Alarm/Puls*/
volatile uint8_t Messwert = 255;		//Messwert
uint16_t Index = 0;						//Index für EEPROM-Modus (Adressen)

//==============================Funktionen==============================
//UART
void sendeUART(char Daten)	//Daten per UART senden
{
	while (!(UCSRA & (1<<UDRE)));	//Endlosschleife solange UDR nicht leer ist
	UDR = Daten;					//Daten zum Senden übergeben
}
void sende()				//Strings an PC senden
{
	SteuerbitsSend ^= (1<<1);	//Watchdog-Bit toggeln
	sendeUART(SteuerbitsSend);
	sendeUART(Messwert);
	sendeUART('\n');			//Endzeichen des Strings senden
	UARTDatenEmpfangen = 0;		//Freigabe für Empfang weiterer Strings
}
//EEPROM
void EEPROMschreiben(uint8_t Wert, uint16_t Stelle)	//Daten ins EEPROM schreiben
{
		while(EECR & (1<<1));	//Warte bis vorherige Schreibaktion abgeschlossen
		EEAR = Stelle;			//Adresse übergeben
		EEDR = Wert;			//zu schreibende Daten übergeben
		EECR = 0x04;			//EEPROM Write Enabled
		EECR = 0x06;			//EEPROM Write
}
uint8_t EEPROMlesen(uint16_t Stelle)				//Daten vom EEPROM auslesen
{
	uint8_t gelesen;
	EEAR = Stelle;					//Adresse an EEAR übergeben
	EECR |= 0b00000001;				//Leseaufforderung
	while (EECR & (1<<0));			//warte auf Fertigmeldung
	gelesen = EEDR;					//Daten aus EEDR übernehmen
	return gelesen;
}
//Sonstige
uint8_t AD_Wandlung()			//Analog-Digital-Wandlung
{
	uint16_t Wert = 0;
	cli();							//globale Interrupts deaktivieren
	ADMUX = 0b00000001;				//Kanal 1 für ADC auswählen
	ADMUX |= (1<<REFS0);			//AVCC als Referenzspannung
	ADMUX &= ~(1<<ADLAR);			//Wandlungsergebnis rechtsbündig
	ADCSRA = 0b11000101;			//Frequenzvorteiler auf 32 setzen und ADC0 als Analogeingangsbit aktivieren
	while(bit_is_set(ADCSRA,ADSC));	//auf Wandlungsende warten
	Wert = (ADCW/4);				//Wert übergeben und auf 8-Bit umrechnen
	sei();							//globale Interrupts aktivieren
	return Wert;
}
void Herzschlag(uint8_t Wert)	//optischer Herzschlag
{
	OCR1A = ((Wert-127)/6);	//Anpassung der LED-Helligkeit und Ausgabe des Wertes
}	 
void Summer()					//akustischer Herzschlag/Alarm
{
	if (bit_is_clear (PINB, 4) && bit_is_set (SteuerbitsEmpf, 2))	//Wenn Summer eingeschaltet und Impuls kommt
	{PORTC |= (1<<PC0);}		//Summer ein
	else {PORTC &= ~(1<<PC0);}	//Summer aus
}

//==============================Interrupts==============================
ISR(USART_RXC_vect)		//Daten über USART empfangen (als Interrupt um nicht währenddessen unterbrochen zu werden)
{
	SteuerbitsEmpf = UDR;	//Empfangene Daten übernehmen (UDR ist ein FIFO-Speicher)
	UARTDatenEmpfangen = 1;	//"Daten wurden empfangen" setzen
}
ISR(TIMER0_OVF_vect)	//Messung im EEPROM-Modus
{
	Messwert = AD_Wandlung();
	Herzschlag(Messwert);
	EEPROMschreiben(Messwert, Index);
	PORTB ^= (1<<0);					//EEPROM-LED toggeln
	Index++;
	if (Index>=512)						//Wenn EEPROM voll beschrieben
	{
		TIMSK &= ~(1<<TOIE0);			//Interrupts für Timer-Overflow deaktivieren
		UCSRB |= (1 << RXCIE);			//Interrupts für UART aktivieren
		Index = 0;						//Index zurücksetzen
	}
	TCNT0 = 183;						//bei 183 mit Zählen beginnen (Overflow bei 0,02s. Entspricht 72 Takte bei 1024 als Vorteiler)
}

//==============================Programm==============================
int main(void)
{
//Datenrichtung einstellen------------------------------
/*	PortB.0	=>	LED EEPROM-Modus
	PortB.1	=>	LED Herzschlag
	PortB.2	=>	LED LabView-Modus
	PortB.3	<=	Betriebswahl	
	PortB.4	<=	Summer ein/aus
	PortB.5	<=	Messung starten (EEPROM)
	PortC.0	=>	Summer
	PortC.1	<=	Messsignal*/
	DDRD = 0b00000000;	//PortD = Eingänge
	DDRB = 0b00000111;	//PortB = Pin0-2(Ausgänge)	/	Pin 3-7(Eingänge)
	DDRC = 0b00000001;	//PortC = Pin0 (Ausgang		/	Pin1-7(Eingänge)
	PORTD = 0b11111111;	//Pull-Ups aktivieren
	PORTB = 0b11111000;	//Pull-Ups aktivieren	/	Ausgänge ausschalten
	PORTC = 0b11111110;	//Pull-Ups aktivieren	/	Ausgänge ausschalten
//UART Einstellungen------------------------------
	UBRRL = 23;			//9600 Baud (siehe Baudratentabelle)
	UCSRB = (1<<RXCIE) | (1<<RXEN) | (1<<TXEN);		//Interrupts ein /Receiver ein /Transmitter ein
	UCSRC = (1<<URSEL) | (1<<UCSZ0) | (1<<UCSZ1);	//Register Select /Character Size (8Bit)
//Timer 1 (PWM für Herzschlag-LED)------------------------------
	TCCR1A = (1<<COM1A1) | (1<<WGM10);	//Fast PWM(8-bit), Compare Match Mode
	TCCR1B = (1<<WGM12);				//Fast PWM(8-bit)
	OCR1A = 0;							//PWM-Wert (0-255), 0 = aus, 1-255 = ein
	TCCR1B = (1<<CS10) | (1<<CS11);		//Vorteiler(Prescaler) auf 64
//Timer 0 (für Messwertermittlung im EEPROM-Modus)------------------------------
	TCCR0 = (1<<CS00) | (1<<CS02);		//Prescaler auf 1024
	TCNT0 = 183;						//bei 183 mit Zählen beginnen (Overflow bei 0,02s. Entspricht 72 Takte bei 1024 Vorteiler)
//Sonstiges------------------------------
	sei();								//globale Interrupts aktivieren

//------------------------------Hauptprogramm------------------------------
    while(1)
    {
//EEPROM-Modus------------------------------
		if (bit_is_clear (PINB, 3))
		{
			PORTB |= (1<<PB0);									//Betriebsmodus-LED EEPROM ein
			PORTB &= ~(1<<PB2);									//Betriebsmodus-LED LabView aus
			SteuerbitsSend |= (1<<0);							//Betriebsmodus (EEPROM) zur Übermittlung an LabView setzen
//Anforderung von Daten aus dem EEPROM------------------------------
			if (bit_is_set (SteuerbitsEmpf, 0) && (Index==0))
			{
				TIMSK &= ~(1<<TOIE0);							//Interrupts für Timer-Overflow deaktivieren
				SteuerbitsSend |= (1<<2);						//Sende-Bit setzen
				for (Index=0; Index<=511; Index++)				//bis EEPROM komplett gesendet ist
				{
					Messwert = EEPROMlesen(Index);
					sende();
				}
				SteuerbitsSend &= ~(1<<2);						//Sende-Bit rücksetzen
				sende();
				while (bit_is_set (SteuerbitsEmpf, 0));			//warte auf Bestätigung das Daten empfangen wurden (um mehrmaliges senden zu verhindern)
				Index = 0;										//Index zurücksetzen
			}
//Messung starten------------------------------
			if (bit_is_clear (PINB, 5))
			{
				TIMSK |= (1<<TOIE0);							//Interrupts für Timer-Overflow aktivieren
				UCSRB &= ~(1<<RXCIE);							//Interrupts für UART deaktivieren
				while(bit_is_set(TIMSK,TOIE0));					//warte solange wie Timer-Interrupt aktiv ist
			}
			if(UARTDatenEmpfangen == 1)							//Wenn String komplett Empfangen wurde
			{sende();}
		}
//LabView-Modus------------------------------
		if (bit_is_set (PINB, 3))
		{
			PORTB |= (1<<PB2);									//Betriebsmodus-LED LabView ein
			PORTB &= ~(1<<PB0);									//Betriebsmodus-LED EEPROM aus
			SteuerbitsSend &= ~(1<<0);							//Betriebsmodus (LabView) zur Übermittlung an LabView setzen
			if(UARTDatenEmpfangen == 1)							//Wenn String komplett Empfangen wurde
			{
				sende();
				Messwert = AD_Wandlung();
				Herzschlag(Messwert);
				Summer();
 			}	
		}
    }
}

Ähnliche Beiträge

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert