On the MSP-EXP430F5529LP Launchpad, I set up the chip to do a sequence of two conversions continually, which does happen. I also need to infrequently break from this and convert on two other inputs (user controls). These user control inputs are not working. I would appreciate suggestions on how to accomplish this. Here is my code:
#include "driverlib.h" void clocks_setup(void); void setup_ADC(void); #define TIMER_PERIOD 200 #define DUTY_CYCLE1 120 #define DUTY_CYCLE2 80 #define COMPARE_VALUE 50000 void main(void) { clocks_setup(); //Stop WDT WDT_A_hold(WDT_A_BASE); //P1.2 and P1.3 output //P1.2 and P1.3 options select GPIO_setAsPeripheralModuleFunctionOutputPin( GPIO_PORT_P1, GPIO_PIN2 + GPIO_PIN3 //TA0.1, TA0.2 ); //Start Timer Timer_A_initUpDownModeParam initUpDownParam = {0}; initUpDownParam.clockSource = TIMER_A_CLOCKSOURCE_SMCLK; initUpDownParam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1; initUpDownParam.timerPeriod = TIMER_PERIOD; initUpDownParam.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE; initUpDownParam.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE; initUpDownParam.timerClear = TIMER_A_DO_CLEAR; initUpDownParam.startTimer = false; Timer_A_initUpDownMode(TIMER_A0_BASE, &initUpDownParam); Timer_A_startCounter(TIMER_A0_BASE, TIMER_A_UPDOWN_MODE ); //Initialze compare registers to generate PWM1 Timer_A_initCompareModeParam initComp1Param = {0}; initComp1Param.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_1; initComp1Param.compareInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE; initComp1Param.compareOutputMode = TIMER_A_OUTPUTMODE_TOGGLE_SET; initComp1Param.compareValue = DUTY_CYCLE1; Timer_A_initCompareMode(TIMER_A0_BASE, &initComp1Param); //Initialze compare registers to generate PWM2 Timer_A_initCompareModeParam initComp2Param = {0}; initComp2Param.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_2; initComp2Param.compareInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE; initComp2Param.compareOutputMode = TIMER_A_OUTPUTMODE_TOGGLE_RESET; initComp2Param.compareValue = DUTY_CYCLE2; Timer_A_initCompareMode(TIMER_A0_BASE, &initComp2Param); // derived from ex2_continousModeOperationWithCCR0Interrupt.c //Set P1.0 to output direction GPIO_setAsOutputPin( GPIO_PORT_P1, GPIO_PIN0 ); //Start timer in continuous mode sourced by SMCLK Timer_A_initContinuousModeParam initContParam = {0}; initContParam.clockSource = TIMER_A_CLOCKSOURCE_SMCLK; initContParam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1; initContParam.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE; initContParam.timerClear = TIMER_A_DO_CLEAR; initContParam.startTimer = false; Timer_A_initContinuousMode(TIMER_A1_BASE, &initContParam); //Initiaze compare mode Timer_A_clearCaptureCompareInterrupt(TIMER_A1_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_0 ); Timer_A_initCompareModeParam initCompParam = {0}; initCompParam.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_0; initCompParam.compareInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE; initCompParam.compareOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE; initCompParam.compareValue = COMPARE_VALUE; Timer_A_initCompareMode(TIMER_A1_BASE, &initCompParam); Timer_A_startCounter(TIMER_A1_BASE, TIMER_A_CONTINUOUS_MODE ); //****************************************************************************** setup_ADC(); //Enter LPM0, enable interrupts // __bis_SR_register(LPM0_bits + GIE); //For debugger __no_operation(); } //****************************************************************************** // //This is the TIMER1_A3 interrupt vector service routine. //This reads the user inputs //****************************************************************************** #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=TIMER1_A0_VECTOR __interrupt #elif defined(__GNUC__) __attribute__((interrupt(TIMER1_A0_VECTOR))) #endif void TIMER1_A0_ISR(void) { uint8_t ADC_input_2_or_3_flag; uint16_t compVal = Timer_A_getCaptureCompareCount(TIMER_A1_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_0) + COMPARE_VALUE; //Toggle P1.0 GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0); ADC12_A_disableConversions(ADC12_A_BASE, ADC12_A_PREEMPTCONVERSION); if (ADC_input_2_or_3_flag){ ADC12_A_startConversion(ADC12_A_BASE, ADC12_A_MEMORY_2, ADC12_A_SINGLECHANNEL); ADC_input_2_or_3_flag = 0; } else { ADC12_A_startConversion(ADC12_A_BASE, ADC12_A_MEMORY_3, ADC12_A_SINGLECHANNEL); ADC_input_2_or_3_flag = 1; } ADC12_A_startConversion(ADC12_A_BASE, ADC12_A_MEMORY_0, // starting memory buffer address ADC12_A_SEQOFCHANNELS); //conversion sequence mode select //Add Offset to CCR0 Timer_A_setCompareValue(TIMER_A1_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_0, compVal ); } #include "driverlib.h" //Needs to be global in this example //Otherwise, the compiler removes it //because it is not used for anything. volatile uint16_t results[4]; void setup_ADC(void) { //Stop Watchdog Timer WDT_A_hold(WDT_A_BASE); //Enable A/D channel inputs GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P6, GPIO_PIN0 + GPIO_PIN1 ); //Initialize the ADC12_A Module /* * Base address of ADC12_A Module * Use internal ADC12_A bit as sample/hold signal to start conversion * USE MODOSC 5MHZ Digital Oscillator as clock source * Use default clock divider of 1 */ ADC12_A_init(ADC12_A_BASE, ADC12_A_SAMPLEHOLDSOURCE_SC, ADC12_A_CLOCKSOURCE_ADC12OSC, ADC12_A_CLOCKDIVIDER_1); ADC12_A_enable(ADC12_A_BASE); /* * Base address of ADC12_A Module * For memory buffers 0-7 sample/hold for 4 clock cycles * For memory buffers 8-15 sample/hold for 16 clock cycles (default) * Enable Multiple Sampling */ ADC12_A_setupSamplingTimer(ADC12_A_BASE, ADC12_A_CYCLEHOLD_4_CYCLES, ADC12_A_CYCLEHOLD_16_CYCLES, ADC12_A_MULTIPLESAMPLESENABLE); //Configure Memory Buffers /* * Base address of the ADC12_A Module * Configure memory buffer 0 * Map input A0 to memory buffer 0 * Vref+ = AVcc * Vref- = AVss * Memory buffer 0 is not the end of a sequence */ ADC12_A_configureMemoryParam param0 = {0}; param0.memoryBufferControlIndex = ADC12_A_MEMORY_0; param0.inputSourceSelect = ADC12_A_INPUT_A0; param0.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC; param0.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS; param0.endOfSequence = ADC12_A_NOTENDOFSEQUENCE; ADC12_A_configureMemory(ADC12_A_BASE,¶m0); /* * Base address of the ADC12_A Module * Configure memory buffer 1 * Map input A1 to memory buffer 1 * Vref+ = AVcc * Vref- = AVss * Memory buffer 1 is the end of a sequence */ ADC12_A_configureMemoryParam param1 = {0}; param1.memoryBufferControlIndex = ADC12_A_MEMORY_1; param1.inputSourceSelect = ADC12_A_INPUT_A1; param1.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC; param1.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS; param1.endOfSequence = ADC12_A_ENDOFSEQUENCE; ADC12_A_configureMemory(ADC12_A_BASE,¶m1); //Enable memory buffer 1 interrupt ADC12_A_clearInterrupt(ADC12_A_BASE, ADC12IE1); ADC12_A_enableInterrupt(ADC12_A_BASE, ADC12IE1); while(1) { //Enable/Start first sampling and conversion cycle /* * Base address of ADC12_A Module * Start the conversion into memory buffer 0 * Use the repeated sequence of channels */ ADC12_A_startConversion(ADC12_A_BASE, ADC12_A_MEMORY_0, // starting memory buffer address ADC12_A_SEQOFCHANNELS); //conversion sequence mode select //Enter LPM4, Enable interrupts __bis_SR_register(LPM4_bits + GIE); //For debugger __no_operation(); } } // ADC12MEM1 interrupt pastes 08h into the ADC12V register and sets bit 1 in the ADC12IFG register, // which is enabled by setting bit 1 in the ADC12IE register. #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=ADC12_VECTOR __interrupt #elif defined(__GNUC__) __attribute__((interrupt(ADC12_VECTOR))) #endif 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: break; //Vector 6: ADC12IFG0 case 8: //Vector 8: ADC12IFG1 //Move results, IFG is cleared results[0] = ADC12_A_getResults(ADC12_A_BASE, ADC12_A_MEMORY_0); //Move results, IFG is cleared results[1] = ADC12_A_getResults(ADC12_A_BASE, ADC12_A_MEMORY_1); //Exit active CPU, SET BREAKPOINT HERE 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; } // User inputs: ADC12_A_configureMemoryParam param2 = {0}; param2.memoryBufferControlIndex = ADC12_A_MEMORY_2; param2.inputSourceSelect = ADC12_A_INPUT_A2; param2.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC; param2.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS; param2.endOfSequence = ADC12_A_ENDOFSEQUENCE; ADC12_A_configureMemory(ADC12_A_BASE,¶m2); ADC12_A_configureMemoryParam param3 = {0}; param3.memoryBufferControlIndex = ADC12_A_MEMORY_3; param3.inputSourceSelect = ADC12_A_INPUT_A3; param3.positiveRefVoltageSourceSelect = ADC12_A_VREFPOS_AVCC; param3.negativeRefVoltageSourceSelect = ADC12_A_VREFNEG_AVSS; param3.endOfSequence = ADC12_A_ENDOFSEQUENCE; ADC12_A_configureMemory(ADC12_A_BASE,¶m3); }