Hi, All,
I am trying to use ADC module of the micro-controller to decode the incoming signal. My input signal will be an OOK modulated signal of 125 kHz frequency. I need to band-pass sample the incoming sequence with 55 kHz.
I have read through the user guide and the forums and figured out that it would be good if i use a PWM signal with 55 kHz to start the ADC conversion. The idea is to use timer with comparator with interrupt to generate PWM signal and then when the interrupt occurs, the ADC conversion should triger the SHI signal.
I have written a piece of code which should have work okay but it seems not to be.
What I am doing:
- I am using MSP430F5529 mcu and CCS with Version: 5.5.0.00077.
- I am using ADC12_A and TImer A0 to do this task.
- For the ADC :
- I am using channel A0 of the ADC with 5 MHz clock provided by ADC12OSC.
- I am using the internal voltage reference generator with Vr+ =2.5V and Vr-=0;
- I want the ADC to run in single channel single conversion mode.
- Also I am using the ADC in pulse sample mode.
- code to configure the ADC:
-
void configureAdc12A(void)
{
volatile unsigned int i;
P6SEL |= 0x01; // Enable A/D channel A0
REFCTL0 &= ~REFMSTR; // Reset REFMSTR to hand over control to ADC12_A ref control egisters
ADC12CTL0 = ADC12ON+ADC12SHT00+ADC12REFON+ADC12REF2_5V;// Turn on ADC12, Sampling tim (0001b = 8 cycles)
// On Reference Generator and set to 2.5VADC12CTL1 = ADC12SHP; // Use sampling timer and clock frequency set to 5MHz
ADC12MCTL0 = ADC12SREF_1; // Vr+=Vref+ and Vr-=AVssfor ( i=0; i<0x30; i++); // Delay for reference start-up
ADC12CTL0 |= ADC12ENC; // Enable conversions
}
- For the PWM:
-
void initTimers(void) {
// Frequency of timer_A is 1MHz. // Generate PWM waveform with frequency 1MHz/18=55kHz and duty ratio 9/19 ~> 50% // TIMER_PERIOD = 18 // DUTYCYCLE = 9
TIMER_A_clearTimerInterruptFlag(TIMER_A0_BASE);
TIMER_A_configureUpMode( TIMER_A0_BASE, TIMER_A_CLOCKSOURCE_SMCLK, TIMER_A_CLOCKSOURCE_DIVIDER_1, TIMER_PERIOD, TIMER_A_TAIE_INTERRUPT_ENABLE, TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE, TIMER_A_DO_CLEAR );
TIMER_A_startCounter( TIMER_A0_BASE, TIMER_A_UP_MODE );
TIMER_A_setOutputForOutputModeOutBitValue(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_2, TIMER_A_OUTPUTMODE_OUTBITVALUE_LOW );
TIMER_A_initCompare(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_2, TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE, TIMER_A_OUTPUTMODE_RESET_SET, DUTYCYCLE);
- Timer ISR code here:
-
#pragma vector=TIMER0_A1_VECTOR
__interrupt void TIMER0_A1_ISR(void)
{
//Any access, read or write, of the TAIV register automatically resets the
//highest "pending" interrupt flag
switch ( __even_in_range(TA0IV, 14) ) {
case 0: break; //No interrupt
case 2: break; //CCR1 not used
case 4: //CCR2
ADC12CTL0 |= ADC12SC; // Start conversion
TIMER_A_clearTimerInterruptFlag(TIMER_A0_BASE);
__bic_SR_register_on_exit(LPM0_bits); // Exit active CPU
break;
default: break;
}
}
-
My main file void main (void) { WDT_A_hold(WDT_A_BASE); //Stop watchdog timer GPIO_setAsPeripheralModuleFunctionOutputPin( GPIO_PORT_P1, GPIO_PIN3 ); GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5,GPIO_PIN3 + GPIO_PIN2 ); //Initialization configureAdc12A(); initTimers();
while (1) { ADC12IFG &=~ADC12IFG0; // Clear Flag bits __bis_SR_register(LPM0_bits + GIE); // LPM0, Comparator_ISR will force exit
__no_operation(); while (!(ADC12IFG & BIT0)); SampledData[index] = ADC12MEM0; index++; } }
Issues I am facing:
- The first problem with the code is that after CPU enters the LPM0 mode the __bic_SR_register_on_exit(LPM0_bits) line does not force the CPU to exist. I have one breakpoint on line while (!(ADC12IFG & BIT0)) in the main and one at ADC12CTL0 |= ADC12SC; in ISR. It always stop at the one in ISR and does not come back to the main loop.
- Since the code was always in the ISR I tried to use the following lines of code inside the ISR and when I use the debugger to watch the SampledData[] values, It always show zero.
while (!(ADC12IFG & BIT0)); SampledData[index] = ADC12MEM0; index++;
Your Suggestion :