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