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