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.