Part Number: MSP432P401R
I had my code working perfectly fine. It still works and runs fine, except now my ADC values are garbage and mean absolutely nothing. I have been testing with P4.7, but wanted to test my idle state so I connected P4.1-4.6 to 5[V] that way their reading would be high and not cause the interrupt so i could isolate it to P4.7. Once i did this all of my values just do random things. I disconnected all pins and connected only P4.7 and now all ADC results are just random super large numbers or small or just anything. I move hand far and close to my sonar sensors and the ADC readings give no form of pattern or logical reading. I know the code works perfectly fine because I was running it for hours testing things and it was all perfect. I would just like to know if anyone can help me figure out what i did when I connected all those pins to the 5[V] and how I can reverse it. To run my code open: Resource Explorer > MSP432P401R LaunchPad - Red 2.x (Red) > SimpleLink MSP432P4 SDK - v:2.30.00.14 > Examples > Development Tools > MSP432P401R LaunchPad - Red 2.x (Red) > DriverLib > adc14_single_conversion_repeat_timera_source > No RTOS > CCS Compiler > Import project to IDE
and copy paste my code it will run fine.
/* DLUG = MSP432_DriverLib_Users_Guide-MSP432P4xx-2_20_00_08 */
/* hold command and click any API to see information about it */
/* DriverLib Includes */
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
/* Standard Includes */
#include <stdint.h>
#include <stdbool.h>
/* For usleep() */
//#include <unistd.h>
//#include <stddef.h>
/* TI-RTOS Header files */
#include <ti/drivers/GPIO.h>
//#include <ti/display/Display.h>
/* Board Header file */
//#include "Board.h"
/* Statics */
uint16_t resultsBuffer[7];//Buffer to hold ADC readings of each Sonar Sensor
/* DLUG section: 2.6.2.25 | Registers an interrupt handler for the ADC interrupt. */
void ADC14_registerInterrupt(void (*ADC14_IRQHandler)(void));
void PWMConfigure(void);//set up PWM
void ADCConfigure(void);//set up ADC
void InitDCO(void);//Change operation frequency of DCO
void SonarOne(void);
void SonarTwo(void);
void SonarThree(void);
void SonarFour(void);
void SonarFive(void);
void SonarSix(void);
void SonarSeven(void);
void EmergencyStop(void);
/**********************Timer_A PWM Configuration Parameter for Right motor*********************
*hold command and click Timer_A_PWMConfig to see that pwmConfigR is a typedef struct _Timer_A_PWMConfig
*S1 is for right motor */
Timer_A_PWMConfig pwmConfigR =
{
TIMER_A_CLOCKSOURCE_SMCLK,//clock source for PWM operation
TIMER_A_CLOCKSOURCE_DIVIDER_1,//divider of clocksource SMCLK
4800,//period
TIMER_A_CAPTURECOMPARE_REGISTER_3,
TIMER_A_OUTPUTMODE_RESET_SET,
2400//start at 50% duty cycle of 5[V] (2.5[V]) so motors not moving.
};
/**********************Timer_A PWM Configuration Parameter for Left motor*********************
*S2 is for left motor*/
Timer_A_PWMConfig pwmConfigL =
{
TIMER_A_CLOCKSOURCE_SMCLK,
TIMER_A_CLOCKSOURCE_DIVIDER_1,
4800,
TIMER_A_CAPTURECOMPARE_REGISTER_4,//makes P2.7 work because TA0.4
TIMER_A_OUTPUTMODE_RESET_SET,
2400
};
/*********************************END TIMER_A_PWMConfig FOR BOTH MOTORS *********************************
* The motors work with direction and speed as one input. 51-100% duty cycle is forward speed (5[V] max,
* higher duty cycle is faster forward speed), 0-49% duty cycle is backward speed (0[V] max, lower duty
* cycle is faster backward speed) and 50% is no movement(2.5[V]).
*
* We want to use about half of each directions duty cycle since we do not want to go fast. Each direction
* has 2,400 levels of speed. Half of each is 1,200 levels of speed. Forward can have a duty cycle of
* 2,401-4,800 and backwards can have a duty cycle of 0 - 2,399. We will be using Forward: 2,401-3,600 &
* Backward: 1,200 - 2,399 */
/*********************************START MAIN**********************************/
int main(void)
{
/* Halting WDT */
MAP_WDT_A_holdTimer();
PWMConfigure();//set up PWM
ADCConfigure();//set up ADC
MAP_Interrupt_enableSleepOnIsrExit();
/* Going to sleep */
while (1)
{
MAP_PCM_gotoLPM0();//sleep while no interrupts are happening.
}
}//END MAIN
/*********************************END MAIN**********************************/
void SonarOne(void){//P4.1 & resultsBuffer[6]
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0);//LED1 (left)
MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN1);
}
void SonarTwo(void){//P4.2 & resultsBuffer[5]
MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1);//LED2 (right)
MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
}
void SonarThree(void){//P4.3 & resultsBuffer[4]
}
void SonarFour(void){//P4.4 & resultsBuffer[3]
}
void SonarFive(void){//P4.5 & resultsBuffer[2]
}
void SonarSix(void){//P4.6 & resultsBuffer[1]
}
void SonarSeven(void){//P4.7 & resultsBuffer[0]
}
/*********************************START ADC HANDLER**********************************/
/* This interrupt is fired whenever a Sonar Reading is whatever the comparator says and the MAP_ADC14_enableInterrupt(X) says. */
void ADC14_IRQHandler(void)
{
uint64_t status;
status = MAP_ADC14_getEnabledInterruptStatus();//gets interrupt status for comparison
MAP_ADC14_clearInterruptFlag(status);//clears interrupt flag for next interrupt check
if(status & ADC_LO_INT)
{
// MAP_ADC14_getMultiSequenceResult(resultsBuffer);
resultsBuffer[0] = MAP_ADC14_getResult(ADC_MEM0);//P4.7
resultsBuffer[1] = MAP_ADC14_getResult(ADC_MEM1);//P4.6
resultsBuffer[2] = MAP_ADC14_getResult(ADC_MEM2);//P4.5
resultsBuffer[3] = MAP_ADC14_getResult(ADC_MEM3);//P4.4
resultsBuffer[4] = MAP_ADC14_getResult(ADC_MEM4);//P4.3
resultsBuffer[5] = MAP_ADC14_getResult(ADC_MEM5);//P4.2
resultsBuffer[6] = MAP_ADC14_getResult(ADC_MEM6);//P4.1
}
if ((resultsBuffer[0] < 550) || (resultsBuffer[1] < 550) || (resultsBuffer[2] < 550) || (resultsBuffer[3] < 550) || (resultsBuffer[4] < 550) || (resultsBuffer[6] < 550) ){//LED 1 ON WHEN OBJECTS ARE CLOSE (RED)
SonarOne();
}
else{//LED 2 ON WHEN OBJECTS ARE FAR (GREEN)
SonarTwo();
}
}//END ADC14 INTERRUPT HANDLER
/*********************************END ADC HANDLER**********************************/
/*********************************START PORT 1 HANDLER**********************************/
/* Port1 ISR - This ISR will progressively step up the duty cycle of the PWM
* on a button press */
void PORT1_IRQHandler(void)
{
uint32_t status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1);//P2.7 brown wire
MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status);
if (status & GPIO_PIN1)
{
if(pwmConfigL.dutyCycle == 4800 && pwmConfigR.dutyCycle == 4800){
pwmConfigL.dutyCycle = 480;
pwmConfigR.dutyCycle = 480;}
else{
pwmConfigL.dutyCycle += 480;
pwmConfigR.dutyCycle += 480;}
MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfigL);
}
}//END PORT 1 INTERRUPT HANDLER
/*********************************END PORT 1 HANDLER**********************************/
/*********************************START PWM CONFIGURE**********************************/
void PWMConfigure(){
InitDCO();//Change clock frequency to 48[MHz]
/* DLUG section: 6.6.2.18 | Initialize SMCLK to DCOCLK frequency divided by 1*/
MAP_CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);
/* Configuring GPIO2.7 as peripheral output for PWM for right motor and
* Configuring GPIO2.6 as peripheral output for PWM for left motor and P1.1 for button interrupt */
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);//P2.7 (right motor)
MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN6, GPIO_PRIMARY_MODULE_FUNCTION);//P2.6 (left motor)
MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1);//set Pin 1 on Port 1
MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1);
MAP_GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1);
// Interrupt_setPriority(INT_PORT1,0);
/* DLUG section: 12.4.2.4 | Enabling interrupts on port 1 for button */
MAP_Interrupt_enableInterrupt(INT_PORT1);
/* DLUG section: 24.4.2.11 | Generate a PWM with timer running in up mode. Clock is set at 48[MHz],
* which is 0.0208333[us] [Microseconds] (2.08s*10^-8). Each Timer is set up with a period of 4,800
* ticks so period is 0.0001[s] which is a frequency of 1/.0001 = 10[kHz] */
MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfigR);
MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfigL);
}//END PWM CONFIGURATION
/*********************************END PWM CONFIGURE**********************************/
/*********************************START ADC CONFIGURE**********************************/
void ADCConfigure(){
/* DLUG section: 2.6.2.14 | This will enable operation of the ADC block. */
MAP_ADC14_enableModule();
// MAP_ADC14_initModule(ADC_CLOCKSOURCE_ADCOSC, ADC_PREDIVIDER_1, ADC_DIVIDER_1,
// 0);
/* Configuring GPIOs for Tertiary Function and inputs on Port 4 Pins 1-7 inclusive */
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN1 | GPIO_PIN2 | GPIO_PIN3 |
GPIO_PIN4 | GPIO_PIN5 | GPIO_PIN6 | GPIO_PIN7 , GPIO_TERTIARY_MODULE_FUNCTION);
/* Setting LED1 and LED2 on board as outputs and initializing them as low */
MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);//LED1(left and red)
MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN1);
MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN1);//LED2(right and green)
// MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN2);
/* DLUG section: 2.6.2.3 | Configuring ADC Memory (ADC_MEM0 - ADC_MEM6 (A6 - A12) with no repeat)
* with internal 3.3[V] reference */
MAP_ADC14_configureMultiSequenceMode(ADC_MEM0,ADC_MEM6, true);
/* DLUG section: 2.6.2.2 | Configures individual memory locations for each ADC module.
* (memory locations, type of voltage reference, which channel is being used for
* ADC sampling, false for non-differential inputs) */
//ADC_VREFPOS_INTBUF_VREFNEG_VSS (does 2.5[V] reference voltage)
MAP_ADC14_configureConversionMemory(ADC_MEM0,
ADC_VREFPOS_AVCC_VREFNEG_VSS, ADC_INPUT_A6, false);//ADC6 = P4.7 = MEM0
MAP_ADC14_configureConversionMemory(ADC_MEM1,
ADC_VREFPOS_AVCC_VREFNEG_VSS, ADC_INPUT_A7, false);//ADC7 = P4.6 = MEM1
MAP_ADC14_configureConversionMemory(ADC_MEM2,
ADC_VREFPOS_AVCC_VREFNEG_VSS, ADC_INPUT_A8, false);//ADC8 = P4.5 = MEM2
MAP_ADC14_configureConversionMemory(ADC_MEM3,
ADC_VREFPOS_AVCC_VREFNEG_VSS, ADC_INPUT_A9, false);//ADC9 = P4.4 = MEM3
MAP_ADC14_configureConversionMemory(ADC_MEM4,
ADC_VREFPOS_AVCC_VREFNEG_VSS, ADC_INPUT_A10, false);//ADC10 = P4.3 = MEM4
MAP_ADC14_configureConversionMemory(ADC_MEM5,
ADC_VREFPOS_AVCC_VREFNEG_VSS, ADC_INPUT_A11, false);//ADC11 = P4.2 = MEM5
MAP_ADC14_configureConversionMemory(ADC_MEM6,
ADC_VREFPOS_AVCC_VREFNEG_VSS, ADC_INPUT_A12, false);//ADC12 = P4.1 = MEM6
/* DLUG section: 2.6.2.16 | Setting up the sample timer to automatically step through the sequence convert
* After one sample/convert is finished, the ADC module will automatically continue on to the next sample.*/
MAP_ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION);
/*DLUG section: 2.6.2.11 | Enables the specified mask of memory channels to use the specified comparator window. The
ADCC module has two different comparator windows that can be set with this function.*/
ADC14_enableComparatorWindow(ADC_MEM0 | ADC_MEM1 | ADC_MEM2 | ADC_MEM3 | ADC_MEM4 | ADC_MEM5 | ADC_MEM6,
ADC_COMP_WINDOW0);
// ADC14_enableComparatorWindow(ADC_MEM0 | ADC_MEM1 | ADC_MEM2 | ADC_MEM3 | ADC_MEM4 | ADC_MEM5 | ADC_MEM6,
// ADC_COMP_WINDOW1);
/* DLUG section: 2.6.2.26 | Sets the lower and upper limits of the specified window comparator.
* (window 0 or 1, lower limit, upper limit) */
ADC14_setComparatorWindowValue(ADC_COMP_WINDOW0,550, 2000);
// ADC14_setComparatorWindowValue(ADC_COMP_WINDOW1,550, 2000);
/* DLUG section: 2.6.2.13 | Enabling the interrupt when a channel drops below threshold of comparator,
* if use ADC_HI_INT enables interrupt when channel goes above threshold of comparator or
* ADC_IN_INT enables interrupt channel when channel is whithin threshold */
MAP_ADC14_enableInterrupt(ADC_LO_INT);
// MAP_ADC14_enableInterrupt(ADC_HI_INT);
// MAP_ADC14_enableInterrupt(ADC_IN_INT);
/* DLUG section: 12.4.2.4 - 12.4.2.5 | Enabling Interrupts */
MAP_Interrupt_enableInterrupt(INT_ADC14);
// Interrupt_setPriority(INT_ADC14,0);
MAP_Interrupt_enableMaster();
/* DLUG section: 2.6.2.12 & 2.6.2.32 | Enables conversion of ADC data. Triggering the start of the sample.
* Toggles the trigger for conversion of the ADC module by toggling the trigger software bit.*/
MAP_ADC14_enableConversion();
MAP_ADC14_toggleConversionTrigger();
}//END ADC CONFIGURATION
/*********************************END ADC CONFIGURE**********************************/
/*********************************START DCO INIT**********************************/
void InitDCO() {
/* DLUG section: 9.3.2.4 | Enables the floating-point unit. */
FPU_enableModule();
/* DLUG section: 14.7.2.16 | Sets the core voltage level (Vcore). The function will
* take care of all power state transitions needed to shift between core voltage levels.
* Before we start we have to change VCORE to 1 to support the 48MHz frequency */
PCM_setCoreVoltageLevel(PCM_AM_LDO_VCORE1);
/* DLUG section: 8.4.2.22 | Changes the number of wait states that are used by the flash
* controller for read operations. When changing frequency ranges of the clock, this
* functions must be used in order to allow for readable flash memory.*/
FlashCtl_setWaitState(FLASH_BANK0, 1);
FlashCtl_setWaitState(FLASH_BANK1, 1);
/* DLUG section: 6.6.2.21 | Sets the centered frequency of DCO operation to [32MHz to 64MHz]. */
MAP_CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_48);
/* DLUG section: 9.3.2.1 | Disables the floating-point unit. */
FPU_disableModule();
}//END DCO INITIALIZATION
/*********************************END DCO INIT**********************************/
/*********************************START EMERGENCY STOP**********************************/
void EmergencyStop(){
pwmConfigL.dutyCycle = 2400;
pwmConfigR.dutyCycle = 2400;
}
/*********************************END EMERGENCY STOP**********************************/