Subversion Repositories FlightCtrl

Rev

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) **********************************************************************************************************