This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP 430 ADC Flag Problem

Hello,

I am working with an MSP 430BT5190 and am just trying to get a bit of the sample code provided for ADC to work. Originally the code was written to sample on channel A0, but since I do not have access to that pin on my board, I have tried to change it to sample on channel A12, which on my board is P7.4. My problem is that when I apply a voltage to the pin, the interrupt flag for the ADC never gets set, and If I set it myself in the code, then ADC12MEM12 where the result should be is empty. I know my connection to the pin is good, because if I just set it high as a digital output I can read it just fine with a multimeter. My code is included below. Currently I am just trying to get one result, which is why it exits the ISR once index=1. Any help would be greatly appreciated, thank you in advance.

/*
* main.c
*/

#include "msp430.h"
#include "stdio.h"
#define   Num_of_Results   8
volatile unsigned int results[Num_of_Results];
int z=0;
int index = 0;

void main(void) {

WDTCTL = WDTPW + WDTHOLD; // Stop WDT
 ADC12CTL0 = ADC12SHT02 + ADC12ON;         // Sampling time, ADC12 on
ADC12CTL1 = ADC12SHP; // Use sampling timer
ADC12IE = (0x1000); // Enable ADC12IFG12
ADC12CTL0 |= ADC12ENC;

P7SEL |= (0x0010); // Enable A/D channel A12
__enable_interrupt(); //Enabling interrupts without entering low power mode
//ADC12IFG |= (0x1000);    //Setting ADC12IFG12 to 1 for testing purposes

for(;;){
 ADC12CTL0 |= ADC12SC;                   // Start sampling/conversion

if(z==1){
puts("Converted!");
int b=0;
for(b=0; b<Num_of_Results; b++){
printf("Results[%d]: %c \n", b, results[b]);
}
index=0;
z=0;
}


}

}

#pragma vector=ADC12_VECTOR
__interrupt void ADC12ISR (void)
{

switch(__even_in_range(ADC12IV,34))
{
case 0: break; // Vector 0: No interrupt
case 2: break; // Vector 2: ADC overflow
case 4: break; // Vector 4: ADC timing overflow
case 6: break; // Vector 6: ADC12IFG0
case 8: break; // Vector 8: ADC12IFG1
case 10: break; // Vector 10: ADC12IFG2
case 12: break; // Vector 12: ADC12IFG3
case 14: break; // Vector 14: ADC12IFG4
case 16: break; // Vector 16: ADC12IFG5
case 18: break; // Vector 18: ADC12IFG6
case 20: break; // Vector 20: ADC12IFG7
case 22: break; // Vector 22: ADC12IFG8
case 24: break; // Vector 24: ADC12IFG9
case 26: break; // Vector 26: ADC12IFG10
case 28: break; // Vector 28: ADC12IFG11
case 30: // Vector 30: ADC12IFG12
puts("Got here!");
results[index] = ADC12MEM12; // Move results
index++; // Increment results index, modulo;
puts("Got here 2!");
if (index == 1){
puts("Got here 3!");
z=1;
}

break;
case 32: break; // Vector 32: ADC12IFG13
case 34: break; // Vector 34: ADC12IFG14
default: break;
}
}
  • The original code for A0 omits several steps of configuraitons because they are the default. If you change to A12 or use ADC12MEM (which are two independent things, you can sample any channel with any ADC12MEM), some more steps are required. Yes, I know, all those undocumented implicit dependencies in the demo code are a pain.

    Default is that ADC12MEM0 is the active configuration, and all ADC12CTLx registers are by default configured for sampling on A0 with VCC as reference.

    I suggest re-reading the ADC12 chapter in the users guide.

    Also, it is not a good idea to call puts from within an ISR. Depedning on its implementation, it may stall the system. Especially if puts requires a TX interrupt to be serviced (whcih cannot be serviced while running in another ISRs context)

**Attention** This is a public forum