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.

ADC10 issue in MSP430G2553

Hi,

I want to trigger ADC10 using Watchdog timer every 2 msec and want the average value of 64 samples. Once the average is obtained, i want to reflect same in the duty cycle of TIMER_A1 . The change in the duty cycle can be seen as the LED brightness change connected to P2.1.

But, when i am running the code, it is toggling between 

if(ADC_flag)   AND     if (Reading_Captured)


Please see what may be the issue with the code. I am NOT able to find out the solution ever after giving so much try.

void main(void)

{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT

CLOCK_Init(); // Initialize clocks for 16 MHz

__delay_cycles (80000000); 

ConfigPins();

__delay_cycles (500); //Random delay

Timer_Init();

__bis_SR_register(GIE); // Enable global interrupt

WDT_Init();

ADC_Init();

while(1)
{

if(ADC_flag)
{
ADC_flag=0;
__bis_SR_register(CPUOFF);                                              // MSP430 waits in LPM0 to save power until ADC10 conversion complete
                                                                                                   // ADC10_ISR will force exit from any LPMx on return.
while (ADC10CTL1 & ADC10BUSY);                               //Wait for conversion. 13 ADC10CLK cycle = 2.6 usec
ADC10SA = (unsigned int)&ADC_Readings;                 // Transfer adc readings to an array
ADC10CTL0 &= ~ENC;                                                      //The ENC bit must be clear so that most bits in ADC10CTL0 and ADC10CTL1 can be changed.

// sequence of conversions complete
Voltage_Sum += ADC_Readings;
Reading_Captured = 1;
Avg_ctr ++;
}

if (Reading_Captured)    
{
Reading_Captured = 0;
if (Avg_ctr == ctr_th)
{

ADC_Update();
if(Voltage > 0)
{
Duty = Voltage;
// P1OUT |= BIT0;
}
}

// Reset all the ADC values
Avg_ctr = 0;
Voltage_Sum = 0;
}
}

}

void CLOCK_Init(void)
{
//if we want DCO=MCLK=SMCLK,then just configure DCOCTL and BCSCTL1
//16Mhz @ maximum device frequency

if (CALBC1_16MHZ==0xFF) // If calibration constant erased
 {
      while(1); // do not load, trap CPU!!
 }
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_16MHZ; // Set range
DCOCTL = CALDCO_16MHZ; // Set DCO step + modulation*/
}

void ConfigPins(void)
{

  P1DIR |= BIT0;   // output

  P1OUT = 0;         // clear output pin

}

void ADC_Init(void)
{

ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE;
ADC10CTL1 = INCH_1 + SHS_0 + ADC10SSEL_0 + ADC10DIV_0 + CONSEQ_0;
ADC10AE0 |= BIT1;                        // Select port pins function as input Analog channels
ADC10DTC1 = 0x001;                    // 1 conversion per sequence
}

void WDT_Init (void)
{
// Watchdog timer is used to generated interrupts for taking ADC readings
// DCO/SMCLK clock source used in this example for the WDT clock source
WDTCTL = WDT_MDLY_32; // WDT 32ms, for SMCLK = 1Mhz,here SMCLK = 16Mhz so timer interval = 2ms
IE1 |= WDTIE; // Enable WDT interrupt
}

// Watchdog Timer interrupt service routine
#pragma vector = WDT_VECTOR
__interrupt void WDT_ISR(void)
{
/* Here for each interrupt, it triggers ADC to take readings
* WDTIFG interrupt flag is automatically cleared */
ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start
ADC_flag =1; //set ADC flag to process adc data
}

// ADC10 interrupt service routine
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void)
{
//ADC10IFG interrupt flag is automatically cleared
__bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(Status Register)
}

void Timer_Init(void)
{
/*TIMER_A1 as PWM generation
*/

P2DIR |= BIT1|BIT2;                      //set as output pin
P2SEL |= BIT1|BIT2;                      //pin selected for pwm operations (P2.1/TA1.1) and (P2.2/TA1.1)
TA1CTL |= TASSEL_2 + MC_1;  //SMCLK and up mode count till ccr register
TA1CCR0 |= 1600 - 1;                         //pwm frequency 10 khz; DCO = MCLK = SMCLK = 16 Mhz
TA1CCR1 |= Duty;                           //Duty cycle 
TA1CCTL1 |= OUTMOD_7;                   //set/reset mode

//_BIS_SR(LPM0_bits + GIE); //For low power mode and global interrupt
// TAKE DUTY AS A VARIBLE TO CHANGE THE DUTY CYCLE
}

void ADC_Update(void)
{

/* Here ctr_th = 64 . i.e average of 64 ADC readings is calculated.
* Once is every 1 ms a set of ADC readings is taken
* So loop time is approximately 64 * 2 = 128 ms
*/

Voltage = Voltage_Sum / ctr_th;

}

THANK YOU ....

 

**Attention** This is a public forum