Tool/software: Code Composer Studio
I am trying to enable GPIO interrupts on P3.0, P3.2, P3.3, P3.5, and P3.6 where I have external buttons connected. When I enable an interrupt for just P3.0 I can get my code to execute, but I'm unsure what I need to enable to get interrupts on the other pins.
Additionally, I know that, generally, when you have interrupts on multiple pins of the same port you need to determine which IFG was set in the ISR. However, I'm not sure if I need to do this as I want all of my interrupts to accomplish the same task, so I don't care which pin triggers the interrupt.
I have attached code that enables an interrupt on P3.0 and is attempting, unsuccessfully, to enable an interrupt for P3.2 below, if anybody could provide any insight into how to initialize the interrupts on the other pins, and how to handle the IFG bits in the ISR, I would greatly appreciate it!
/* 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 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;
// Initialize Port 3 (button connections)
P3->SEL0 = 0; //clear register selection
P3->SEL1 = 0; //clear register selection
P3->SEL0 |= BIT2;
P3->SEL1 |= BIT2;
P3->DIR = 0;
P3->DIR = BIT2;
P3->OUT = BIT0;
P3->OUT = BIT2;
P3->REN = BIT0; //enable pull up resistor
P3->REN = BIT2;
P3->IES = BIT0; //interrupt on high-low transition
P3->IES = BIT2;
P3->IFG = 0; //clear any pending flags
P3->IE = BIT0; //enable port 3 interrupts
P3->IE = BIT2;
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
ADC14->CTL0 |= ADC14_CTL0_ENC | ADC14_CTL0_SC; //start sampling/conversion
button_flag = 0; //Reset flag
P3->IFG = 0; //clear any pending flags
}
if (timer_flag){ //time up, turn ADC off
ADC14->CTL0 &= ~ADC14_CTL0_ENC; //turn off ADC
timer_flag = 0;
P3->IE |= BIT0; //re-enable P3.0 interrupt
P3->IE |= BIT2; //re-enable P3.2 interrupt
}
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
TA0CTL = 0; //turn off the timer
}
void PORT3_IRQHandler(void) //Interrupt handler for Port 3
{
button_flag = 1; //Set flag to signal button press detected
//configure Timer A0
TA0CCR0 = 900000; //Timer length = 300ms
TA0CCTL0 |= CCIE;
TA0CTL |= TASSEL_2 | MC_1;
P3->IFG = 0; //Clear pending interrupt flag
P3->IE &= ~BIT0; //Disable interrupt for P3.0 for debouncing
P3->IE &= ~BIT2; //Disable interrupt for P3.2 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
}