Rev 624 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | ingob | 1 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 | // + Copyright (c) 04.2007 Holger Buss |
||
3 | // + only for non-profit use |
||
4 | // + www.MikroKopter.com |
||
5 | // + see the File "License.txt" for further Informations |
||
6 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
||
7 | |||
8 | #include "main.h" |
||
9 | |||
683 | killagreg | 10 | volatile int16_t Current_Nick = 0, Current_Roll = 0, Current_Gier = 0; |
11 | volatile int16_t Current_AccX = 0, Current_AccY = 0, Current_AccZ = 0; |
||
12 | volatile int16_t UBat = 100; |
||
13 | volatile int16_t AdValueGyrNick = 0, AdValueGyrRoll = 0, AdValueGyrGier = 0; |
||
14 | volatile int16_t AdValueAccRoll = 0, AdValueAccNick = 0, AdValueAccTop = 0; |
||
15 | volatile uint8_t messanzahl_AccHoch = 0; |
||
16 | volatile int32_t Luftdruck = 32000; |
||
17 | volatile int16_t StartLuftdruck; |
||
18 | volatile uint16_t MessLuftdruck = 1023; |
||
19 | uint8_t DruckOffsetSetting; |
||
20 | volatile int16_t HoeheD = 0; |
||
21 | volatile int16_t tmpLuftdruck; |
||
22 | volatile uint16_t ZaehlMessungen = 0; |
||
1 | ingob | 23 | |
683 | killagreg | 24 | /*****************************************************/ |
25 | /* Initialize Analog Digital Converter */ |
||
26 | /*****************************************************/ |
||
1 | ingob | 27 | void ADC_Init(void) |
683 | killagreg | 28 | { |
29 | uint8_t sreg = SREG; |
||
30 | // disable all interrupts before reconfiguration |
||
31 | cli(); |
||
32 | //ADC0 ... ADC7 is connected to PortA pin 0 ... 7 |
||
33 | DDRA = 0x00; |
||
34 | PORTA = 0x00; |
||
35 | // Digital Input Disable Register 0 |
||
36 | // Disable digital input buffer for analog adc_channel pins |
||
37 | DIDR0 = 0xFF; |
||
38 | // external reference, adjust data to the right |
||
39 | ADMUX &= ~((1 << REFS1)|(1 << REFS0)|(1 << ADLAR)); |
||
40 | // set muxer to ADC adc_channel 0 (0 to 7 is a valid choice) |
||
41 | ADMUX = (ADMUX & 0xE0) | 0x00; |
||
42 | //Set ADC Control and Status Register A |
||
43 | //Auto Trigger Enable, Prescaler Select Bits to Division Factor 128, i.e. ADC clock = SYSCKL/128 = 156.25 kHz |
||
44 | ADCSRA = (1<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); |
||
45 | //Set ADC Control and Status Register B |
||
46 | //Trigger Source to Free Running Mode |
||
47 | ADCSRB &= ~((1 << ADTS2)|(1 << ADTS1)|(1 << ADTS0)); |
||
48 | // Enable AD conversion |
||
49 | ADC_Enable(); |
||
50 | // restore global interrupt flags |
||
51 | SREG = sreg; |
||
1 | ingob | 52 | } |
53 | |||
54 | void SucheLuftruckOffset(void) |
||
55 | { |
||
56 | unsigned int off; |
||
173 | holgerb | 57 | off = eeprom_read_byte(&EEPromArray[EEPROM_ADR_LAST_OFFSET]); |
58 | if(off > 20) off -= 10; |
||
59 | OCR0A = off; |
||
380 | hbuss | 60 | Delay_ms_Mess(100); |
173 | holgerb | 61 | if(MessLuftdruck < 850) off = 0; |
62 | for(; off < 250;off++) |
||
1 | ingob | 63 | { |
64 | OCR0A = off; |
||
380 | hbuss | 65 | Delay_ms_Mess(50); |
683 | killagreg | 66 | printf("."); |
1 | ingob | 67 | if(MessLuftdruck < 900) break; |
68 | } |
||
173 | holgerb | 69 | eeprom_write_byte(&EEPromArray[EEPROM_ADR_LAST_OFFSET], off); |
70 | DruckOffsetSetting = off; |
||
380 | hbuss | 71 | Delay_ms_Mess(300); |
1 | ingob | 72 | } |
73 | |||
74 | |||
683 | killagreg | 75 | /*****************************************************/ |
76 | /* Interrupt Service Routine for ADC */ |
||
77 | /*****************************************************/ |
||
78 | ISR(ADC_vect) |
||
1 | ingob | 79 | { |
683 | killagreg | 80 | static uint8_t adc_channel = 0, state = 0; |
81 | static uint16_t gier1, roll1, nick1; |
||
82 | static uint8_t messanzahl_Druck = 0; |
||
83 | // disable further AD conversion |
||
84 | ADC_Disable(); |
||
85 | // state machine |
||
1 | ingob | 86 | switch(state++) |
87 | { |
||
88 | case 0: |
||
683 | killagreg | 89 | gier1 = ADC; // get Gyro Gier Voltage 1st sample |
90 | adc_channel = 1; // set next channel to ADC1 = ROLL GYRO |
||
91 | ZaehlMessungen++; // increment total measurement counter |
||
1 | ingob | 92 | break; |
93 | case 1: |
||
683 | killagreg | 94 | roll1 = ADC; // get Gyro Roll Voltage 1st sample |
95 | adc_channel = 2; // set next channel to ADC2 = NICK GYRO |
||
1 | ingob | 96 | break; |
97 | case 2: |
||
683 | killagreg | 98 | nick1 = ADC; // get Gyro Nick Voltage 1st sample |
99 | adc_channel = 4; // set next channel to ADC4 = UBAT |
||
1 | ingob | 100 | break; |
101 | case 3: |
||
683 | killagreg | 102 | // get actual UBat (Volts*10) is ADC*30V/1024*10 = ADC/3 |
103 | UBat = (3 * UBat + ADC / 3) / 4; // low pass filter updates UBat only to 1 quater with actual ADC value |
||
104 | adc_channel = 6; // set next channel to ADC6 = ACC_Y |
||
1 | ingob | 105 | break; |
106 | case 4: |
||
683 | killagreg | 107 | Current_AccY = NeutralAccY - ADC; // get acceleration in Y direction |
108 | AdValueAccRoll = Current_AccY; |
||
109 | adc_channel = 7; // set next channel to ADC7 = ACC_X |
||
1 | ingob | 110 | break; |
111 | case 5: |
||
683 | killagreg | 112 | Current_AccX = ADC - NeutralAccX; // get acceleration in X direction |
113 | AdValueAccNick = Current_AccX; |
||
114 | adc_channel = 0; // set next channel to ADC7 = GIER GYRO |
||
1 | ingob | 115 | break; |
116 | case 6: |
||
683 | killagreg | 117 | // average over two samples to create current ADValueGier |
118 | if(PlatinenVersion == 10) AdValueGyrGier = (ADC + gier1) / 2; |
||
119 | else AdValueGyrGier = ADC + gier1; // gain is 2 times lower on FC 1.1 |
||
120 | adc_channel = 1; // set next channel to ADC7 = ROLL GYRO |
||
401 | hbuss | 121 | break; |
122 | case 7: |
||
683 | killagreg | 123 | // average over two samples to create current ADValueRoll |
124 | if(PlatinenVersion == 10) AdValueGyrRoll = (ADC + roll1) / 2; |
||
125 | else AdValueGyrRoll = ADC + roll1; // gain is 2 times lower on FC 1.1 |
||
126 | adc_channel = 2; // set next channel to ADC2 = NICK GYRO |
||
401 | hbuss | 127 | break; |
128 | case 8: |
||
683 | killagreg | 129 | // average over two samples to create current ADValueNick |
130 | if(PlatinenVersion == 10) AdValueGyrNick = (ADC + nick1) / 2; |
||
131 | else AdValueGyrNick = ADC + nick1; // gain is 2 times lower on FC 1.1 |
||
132 | adc_channel = 5; // set next channel to ADC5 = ACC_Z |
||
401 | hbuss | 133 | break; |
134 | case 9: |
||
683 | killagreg | 135 | // get z acceleration |
136 | AdValueAccTop = (int16_t) ADC - NeutralAccZ; // get plain acceleration in Z direction |
||
137 | AdValueAccTop += abs(Current_AccY) / 4 + abs(Current_AccX) / 4; |
||
138 | if(AdValueAccTop > 1) |
||
1 | ingob | 139 | { |
683 | killagreg | 140 | if(NeutralAccZ < 800) NeutralAccZ+= 0.02; |
141 | } |
||
142 | else if(AdValueAccTop < -1) |
||
1 | ingob | 143 | { |
144 | if(NeutralAccZ > 600) NeutralAccZ-= 0.02; |
||
683 | killagreg | 145 | } |
1 | ingob | 146 | messanzahl_AccHoch = 1; |
683 | killagreg | 147 | Current_AccZ = ADC; |
148 | Mess_Integral_Hoch += AdValueAccTop; // Integrieren |
||
1 | ingob | 149 | Mess_Integral_Hoch -= Mess_Integral_Hoch / 1024; // dämfen |
683 | killagreg | 150 | adc_channel = 3; // set next channel to ADC3 = air pressure |
1 | ingob | 151 | break; |
401 | hbuss | 152 | case 10: |
683 | killagreg | 153 | tmpLuftdruck += ADC; // sum vadc values |
154 | if(++messanzahl_Druck >= 5) // if 5 values are summerized for averaging |
||
1 | ingob | 155 | { |
683 | killagreg | 156 | MessLuftdruck = ADC; // update measured air pressure |
157 | messanzahl_Druck = 0; // reset air pressure measurement counter |
||
158 | HoeheD = (int16_t)(StartLuftdruck - tmpLuftdruck - HoehenWert); // D-Anteil = neuerWert - AlterWert |
||
159 | Luftdruck = (tmpLuftdruck + 3 * Luftdruck) / 4; // averaging using history |
||
1 | ingob | 160 | HoehenWert = StartLuftdruck - Luftdruck; |
161 | tmpLuftdruck = 0; |
||
683 | killagreg | 162 | } |
163 | adc_channel = 0; // set next channel to ADC0 = GIER GYRO |
||
164 | state = 0; // reset state |
||
1 | ingob | 165 | break; |
683 | killagreg | 166 | default: |
167 | adc_channel = 0; |
||
1 | ingob | 168 | state = 0; |
169 | break; |
||
683 | killagreg | 170 | } |
171 | // set adc muxer to next adc_channel |
||
172 | ADMUX = (ADMUX & 0xE0) | adc_channel; |
||
173 | // ?? |
||
174 | if(state != 0) ADC_Enable(); |
||
1 | ingob | 175 | } |