#include "c:\cvavr\inc\mega128.h"
#include "portdef.h"
#include "adc.h"
extern void serprintstr(char *);
extern int systime_ms;
/* adc_state is used to store the channel that we are currently reading,
* and whether we are still waiting for it or if it's already read.
*/
ADCState adc_state;
int ADCdata[8]; // The actual data we got from the adc
int ADCoffsets[8]; // The offset of the accel/gyro
int ADCscalingn[8]; // The scaling numerator (multiply by this)
int ADCscalingd[8]; // The scaling denominator (divide by this)
void ADCinit(void) {
EICRB=0x80; // trigger INT7 on falling edge (/INT line of ADC)
EIMSK=0x80;
DDRE=0x70; // Bits 4,5,6 are outputs
adc_state.chan=0;
adc_state.waiting=0;
ADCCtrlRD = 1;
ADCCtrlWR = 1;
// 2-4 are gyros, 5-7 are accelerometers
ADCoffsets[2]=2096;
ADCoffsets[3]=1398;
ADCoffsets[4]=1988;
ADCoffsets[5]=1160;
ADCoffsets[6]=1195;
ADCoffsets[7]=1133;
ADCscalingn[2]=1;
ADCscalingn[3]=1;
ADCscalingn[4]=1;
ADCscalingn[5]=2;
ADCscalingn[6]=2;
ADCscalingn[7]=2;
ADCscalingd[2]=1;
ADCscalingd[3]=1;
ADCscalingd[4]=1;
ADCscalingd[5]=1;
ADCscalingd[6]=1;
ADCscalingd[7]=1;
}
/* Set up a conversion for the next channel. */
void ADCCnvSetup(void) {
DisableInterrupts;
DDRA = 0xFF;
ADCCtrlWR = 0;
// Normal operation, internal clock mode, internally controlled acquisition,
// 0 to 5V input range
PORTA = (0b01000000 + adc_state.chan);
ADCCtrlWR = 1;
adc_state.waiting=1;
EnableInterrupts;
}
/* When we get an interrupt from the ADC, read in the data */
interrupt [EXT_INT7] void adc_ready(void) {
// If we are waiting for a conversion
if(adc_state.waiting) {
adc_state.waiting=0;
DDRA = 0x00;
ADCCtrlRD = 0;
ADCCtrlHBEN = 0;
ADCdata[adc_state.chan]=0x0000;
// Read in the low byte
ADCdata[adc_state.chan]=PINA;
ADCCtrlHBEN = 1;
// Read in the high byte
ADCdata[adc_state.chan]+=((int)(PINA & 0x0F)) <<8;
ADCCtrlRD = 1;
// Scale the data
ADCdata[adc_state.chan]=ADCdata[adc_state.chan]-ADCoffsets[adc_state.chan];
ADCdata[adc_state.chan]=ADCscalingn[adc_state.chan]*ADCdata[adc_state.chan];
ADCdata[adc_state.chan]=ADCdata[adc_state.chan]/ADCscalingd[adc_state.chan];
adc_state.chan++;
}
ADCCnvSetup();
}
评论0