162_ICP_DDS_01.c
1 | // Atmega 162 Messung der Herzfrequenz über ICP, Berechnung der daraus
| 2 | //resultierenden Therapiefrequenz und deren Synthese mit DDS 24.1.2011
| 3 |
| 4 | #include <inttypes.h>
| 5 | #include <avr/interrupt.h>
| 6 | #include <avr/io.h>
| 7 | #include <stdint.h>
| 8 | #include <stdlib.h>
| 9 | #include <string.h>
| 10 | #include <avr/io.h>
| 11 |
| 12 | #ifndef TRUE
| 13 | #define TRUE 1
| 14 | #define FALSE 0
| 15 | #endif
| 16 |
| 17 | //Variablen für ICP
| 18 |
| 19 | volatile unsigned char NrOverflows = 0; // Anzahl der Timer Overflows zwischen den beiden Flanken
| 20 | volatile unsigned short StartTime = 0; // ICR-Wert bei 1.High-Flanke speichern
| 21 | volatile unsigned short EndTime = 0; // ICR-Wert bei 2.High-Flanke speichern
| 22 | volatile unsigned char Pulsmess; // Job Flag
| 23 |
| 24 | //Variablen für DDS
| 25 | volatile uint32_t FCW;
| 26 | volatile uint32_t Tabellenposition;
| 27 |
| 28 | volatile unsigned char Tabelle [256]=
| 29 | {
| 30 | 0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,
| 31 | 0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
| 32 | 0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,
| 33 | 0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
| 34 | 0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,
| 35 | 0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
| 36 | 0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,
| 37 | 0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
| 38 | 0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,
| 39 | 0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
| 40 | 0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,
| 41 | 0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
| 42 | 0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,
| 43 | 0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
| 44 | 0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,
| 45 | 0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
| 46 | 0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,
| 47 | 0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,
| 48 | 0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,
| 49 | 0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,
| 50 | 0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,
| 51 | 0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,
| 52 | 0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,
| 53 | 0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
| 54 | 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,
| 55 | 0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
| 56 | 0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,
| 57 | 0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
| 58 | 0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,
| 59 | 0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,
| 60 | 0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,
| 61 | 0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c
| 62 | };
| 63 |
| 64 |
| 65 |
| 66 | // ICP Initialisierung mit Timer 1
| 67 | void initTimer1()
| 68 | {
| 69 | TCCR1B = (1<<ICES1) | (1<<CS12) ; // Input Capture Edge, PreScale 256 kein Noise cancler, da der auf
| 70 | // auf 4 gleichartige Signale wartet!
| 71 | TIMSK = (1<<TICIE1) | (1<<TOIE1); // Interrupts akivieren, Capture + Overflow
| 72 | }
| 73 |
| 74 | // CTC Initialisiserung mit Timer 3
| 75 |
| 76 | void initTimer3()
| 77 | {
| 78 | TCCR3B = (1<<WGM32) | (1<<CS30); // no prescale, CTC (Top OCR3A)
| 79 | OCR3A = 1024;
| 80 | ETIMSK |= (1<<OCIE3A); // Interruptauslösung bei OCR3A compare match
| 81 | }
| 82 |
| 83 | // Port B initialisieren
| 84 |
| 85 | void initPorts()
| 86 | {
| 87 | DDRB = 0xFF; // Port B als Ausgang für DDS Signal
| 88 | PORTB = 0;
| 89 | //DDRA = (1<<PA1);
| 90 | }
| 91 |
| 92 | // PulsLED initialisieren
| 93 | //void Puls()
| 94 | //{
| 95 |
| 96 | //ISR zur Messung des Eingangsignales
| 97 |
| 98 | ISR( TIMER1_CAPT_vect )
| 99 | {
| 100 | static unsigned char ErsteFlanke = TRUE;
| 101 |
| 102 | // Bei der ersten Flanke beginnt die Messung, es wird der momentane
| 103 | // Timer beim Input Capture als Startwert gesichert
| 104 | //
| 105 | if( ErsteFlanke )
| 106 | {
| 107 | DDRA^=(1<<PA2); // Puls Anzeige mit LED
| 108 | StartTime = ICR1;
| 109 | NrOverflows = 0;
| 110 | ErsteFlanke = FALSE; // Die naechste Flanke ist das Ende der Messung
| 111 | }
| 112 |
| 113 | //
| 114 | // das ist die zweite Flanke im Messzyklus. Die Messung wird gestoppt
| 115 | //
| 116 | else
| 117 | {
| 118 | EndTime = ICR1;
| 119 | Pulsmess = TRUE; // Eine vollständige Messung. Sie kann ausgewertet werden
| 120 | ErsteFlanke = TRUE; // Bei der naechsten Flanke beginnt der naechste Messzyklus
| 121 | }
| 122 | }
| 123 |
| 124 |
| 125 | ISR( TIMER1_OVF_vect ) // Zählung der Overflows von Timer1
| 126 | {
| 127 | NrOverflows++;
| 128 | }
| 129 |
| 130 | // DDS Phasenincrement, Tabellenposition ist Phasenakkumulator
| 131 | ISR(TIMER3_COMPA_vect)
| 132 | {
| 133 | uint32_t i;
| 134 | Tabellenposition +=FCW;
| 135 | i = Tabellenposition >> 24 ;
| 136 | PORTB = Tabelle [i];
| 137 | }
| 138 |
| 139 |
| 140 |
| 141 | int main()
| 142 | {
| 143 | unsigned long Erg = 0; // Variable für IPC
| 144 | unsigned long Faktor = 0; // Variable für Ausgangssignalberechnung
| 145 | unsigned long signal = 0; // Signal in mHz
| 146 |
| 147 |
| 148 | initPorts();
| 149 | initTimer3();
| 150 | initTimer1();
| 151 | sei();
| 152 |
| 153 | while(1)
| 154 | {
| 155 | // kein Pulssignal nach 4,5 sec detektiert? Warnanzeige an und Therapiesignal aus
| 156 | if (NrOverflows > 1 )
| 157 | {
| 158 | DDRB = 0x00; // DDS Signal aus
| 159 | DDRA = (1<<PA0)|(1<<PA1); // "kein Signal"Warn LED PA0 an, Betriebsanzeige an
| 160 | }
| 161 |
| 162 | // liegt eine vollständige Messung vor?
| 163 | else if(Pulsmess)
| 164 | {
| 165 |
| 166 | DDRB = 0xFF; // DDS Signal an
| 167 | DDRA =(0<<PA0)|(1<<PA1); //"kein Signal"Warn LED PA0 aus, Betriebsanzeige an
| 168 |
| 169 |
| 170 | // Berechnung der Subharmonischen
| 171 | Erg = (NrOverflows * 65536) + EndTime - StartTime;
| 172 |
| 173 |
| 174 | Erg = Erg*100 / 144; // Ergebnis in Millisekunden (*10 wg höherer
| 175 | //Auflösung d.h.5-6 Stellen)
| 176 |
| 177 | Faktor = Erg*65 / 10000; // ganzzahliger Faktor zur Berechnung
| 178 | // des Therapiesignales, zweistellig
| 179 |
| 180 | signal = Faktor*10000000 / Erg; //Berechnung des Therapievorsignals
| 181 | // im Bereich zwischen 63000 und 65000 mHz
| 182 |
| 183 | FCW = (signal*4294967296 / 3600) / 1000; // FCW für Therapiesignal DDS
| 184 | // Umwandlung mHz in Hz mit drei Nachkommastellen durch FCW / 1000
| 185 |
| 186 | Pulsmess = FALSE;
| 187 | } //else if
| 188 | } //while
| 189 | } //main
|
|