Part Number: MSP432P401R
Tool/software: Code Composer Studio
My goal is to have code that allows me to turn on the ADC by pressing an external button and then an interrupt from Timer A will turn off the ADC after a specified amount of time (ideally, 300 ms). I have written and tested code that generates a GPIO interrupt when an external button connected to P3.0 is pressed, as well as code that turns the ADC off based on an interrupt generated by Timer A. However, when I attempted to put these two code blocks together, I am not getting the desired result.
Currently, the code that I have (shown below) displays 1 ADC value via UART when the external button is pressed, and then the green LED (P2.1) blinks continuously, indicating that timer_flag is always set. Additionally, I am unsure of how to turn off the ADC (when the timer interrupt is set). Any help that anyone could provide would be greatly appreciated.
/* Test ADC ON by external button and OFF by Timer A */
#include "msp.h"
#include "mytiming.h"
volatile unsigned int UART_flag = 0;
volatile unsigned int timer_flag = 0;
volatile unsigned int button_flag = 0;
volatile unsigned int var = 0;
int millivolt = 0;
void UART0_init(void);
void delayMs(int n, int freq);
void setFreq(int freq);
int main(void) {
setFreq(FREQ_3_MHZ);
int mv_char_0 = 0;
int mv_char_1 = 0;
int mv_char_2 = 0;
int mv_char_3 = 0;
char uart_0;
char uart_1;
char uart_2;
char uart_3;
WDT_A->CTL = WDT_A_CTL_PW | // Stop WDT
WDT_A_CTL_HOLD;
// GPIO Setup
P5->SEL1 |= BIT4; // Configure P5.4 for ADC
P5->SEL0 |= BIT4;
//for testing
P2->SEL1 &= ~BIT1; //P2.1 is simple I/O
P2->SEL0 &= ~BIT1;
P2->DIR |= BIT1; // P2.1 set as output pin
P2->OUT &= ~BIT1; // LED initially low (off)
// Initialize Port 3 (button connections)
P3->SEL0 = 0; //clear register selection
P3->SEL1 = 0; //clear register selection
P3->DIR = 0;
P3->OUT = BIT0;
P3->REN = BIT0; //enable pull up resistor
P3->IES = BIT0; //interrupt on high-low transition
P3->IFG = 0; //clear any pending flags
P3->IE = BIT0; //enable port 3 interrupts
UART0_init();
// Enable global interrupt
__enable_irq();
// Enable ADC and Timer A0 interrupts in NVIC module
NVIC_EnableIRQ(TA0_0_IRQn);
NVIC_EnableIRQ(ADC14_IRQn);
NVIC_EnableIRQ(PORT3_IRQn);
// Sampling time, S&H=16, ADC14 on
ADC14->CTL0 = ADC14_CTL0_SHT0_2 | ADC14_CTL0_SHP | ADC14_CTL0_ON;
ADC14->CTL1 = ADC14_CTL1_RES_2;
ADC14->MCTL[0] |= ADC14_MCTLN_INCH_1; /* A1 ADC input select;
Vref=AVCC */
ADC14->IER0 |= ADC14_IER0_IE0; /* Enable ADC conv
complete interrupt */
SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk; /* Wake up on exit from
ISR */
while (1){
if (button_flag){ //button pushed, turn ADC on
button_flag = 0;
ADC14->CTL0 |= ADC14_CTL0_ENC | ADC14_CTL0_SC; //start sampling/conversion
}
if (timer_flag){ //time up, turn ADC off
timer_flag = 0;
P2->OUT |= BIT1; //turn on P2.1 green LED
delayMs(500, FREQ_3_MHZ);
P2->OUT &= ~BIT1; //turn off P2.1 green LED
delayMs(500, FREQ_3_MHZ);
//turn off ADC
}
if (UART_flag) {
UART_flag = 0;
millivolt = (int)((var + 1.46) / 1.2361);
mv_char_3 = millivolt / 1000;
mv_char_2 = millivolt / 100 - (mv_char_3 * 10);
mv_char_1 = millivolt / 10 - (mv_char_3 * 100 + mv_char_2 * 10);
mv_char_0 = millivolt - (mv_char_1 * 10 + mv_char_3 * 1000 + mv_char_2 * 100);
uart_0 = (char) mv_char_0 + '0';
uart_1 = (char) mv_char_1 + '0';
uart_2 = (char) mv_char_2 + '0';
uart_3 = (char) mv_char_3 + '0';
while(!(EUSCI_A0->IFG & 0x02)) { }
EUSCI_A0->TXBUF = uart_3;
while(!(EUSCI_A0->IFG & 0x02)) { }
EUSCI_A0->TXBUF = uart_2;
while(!(EUSCI_A0->IFG & 0x02)) { }
EUSCI_A0->TXBUF = uart_1;
while(!(EUSCI_A0->IFG & 0x02)) { }
EUSCI_A0->TXBUF = uart_0;
while(!(EUSCI_A0->IFG & 0x02)) { }
EUSCI_A0->TXBUF = 0x0D;
}
}
}
// ADC14 interrupt service routine
void ADC14_IRQHandler(void) {
UART_flag = 1;
var = ADC14->MEM[0];
}
//Timer A0 interrupt service routine
void TA0_0_IRQHandler(void){
timer_flag = 1; //flag when timer reaches value
TA0CCTL0 &= ~CCIFG; //clear pending interrupt flag
}
void PORT3_IRQHandler(void) //Interrupt handler for P3.0
{
button_flag = 1; //Set flag to signal button press detected
//configure Timer A0
TA0CCR0 = 20000; // arbitrary value (need 300 ms of ADC)
TA0CCTL0 |= CCIE;
TA0CTL |= TASSEL_2 | MC_1;
P3->IFG = 0; //Clear P3.0 pending interrupt flag
P3->IE &= ~BIT0; //Disable interrupt for P3.0 for debouncing
}
void UART0_init(void)
{
EUSCI_A0->CTLW0 |= 1; // put in reset mode for config
EUSCI_A0->MCTLW = 0; // disable oversampling
EUSCI_A0->CTLW0 = 0x0081; /* 1 stop bit, no parity,SMCLK,byte
data */
EUSCI_A0->BRW = 26; // 3,000,000 / 115200 = 26
P1->SEL0 |= 0x0C; // P1.3, P1.2 for UART
P1->SEL1 &= ~0x0C;
EUSCI_A0->CTLW0 &= ~1; // take UART out of reset mode
}