Quantcast
Channel: Microcontrollers
Viewing all articles
Browse latest Browse all 234877

Forum Post: ADC10 issue in MSP430G2553

$
0
0
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 ....

Viewing all articles
Browse latest Browse all 234877

Trending Articles