Other Parts Discussed in Thread: MSP430F5338
Hi all,
I am using MSP430F5338. In this i am trying to read the internal temperature sensor value from ADC channel number 10 (A10). In this uC 12bit ADC is available sine i take a decision to disable the REFMSTR bit of REFCTL0. To enable the Temperature sensor enabled ADC12REFON bit of ADC12CTL0 register. Apart from this i am reading ADC channel 0 to 7 (A0-A7) with the external reference volatage 3.3V. As per the data sheet " Setting the ADC12REFON bit enables the REFGEN subsystem which includes the bandgap, the bandgap bias circuitry, and the 1.5-V, 2.0-V, 2.5-V buffer. Setting this bit causes the ADC12REFON REFGEN subsystem to remain enabled regardless if any module has requested it. Clearing this bit disables the REFGEN subsystem only when there are no pending requests for REFGEN from all modules." I have quite confusion here "if i enable the ADC12REFON for the temperature channel alone the internal reference will enabled whether is it affect the renaining channel whichever using external reference voltage". Also after modifying the REFMSTR bit 0 none of the code except REFMSTR bit 0 made code is not running on the controller, why? Is the REFMSTR will affect any default settings of uC? Also if the following BSP code run means the count for temp value received as around 2000.
int i;
long temp;
volatile long IntDegF;
volatile long IntDegC;
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
REFCTL0 &= ~REFMSTR; // Reset REFMSTR to hand over control to
// ADC12_A ref control registers
ADC12CTL0 = ADC12SHT0_8 + ADC12REFON + ADC12ON;
// Internal ref = 1.5V
ADC12CTL1 = ADC12SHP; // enable sample timer
ADC12MCTL0 = ADC12SREF_1 + ADC12INCH_10; // ADC i/p ch A10 = temp sense i/p
ADC12IE = 0x001; // ADC_IFG upon conv result-ADCMEMO
for(i=0;i<30;i++) // Delay to allow Ref to settle
ADC12CTL0 |= ADC12ENC;
while(1)
{
ADC12CTL0 |= ADC12SC; // Sampling and conversion start
__bis_SR_register(LPM4_bits + GIE); // LPM0 with interrupts enabled
__no_operation();
// Temperature in Celsius
// ((A10/4096*1500mV) - 894mV)*(1/3.66mV) = (A10/4096*410) - 244
// = (A10 - 2438) * (410 / 4096)
IntDegC = ((temp - 2438) * 410) / 4096;
// Temperature in Fahrenheit
// ((A10/4096*1500mV) - 829mV)*(1/2.033mV) = (A10/4096*738) - 408
// = (A10 - 2264) * (738 / 4096)
IntDegF = ((temp - 2264) * 738) / 4096;
__no_operation(); // SET BREAKPOINT HERE
}
}
#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: // Vector 6: ADC12IFG0
temp = ADC12MEM0; // Move results, IFG is cleared
__bic_SR_register_on_exit(LPM4_bits); // Exit active CPU
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: break; // Vector 30: ADC12IFG12
case 32: break; // Vector 32: ADC12IFG13
case 34: break; // Vector 34: ADC12IFG14
default: break;
}
}
If i run the code which developed by me means the count for temp value is come around 1400 only. I am not able to get the reason. The pseudocode of the my code as below
ADC12CTL0 &= ~(0xFF80);
ADC12CTL1 |= 0x0C1E;
ADC12CTL1 &= ~(0x03E0)
ADC12CTL2 |= 0x0020;
ADC12CTL0 |= 0x0010;
// Channel number is up to temp sensor channel
for (ix = 0; ix <= 10; ++ix)
{
ADC12MCTLX[ix] = 0x00;
// Select reference
if(ix == 10)
{
REFCTL0 &= ~REFMSTR;
ADC12CTL0 |= 0x0020;
// 001b = V(R+) = VREF+ and V(R-) = AVSS
ADC12MCTLX[ix] &= 0x9F;
} else
{
// 000b = V(R+) = AVCC and V(R-) = AVSS or
ADC12MCTLX[ix] &= 0x8F;
}
// ADC12INCHx - Input channel select
ADC12MCTLX[ix] |= ix;
}
// Set EOS to memory control register.
ADC12MCTLX[10] |= 0x80;
ADC12CTL0 |= 0x0002;
ix = 0;
while (ix != adc_ptr->eosChanNo))
{
// Interrupt flag check
while (ADC12IFG == 0x0000)
{
}
// Selecting the channel number based on interrupt flag
for (ix = 0; ix < 10; ++ix)
{
if ((ADC12IFG >> ix) & 0x01)
{
break;
}
} // closing of for loop
// Reset only particular channel flag
adcReg_ptr->ADC12IFG &= ~(0x01 << ix);
// Store the ADC converted value from the ADC memory register.
*ptr[ix]) = ADC12MEMX[ix];
++ptr[ix];
}
have anyone face such a kind of issue.
