Part Number:MSP432P401R
Tool/software: Code Composer Studio
Is it possible to periodically trigger the ADC to sample in autoscan mode? I would like the set up the adc to read an array of sensor periodically but not continuously. I've tried to combined driver library examples
"adc14_multiple_channel_no_repeat" and "adc14_single_conversion_repeat_timera_source", using the parts from both that i thought would work. The code I have now does a conversion for the sequence only
once and never enters the ISR again. My project will required the sensor array to be sample at a rate of 15 - 25 Hz.
I would appreciate if someone could review my code and give me some insight.
/* * ------------------------------------------- * MSP432 DriverLib - v3_21_00_05 * ------------------------------------------- * * --COPYRIGHT--,BSD,BSD * Copyright (c) 2016, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * --/COPYRIGHT--*/ /******************************************************************************* * MSP432 ADC14 - Multiple Channel Sample without Repeat * * Description: In this code example, the feature of being able to scan multiple * ADC channels is demonstrated by the user a the DriverLib APIs. Conversion * memory registers ADC_MEM0 - ADC_MEM7 are configured to read conversion * results from A0-A7 respectively. Conversion is enabled and then sampling is * toggled using a software toggle. Repeat mode is not enabled and sampling only * occurs once (and it is expected that the user pauses the debugger to observe * the results). Once the final sample has been taken, the interrupt for * ADC_MEM7 is triggered and the result is stored in the resultsBuffer buffer. * * MSP432P401 * ------------------ * /|\| | * | | | * --|RST P5.5 |<--- A0 (Analog Input) * | P5.4 |<--- A1 (Analog Input) * | P5.3 |<--- A2 (Analog Input) * | P5.2 |<--- A3 (Analog Input) * | P5.1 |<--- A4 (Analog Input) * | P5.0 |<--- A5 (Analog Input) * | P4.7 |<--- A6 (Analog Input) * | P4.6 |<--- A7 (Analog Input) * | | * | | * * Author: Timothy Logan ******************************************************************************/ /* DriverLib Includes */ #include "driverlib.h" /* Standard Includes */ #include <stdint.h> #include <stdbool.h> #include <string.h> static uint16_t resultsBuffer[8]; /* Timer_A Continuous Mode Configuration Parameter */ const Timer_A_UpModeConfig upModeConfig = { TIMER_A_CLOCKSOURCE_ACLK, // ACLK Clock Source TIMER_A_CLOCKSOURCE_DIVIDER_1, // ACLK/1 = 32Khz 16384, TIMER_A_TAIE_INTERRUPT_DISABLE, // Disable Timer ISR TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE, // Disable CCR0 TIMER_A_DO_CLEAR // Clear Counter }; /* Timer_A Compare Configuration Parameter */ const Timer_A_CompareModeConfig compareConfig = { TIMER_A_CAPTURECOMPARE_REGISTER_1, // Use CCR1 TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE, // Disable CCR interrupt TIMER_A_OUTPUTMODE_SET_RESET, // Toggle output but 16384 // 16000 Period }; int main(void) { /* Halting WDT */ MAP_WDT_A_holdTimer(); MAP_Interrupt_enableSleepOnIsrExit(); /* Zero-filling buffer */ memset(resultsBuffer, 0x00, 8); /* Setting up clocks * MCLK = MCLK = 3MHz * ACLK = REFO = 32Khz */ MAP_CS_initClockSignal(CS_ACLK, CS_REFOCLK_SELECT, CS_CLOCK_DIVIDER_1); /* Setting reference voltage to 2.5 and enabling reference */ MAP_REF_A_setReferenceVoltage(REF_A_VREF2_5V); MAP_REF_A_enableReferenceVoltage(); /* Initializing ADC (MCLK/1/1) */ MAP_ADC14_enableModule(); MAP_ADC14_initModule(ADC_CLOCKSOURCE_MCLK, ADC_PREDIVIDER_1, ADC_DIVIDER_1, 0); /* Configuring GPIOs for Analog In */ MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN5 | GPIO_PIN4 | GPIO_PIN3 | GPIO_PIN2 | GPIO_PIN1 | GPIO_PIN0, GPIO_TERTIARY_MODULE_FUNCTION); MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN7 | GPIO_PIN6, GPIO_TERTIARY_MODULE_FUNCTION); /* Configuring ADC Memory (ADC_MEM0 - ADC_MEM7 (A0 - A7) with no repeat) * with internal 2.5v reference */ MAP_ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM7, false); MAP_ADC14_configureConversionMemory(ADC_MEM0, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A0, false); MAP_ADC14_configureConversionMemory(ADC_MEM1, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A1, false); MAP_ADC14_configureConversionMemory(ADC_MEM2, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A2, false); MAP_ADC14_configureConversionMemory(ADC_MEM3, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A3, false); MAP_ADC14_configureConversionMemory(ADC_MEM4, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A4, false); MAP_ADC14_configureConversionMemory(ADC_MEM5, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A5, false); MAP_ADC14_configureConversionMemory(ADC_MEM6, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A6, false); MAP_ADC14_configureConversionMemory(ADC_MEM7, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A7, false); //----------------------------------------------------------- /* Configuring Timer_A in continuous mode and sourced from ACLK */ MAP_Timer_A_configureUpMode(TIMER_A0_BASE, &upModeConfig); /* Configuring Timer_A0 in CCR1 to trigger at 16000 (0.5s) */ MAP_Timer_A_initCompare(TIMER_A0_BASE, &compareConfig); /* Configuring the sample trigger to be sourced from Timer_A0 and setting it * to automatic iteration after it is triggered*/ MAP_ADC14_setSampleHoldTrigger(ADC_TRIGGER_SOURCE1, false); MAP_ADC14_enableSampleTimer(ADC_MANUAL_ITERATION); /* Enabling the interrupt when a conversion on channel 7 (end of sequence) * is complete and enabling conversions */ MAP_ADC14_enableInterrupt(ADC_INT7); MAP_ADC14_enableConversion(); /* Enabling Interrupts */ MAP_Interrupt_enableInterrupt(INT_ADC14); MAP_Interrupt_enableMaster(); /* Starting the Timer */ MAP_Timer_A_startCounter(TIMER_A0_BASE, TIMER_A_UP_MODE); /* Going to sleep */ while (1) { MAP_PCM_gotoLPM0(); } } /* This interrupt is fired whenever a conversion is completed and placed in * ADC_MEM7. This signals the end of conversion and the results array is * grabbed and placed in resultsBuffer */ void ADC14_IRQHandler(void) { uint64_t status; status = MAP_ADC14_getEnabledInterruptStatus(); MAP_ADC14_clearInterruptFlag(status); if(status & ADC_INT7) { MAP_ADC14_getMultiSequenceResult(resultsBuffer); } }