I am trying to sample two channels and store the result in an array. So far I get through one successful conversion, trigger the interrupt, and then for whatever reason the ADC seems shut off and will not resume. I am using the G2553 controller. I apologize for the terribly formatted code.
I thought I had everything correctly configured and understood the sequence of conversion flow chart, but the debugger disagrees.
How can I make the ADC convert a channel, interrupting to store a conversion when ADC10MEM receives a result, and then move onto the next channel?
#include <msp430g2553.h>
/*
* main.c
*/
void ConfigClock(); // declaring config function for uC CLK speeds
void ConfigADC(); // declaring config function for ADC10
void ConfigPorts(); // declaring config function for ADC10 input ports
volatile unsigned long CH0_Data[32]; // 32 ADC values stored here from PA1.0. TODO make dynamic
volatile unsigned long CH1_Data; // 32 ADC values stored here from PA1.1. TODO make dynamic
//volatile unsigned int count = 0; // counter for sensorData
unsigned long sampleCount = 0; // keeps track of how many times the ADC samples
int main(void) {
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
ConfigClock();
ConfigADC();
ConfigPorts();
_BIS_SR(GIE); // enable interrupts
ADC10CTL0 |= ADC10IE; // ADC10 interrupt enabled
ADC10CTL0 |= ENC + ADC10SC;
while(1){
__bis_SR_register(CPUOFF + GIE); // will resume upon interrupt
ADC10CTL0 |= ADC10ON; // make sure ADC is on
ADC10CTL0 |= ENC + ADC10SC + ADC10IE; // enable, start conversion, enable interrupts
}
return 0;
}
/*
* Configures ports for their use by the ADc
*
*/
void ConfigPorts() {
P1DIR = 0x0000; // all pins on P1 are inputs
}
/*
* Configures ADC for dual channel sequencing and storage
*/
void ConfigADC() {
ADC10AE0 |= BIT0 + BIT1; // PA1.0 and PA1.1 are selected as channels for the ADC
ADC10CTL1 |= CONSEQ_3; // Control register set to convert sequence of channels repeatedly
ADC10CTL1 |= ADC10DIV_7; // prescale divider is now /8
ADC10CTL1 |= INCH_1; // input sequence is PA1.1, PA1.0
ADC10CTL1 |= ADC10SSEL_1; // select ACLK as source
ADC10CTL0 |= ADC10ON; // finally, turn the damn thing on.
}
/*
* Configures clock to operate at lower frequency for less power consumption
*/
void ConfigClock() {
// configure clock
BCSCTL1 |= CALBC1_1MHZ; // calibrate CLK for 1 MHz
DCOCTL |= CALDCO_1MHZ; // calibrate DCO for 1 MHZ
BCSCTL3 |= LFXT1S_2; // Enable VLO, LFXT1 = VLO
BCSCTL1 |= DIVA_3; // ACLK/8
// ACLK is sourced from VLO by default. ~12 kHz default
IFG1 &= ~OFIFG; // disable oscillator fault interrupt flag
BCSCTL2 |= DIVM_3; // set divider for MCLK to DCO/8
BCSCTL2 |= DIVS_3; // set divider for SCLK to DCO/8
BCSCTL2 |= SELM_0; // MCLK & SCLK are running off DCO.
}
/*
* The ADC interrupt is triggered once a conversion is complete and placed into ADC10MEM
*/
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR(void) {
CH0_Data[sampleCount++] = ADC10MEM;
__bic_SR_register_on_exit(CPUOFF);
}