Subversion Repositories Projects

Rev

Rev 273 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
273 killagreg 1
 
2
#include <stdlib.h>
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
 
6
#include "analog.h"
7
 
8
volatile int16_t Adc0, Adc1, Adc2, Adc3, Adc4, Adc5, Adc6, Adc7;
9
volatile uint8_t ADReady = 1;
10
 
11
/*****************************************************/
12
/*     Initialize Analog Digital Converter           */
13
/*****************************************************/
14
void ADC_Init(void)
15
{
16
        uint8_t sreg = SREG;
17
        // disable all interrupts before reconfiguration
18
        cli();
19
        //ADC0 ... ADC7 is connected to PortA pin 0 ... 7
20
        DDRA = 0x00;
21
        PORTA = 0x00;
22
        // Digital Input Disable Register 0
23
        // Disable digital input buffer for analog adc_channel pins
24
        DIDR0 = 0xFF;
275 killagreg 25
        // external reference AREF, adjust data to the right
273 killagreg 26
    ADMUX &= ~((1 << REFS1)|(1 << REFS0)|(1 << ADLAR));
27
    // set muxer to ADC adc_channel 0 (0 to 7 is a valid choice)
28
    ADMUX = (ADMUX & 0xE0) | 0x00;
29
    //Set ADC Control and Status Register A
30
    //Auto Trigger Enable, Prescaler Select Bits to Division Factor 128, i.e. ADC clock = SYSCKL/128 = 156.25 kHz
31
        ADCSRA = (0<<ADEN)|(0<<ADSC)|(0<<ADATE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(0<<ADIE);
32
        //Set ADC Control and Status Register B
33
        //Trigger Source to Free Running Mode
34
        ADCSRB &= ~((1 << ADTS2)|(1 << ADTS1)|(1 << ADTS0));
35
        // Start AD conversion
36
        ADC_Enable();
37
    // restore global interrupt flags
38
    SREG = sreg;
39
}
40
 
41
/*****************************************************/
42
/*     Interrupt Service Routine for ADC             */
43
/*****************************************************/
44
// runs at 312.5 kHz or 3.2 µs
45
// if after (60.8µs) all 19 states are processed the interrupt is disabled
46
// and the update of further ads is stopped
47
 
48
 
49
#define ADC0    0
50
#define ADC1    1
51
#define ADC2    2
52
#define ADC3    3
53
#define ADC4    4
54
#define ADC5    5
55
#define ADC6    6
56
#define ADC7    7
57
 
58
ISR(ADC_vect)
59
{
60
    static uint8_t ad_channel = ADC0, state = 0;
61
 
62
    // state machine
63
        switch(state++)
64
        {
65
                case 0:
66
                        Adc0 = ADC;
67
                        ad_channel = ADC1;
68
                        break;
69
                case 1:
70
                        Adc1 = ADC;
71
                        ad_channel = ADC2;
72
                        break;
73
                case 2:
74
                        Adc2 = ADC;
75
                        ad_channel = ADC3;
76
                        break;
77
                case 3:
78
                        Adc3 = ADC;
79
                        ad_channel = ADC4;
80
            break;
81
                case 4:
82
                        Adc4 = ADC;
83
                        ad_channel = ADC5;
84
                        break;
85
                case 5:
86
                        Adc5 = ADC;
87
                        ad_channel = ADC6;
88
                        break;
89
                case 6:
90
                        Adc6 = ADC;
91
                        ad_channel = ADC7;
92
                        break;
93
                case 7:
94
                        Adc7 = ADC;
95
                        ad_channel = ADC0;
96
                        state = 0;
97
                        ADReady = 1;
98
            break;
99
                default:
100
                        ad_channel = ADC0;
101
                        state = 0;
102
                        ADReady = 1;
103
                        break;
104
        }
105
    // set adc muxer to next ad_channel
106
    ADMUX = (ADMUX & 0xE0) | ad_channel;
107
    // after full cycle stop further interrupts
108
    if(state != 0) ADC_Enable();
109
}