Blame |
Last modification |
View Log
| RSS feed
/*****************************************************************************************************************************
* File: analog.c
*
* Purpose: collecting ADC analog inputs
*
* Functions: void ADC_Init(void)
* ISR(ADC_vect)
*
* Created: Feb 2013
*
* Version: 1.00 experimental version
*
* Copyright: (c)2013 dk9nw -at- darc.de
* All rights reserved. This software is available only for non-commercial amateur radio or educational applications.
* Other uses are prohibited. This software may be modified only if
* the resulting code be made available publicly and the original author(s) given credit.
*
*****************************************************************************************************************************/
#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) **********************************************************************************************************