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);
}
}