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.
Hi,
I am currently using an MSP430F5528. I have 2 ADCs enabled and I am trying to read both at the same time. The problem is that I need to send 2 requests to get the ADC values. I believe that the interrupt does not get called. Do you have any ideas why this might be?
Here is the code to initialize the ADC
void ADC_Init(void)
{
P6SEL = 0x11; // Enable A/D channel inputs
ADC12CTL0 = ADC12ON+ADC12MSC+ADC12SHT0_8; // Turn on ADC12, set sampling time
ADC12CTL1 = ADC12SHP+ADC12CONSEQ_1; // Use sampling timer, single sequence
ADC12MCTL0 = ADC12INCH_0+ADC12SREF_1; // ref+=AVcc, channel = A0
ADC12MCTL4 = ADC12INCH_4+ADC12SREF_1+ADC12EOS; // ref+=AVcc, channel = A3, end seq.
ADC12IE = 0x10; // Enable ADC12IFG.3
ADC12CTL0 |= ADC12ENC; // Enable conversions
}
The ISR is:
#pragma vector = ADC12_VECTOR
__interrupt void ADC12_ISR(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: // Vector 6: ADC12IFG0
//ADC_Result1 = ADC12MEM0; //store the temperature
// ADC_done_flag=1;
break;
case 8: break; // Vector 8: ADC12IFG1
case 10: break; // Vector 10: ADC12IFG2
case 12: break; // Vector 12: ADC12IFG3
case 14: // Vector 14: ADC12IFG4
ADC_Result1 = ADC12MEM0; //store the temperature
ADC_Result2 = ADC12MEM4; //store the temperature
ADC_done_flag=1;
break;
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: break; // Vector 30: ADC12IFG12
case 32: break; // Vector 32: ADC12IFG13
case 34: break; // Vector 34: ADC12IFG14
default: break;
}
}
and I start the conversion by doing:
ADC12CTL0 |= ADC12SC; // Sampling and conversion start
One fix is to call the conversion two times one right after another, but I want to know if I am doing something wrong. (when I had only one enabled it worked fine)
Thank you.
Alin
What about 1,2 and 3? The ADC12 works a sequence as if the MCTL registers were a script. It first converts based on MCTL0, then MCTL1, then MCTL2 until it hits the EOS bit. (which might even be set after a reset for one fo the MCTLs you skipped in the setup)Alin Dosa said:ADC12MCTL0 = ADC12INCH_0+ADC12SREF_1; // ref+=AVcc, channel = A0
ADC12MCTL4 = ADC12INCH_4+ADC12SREF_1+ADC12EOS; // ref+=AVcc, channel = A3, end seq.
There is no need to configure ADC12MCTL4 for channel 4 nd 0 for channel 0.
The MCTLs can use any input channel. So you can configure MCTL0 for channel 0 and MCTL1 for channel 4 (or even mutiple MCTLs for the same channel, if you want)
It's ADC12IFG.4. However, I gues that's what you wanted anyway.Alin Dosa said:ADC12IE = 0x10; // Enable ADC12IFG.3
Another thin I nothiced: you use ADC12SREF_1, but you don't enable the reference anywhere. Won't work. Use ADC12SREF_0 to compare against VCC or enable the internal reference.
I am setting the reference previously in the code:
REFCTL0 |= REFON+REFVSEL_1; // Set 2.0V reference for ADC
I have changed my ADC init function based on your recommendation (and of course then interrupt service routine), and I still get the same behavior (I need to send conversion start twice)
void ADC_Init(void)
{
P6SEL = 0x11; // Enable A/D channel inputs
ADC12CTL0 = ADC12ON+ADC12MSC+ADC12SHT0_8; // Turn on ADC12, set sampling time
ADC12CTL1 = ADC12SHP+ADC12CONSEQ_1; // Use sampling timer, single sequence
ADC12MCTL0 = ADC12INCH_0+ADC12SREF_1; // ref+=AVcc, channel = A0
ADC12MCTL1 = ADC12INCH_4+ADC12SREF_1+ADC12EOS; // ref+=AVcc, channel = A3, end seq.
ADC12IE = 0x2; // Enable ADC12IFG.2
ADC12CTL0 |= ADC12ENC; // Enable conversions
}
#pragma vector = ADC12_VECTOR
__interrupt void ADC12_ISR(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: // Vector 6: ADC12IFG0
//ADC_Result1 = ADC12MEM0; //store the temperature
// ADC_done_flag=1;
break;
case 8: // Vector 8: ADC12IFG1
ADC_Result1 = ADC12MEM0; //store the temperature
ADC_Result2 = ADC12MEM1; //store the temperature
ADC_done_flag=1;
break;
case 10: break; // Vector 10: ADC12IFG2
case 12: break; // Vector 12: ADC12IFG3
case 14: // Vector 14: ADC12IFG4
break;
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: break; // Vector 30: ADC12IFG12
case 32: break; // Vector 32: ADC12IFG13
case 34: break; // Vector 34: ADC12IFG14
default: break;
}
}
Any other thoughts?
Okay. I cannot know what you don't post :) A buggy program is like an elephant. You know the joke about the blind men describing an elephant? One was touching the nose ad said "it's a snake", the other was touching the foot and said 'No, it's a tree' while the third was holding the tail and said "you're both wrong, it's a rope".Alin Dosa said:I am setting the reference previously in the code:
Alin Dosa said:ADC12IE = 0x2; // Enable ADC12IFG.2
However, I don't see what's wrong with your code.
My own ADC12 init code is similar except one thing: I first set ADC12ON in a separate statement, then I set ADC12MSC and the rest. Maybe the ADC12MSC bit isn't set if you don't enable ADC12ON before (and not at the same time).
**Attention** This is a public forum