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

  • Vorverstärker #2 (final)

    (Schuljahr 2014/2015) Dieser Vorverstärker entstand als Abschlussprojekt der Techniker-Ausbildung und ist die Weiterführung und Vollendung des Vorverstärkers #2. Da ich hier nicht all das, was schon in der zugehörigen Facharbeit geschrieben wurde, nochmals aufwärmen will, gibt’s gleich die gesamte Arbeit (bis auf etwas Vorgeplänkel am Anfang) als *.pdf und das zugehörige µC-Programm noch oben drauf.Viel…

  • Verstärker #1 Class-AB

    (irgendwann bis März 2007) So, hier ein Projekt das es nie wirklich weit gebracht hat, obwohl der Class-AB Verstärker zeitweise „sogar“ funktionstüchtig war …Das ganze ist ein so genannter „Symp-Amp“ Pläne etc. habe ich mittlerweile nicht mehr. Ich kann nur sagen das Idee, Layout, etc. nicht von mir kommt.Die Quelle der Pläne war glaube ich…

  • Verstärker #2 Class-T

    (ewig und drei Tage) Dies ist ein Bausatz von der Seite 41hz.com, welche mittlerweile nicht mehr verfügbar ist. Grundstein ist ein Class-T-Chip der Firma Tripath, welcher Vorteile von Analog- und Digitaltechnik vereinen und somit besonders gut klingen soll. daher kommt auch die Bezeichnung Verstärker Class-T. Da hier ein großer Teil in SMD-Technik verlötet werden muss,…

  • Vorverstärker #1

    (Juli – November 2006) Wie auch meinen 1.Verstärker wollte ich zu Anfang meiner Ausbildung auch einen Vorverstärker bauen. Denn was bringt ein Verstärker den ich in keiner Weise einstellen kann (Lautstärke, Höhen, Tiefen, …)?(Den Prototypen des Vorverstärkers hatte ich sogar schon vor dem Verstärker #1 Class-AB gebaut.)Also habe ich einen einfachen Vorverstärker zum nachbauen gesucht….

  • Word-Clock

    (Januar und Mai 2010) Angefangen hat das Projekt damit, dass ich die komplette Word-Clock selbst entwickeln wollte. Jedoch bildete sich, kurz nachdem ich mit der Planung dazu angefangen hatte, eine Gruppe im Mikrocontroller-Forum, die sich auch mit der Entwicklung befasst hat. Somit habe ich mich ebenfalls dabei eingeklinkt. Aus diversen Beiträgen etc. wurde mittlerweile sogar…

  • Vorverstärker #2

    (Mitte 2008 – 2010) An diesem Vorverstärker-Projekt arbeite ich echt schon ewig …Oft habe ich angefangen, wieder etwas geändert, überarbeitet, komplett anders gemacht und auch nur mal zwischendurch überhaupt etwas dran gearbeitet. Ein echtes Dauerprojekt halt.Ein Großteil dessen was hier im Moment zu sehen ist, funktioniert auch schon. Hier einige Quellen, die ich für dieses…

Schreibe einen Kommentar

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