0,0 → 1,148 |
/***************************************************************************************************************************** |
* File: analog.c |
* |
* Purpose: collecting ADC analog inputs |
* |
* Functions: void ADC_Init(void) |
* ISR(ADC_vect) |
* |
*****************************************************************************************************************************/ |
#include "analog.h" |
|
|
#include <stdlib.h> |
#include <avr/interrupt.h> |
|
volatile int AdWertNick=0, AdWertAccNick, Aktuell_ax; |
int NeutralAccX = 511; |
volatile unsigned char AdReady = 1; |
|
|
|
// ************************************************************************************************************************** |
// Purpose: set up ADC |
// |
// INPUT: None |
// OUTPUT: None |
// RETURN: None |
// -------------------------------------------------------------------------------------------------------------------------- |
void init_ADC(void) |
{ |
static unsigned char sreg; // temporary variable to store SREG |
|
sreg = SREG; // save backup status register , to be reseted later |
cli(); // switch off Global Interrupt |
|
// ADMUX = ADC Multiplexer Selection Register > REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0 |
// ----------------------------------------------------------------------------------------- |
// REFS1:0 = Reference Selection Bits |
// ADLAR = ADC Left Adjust Result |
// MUX4:0 = Analog Channel and Gain Selection Bits |
// |
ADMUX &= ~((1 << REFS1)|(1<<REFS0)); // AREF is the reference and Internal Vref is turned off |
ADMUX &= ~(1 << ADLAR); // the result is right side edge |
ADMUX &= ~((1<<MUX4)|(1<<MUX3)|(1<<MUX2)|(1<<MUX1)|(1<<MUX0)); // the analog input is connected to ADC0 = PORTA0 = port S21 |
|
// SFIOR = Special Function IO Register > ADTS2 ADTS1 ADTS0 ACME PUD PSR2 PSR10 |
//--------------------------------------------------------------------------------- |
SFIOR &= ~((1<<ADTS2)|(1<<ADTS2)|(1<<ADTS0)); // ADTS2:0 = ADC Auto Trigger Source = 000 = Free Running mode |
|
// ADCSRA = Analog Digital Conversion Status Register A -> ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0 |
// ---------------------------------------------------------------------------------------------------- |
// ADEN = AD Wandler enable |
// ADSC = start conversion |
// ADATE = auto trigger ein |
// ADIF = interrupt flag -> This bit is set when an ADC conversion completes and the Data Registers are updated |
// ADIE = Analog to Dig Conversion Interrupt Enable |
// ADPS = Prescaler = 111 = Division Factor 128 |
// |
ADCSRA |= (1<<ADEN)|(1<<ADSC)|(1<<ADIF)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); |
ADCSRA &= ~((1<<ADATE)); |
|
SREG = sreg; // write back to old state, |
sei(); // switch on Global Interrupt |
} |
// *** EOF: init_ADC() ************************************************************************************************************** |
|
|
|
|
// ********************************************************************************************************************************* |
// read analog inputs from ADC with the following sequence: |
// ------------------------------------------------------------------------------------------------ |
// cases: |
// 0 nick-gyro |
// 1 x acc nick |
// 2 nick-gyro |
// 3 nick-gyro |
// 4 x acc nick |
// 5 nick-gyro |
// ------------------------------------------------------------------------------------------------ |
// Chanels: |
// PA0 Gyro Gier |
// PA1 Gyro Roll |
// PA2 Gyro Nick |
// PA3 Air Pressure |
// PA4 Voltage |
// PA5 ACC H |
// PA6 ACC Roll |
// PA7 ACC Nick |
// ------------------------------------------------------------------------------------------------ |
ISR(ADC_vect) |
{ |
static unsigned char kanal=AD_NICK, state = 0; |
static signed int nick1, accx; |
|
switch(state++) |
{ |
case 0: |
nick1 = ADC; // 1st measure of Nick Gyro Sensor |
kanal = AD_ACC_X; |
break; |
|
case 1: |
Aktuell_ax = ADC - NeutralAccX; // 1st measure of ACC Nick Sensor |
accx = Aktuell_ax; |
kanal = AD_NICK; |
break; |
|
case 2: |
nick1 += ADC; // 2nd measure of Nick Gyro Sensor |
kanal = AD_NICK; |
break; |
|
case 3: |
nick1 += ADC; // 3rd measure of Nick Gyro Sensor |
kanal = AD_ACC_X; |
break; |
|
case 4: |
Aktuell_ax = ADC - NeutralAccX; |
AdWertAccNick = (Aktuell_ax + accx); // 2nd measure of ACC Nick Sensor 0...512 |
kanal = AD_NICK; |
break; |
|
case 5: |
nick1 += ADC; // 4th measure of Nick Gyro |
AdWertNick = nick1 / 8; // AdWertNick = 0...511 |
kanal = AD_NICK; |
break; |
|
case 6: |
AdReady = 1; // all cases have been passed -> analog conversion ready |
state = 0; |
kanal = AD_NICK; |
break; |
|
default: |
kanal = 0; state = 0; kanal = AD_NICK; |
break; |
} |
ADMUX = kanal; // ADMUX = ADC Multiplexer Selection Register |
|
// ADCSRA = Analog Digital Conversion Status Register A -> ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0 |
// ADSC = start conversion |
if(state != 0) ADCSRA |= (1<<ADSC); |
|
} |
// *** EOF : ISR(ADC_vect) ********************************************************************************************************** |