This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
器件型号:MSP432P401R
工具/软件:Code Composer Studio
我正在尝试在 P3.0、P3.2、P3.3、P3.5和 P3.6上启用 GPIO 中断、我在这里连接了外部按钮。 当我仅为 P3.0启用中断时、我可以让我的代码执行、但我不确定需要启用什么才能在其他引脚上获得中断。
此外、我知道、通常、当您在同一端口的多个引脚上有中断时、您需要确定 ISR 中设置了哪个 IFG。 但是、我不确定是否需要这样做、因为我希望我的所有中断都完成相同的任务、所以我不关心哪个引脚触发中断。
我附加了在 P3.0上启用中断的代码、如果有人能够提供有关如何在其他引脚上初始化中断的任何见解、我尝试在下面为 P3.2启用中断、但未成功。 以及如何在 ISR 中处理 IFG 位、我会非常感激!
/*使用外部按钮测试 ADC、使用计时器 A 测试 ADC */ #include "msp.h" #include "mytime.h" volatile unsigned int UART_flag = 0; volatile unsigned int timer_flag = 0; volatile unsigned int var = 0; int mvoltv = 0; void UART0_init (void); setfreq (void);int freq (void) 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; 字符 UART_0; 字符 UART_1; 字符 UART_2; 字符 UART_3; WDT_A->CTL = WDT_A_CTL_PW | //停止 WDT WDT_A_CTL_HOLD; // GPIO 设置 P5->SEL1 |= BIT4; //为 ADC 配置 P5.4 P5->SEL0 |= BIT4; //初始化端口3 (按钮连接) P3->SEL0 = 0;//清除寄存器选择 P3->SEL1 = 0;//清除寄存器选择 P3->SEL0 |= BIT2; P3->SEL1 |= BIT2; P3->DIR = 0; P3->DIR = BIT2; P3->OUT = BIT0; P3->OUT = BIT2; P3->REN = BIT0;//启用上拉电阻 P3->REN = BIT2; P3->IES = BIT0;//高-低转换时中断 P3->IES = BIT2; P3->IFG = 0; //清除任何挂起标志 P3->IE = BIT0;//启用端口3中断 P3->IE = BIT2; UART0_init(); //启用全局中断 __ENABLE_IRQ(); //在 NVIC 模块中启用 ADC 和计时器 A0中断 NVIC_EnableIRQ (TA0_0_IRQn); NVIC_EnableIRQ (ADC14_IRQn); NVIC_EnableIRQ (PORT3_IRQn); //采样时间、S&H=16、ADC14打开 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 输入选择; VREF=AVCC */ ADC14->IER0 |= ADC14_IER0_IE0; /*启用 ADC 转换 完成中断*/ SCB->SCR &=~SCB_SCR_SLEEPONEXIT_MSK;/*退出时唤醒 ISR */ while (1){ if (button_flag){ //按钮被按下、打开 ADC ADC14->CTL0 |= ADC14_CTL0_ENC | ADC14_CTL0_SC;//开始采样/转换 button_flag = 0; //复位标志 P3->IFG = 0; //清除任何挂起标志 } if (timer_flag){ //time up、关闭 ADC ADC14->CTL0 &=~ADC14_CTL0_ENC;//关闭 ADC Timer_flag = 0; P3->IE |= BIT0; //重新启用 P3.0中断 P3->IE |= BIT2; //重新启用 P3.2中断 } if (UART_flag){ UART_FLAG = 0; 毫伏=(int)((var + 1.46)/ 1.2361); mV_char_3 =毫伏/1000; mV_char_2 =毫伏/100 -(mV_char_3 * 10); MV_CHAR_1 =毫伏/ 10 -(MV_CHAR_3 * 100 + MV_CHAR_2 * 10); mV_char_0 =毫伏-(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中断服务例程 void ADC14_IRQHandler (void){ UART_FLAG = 1; VAR = ADC14->MEM[0]; } //计时器 A0中断服务例程 void TA0_0_IRQHandler (void){ Timer_flag = 1; 定时器达到值时为//flag TA0CCTL0 &=~CCIFG; //清除挂起中断标志 TA0CTL = 0; //关闭计时器 } void PORT3_IRQHandler (void) //端口3 的中断处理程序{ button_flag = 1; //set flag to signal button pressed.(检测到按压信号。 //配置计时器 A0 TA0CCR0 = 900000; //计时器长度= 300ms TA0CCTL0 |= CCIE; TA0CTL |= TASSEL_2 | MC_1; P3->IFG = 0; //清除挂起中断标志 P3->IE &=~BIT0; //禁用 P3.0的去抖中断 P3->IE &=~BIT2; //禁用 P3.2的去抖中断 } void UART0_init (void) { EUSCI_A0->CTLW0 |= 1; //为 config 进入复位模式 EUSCI_A0->MCTLW = 0; //禁用过采样 EUSCI_A0->CTLW0 = 0x0081;/* 1停止位、无奇偶校验、SMCLK、字节 数据*/ EUSCI_A0->BRW = 26; // 3、000、000 / 115200 = 26 P1->SEL0 |= 0x0C; //对于 UART、P1.3、P1.2 P1->SEL1 &=~0x0C; EUSCI_A0->CTLW0 &=~1; //使 UART 退出复位模式 }
我更改了=的所有实例、我认为应该是|=、当按钮连接到 P3.0而不是 P3.2时、我具有适当的中断功能。 当我将一个外部按钮连接到 P3.2时、没有发生任何事情、我不确定原因。
/*使用外部按钮测试 ADC、使用计时器 A 测试 ADC */ #include "msp.h" #include "mytime.h" volatile unsigned int UART_flag = 0; volatile unsigned int timer_flag = 0; volatile unsigned int var = 0; int mvoltv = 0; void UART0_init (void); setfreq (void);int freq (void) 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; 字符 UART_0; 字符 UART_1; 字符 UART_2; 字符 UART_3; WDT_A->CTL = WDT_A_CTL_PW | //停止 WDT WDT_A_CTL_HOLD; // GPIO 设置 P5->SEL1 |= BIT4; //为 ADC 配置 P5.4 P5->SEL0 |= BIT4; //初始化端口3 (按钮连接) P3->SEL0 = 0;//清除寄存器选择 P3->SEL1 = 0;//清除寄存器选择 P3->SEL0 |= BIT2; P3->SEL1 |= BIT2; P3->DIR |= BIT0; P3->DIR |= BIT2; P3->OUT |= BIT0; P3->OUT |= BIT2; P3->REN |= BIT0;//enable 上拉电阻器 P3->REN |= BIT2; P3->IES |= BIT0;//高-低转换时中断 P3->IES |= BIT2; P3->IFG = 0; //清除任何挂起标志 P3->IE |= BIT0;//启用端口3中断 P3->IE |= BIT2; UART0_init(); //启用全局中断 __ENABLE_IRQ(); //在 NVIC 模块中启用 ADC 和计时器 A0中断 NVIC_EnableIRQ (TA0_0_IRQn); NVIC_EnableIRQ (ADC14_IRQn); NVIC_EnableIRQ (PORT3_IRQn); //采样时间、S&H=16、ADC14打开 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 输入选择; VREF=AVCC */ ADC14->IER0 |= ADC14_IER0_IE0; /*启用 ADC 转换 完成中断*/ SCB->SCR &=~SCB_SCR_SLEEPONEXIT_MSK;/*退出时唤醒 ISR */ while (1){ if (button_flag){ //按钮被按下、打开 ADC ADC14->CTL0 |= ADC14_CTL0_ENC | ADC14_CTL0_SC;//开始采样/转换 button_flag = 0; //复位标志 P3->IFG = 0; //清除任何挂起标志 } if (timer_flag){ //time up、关闭 ADC ADC14->CTL0 &=~ADC14_CTL0_ENC;//关闭 ADC Timer_flag = 0; P3->IE |= BIT0; //重新启用 P3.0中断 P3->IE |= BIT2; } if (UART_flag){ UART_FLAG = 0; 毫伏=(int)((var + 1.46)/ 1.2361); mV_char_3 =毫伏/1000; mV_char_2 =毫伏/100 -(mV_char_3 * 10); MV_CHAR_1 =毫伏/ 10 -(MV_CHAR_3 * 100 + MV_CHAR_2 * 10); mV_char_0 =毫伏-(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中断服务例程 void ADC14_IRQHandler (void){ UART_FLAG = 1; VAR = ADC14->MEM[0]; } //计时器 A0中断服务例程 void TA0_0_IRQHandler (void){ Timer_flag = 1; 定时器达到值时为//flag TA0CCTL0 &=~CCIFG; //清除挂起中断标志 TA0CTL = 0; //关闭计时器 } void PORT3_IRQHandler (void) //端口3 的中断处理程序{ button_flag = 1; //set flag to signal button pressed.(检测到按压信号。 //配置计时器 A0 TA0CCR0 = 900000; //计时器长度= 300ms TA0CCTL0 |= CCIE; TA0CTL |= TASSEL_2 | MC_1; P3->IFG = 0; //清除 P3.0挂起中断标志 P3->IE &=~BIT0; //禁用 P3.0的去抖中断 P3->IE &=~BIT2; //禁用 P3.0的去抖中断 } void UART0_init (void) { EUSCI_A0->CTLW0 |= 1; //为 config 进入复位模式 EUSCI_A0->MCTLW = 0; //禁用过采样 EUSCI_A0->CTLW0 = 0x0081;/* 1停止位、无奇偶校验、SMCLK、字节 数据*/ EUSCI_A0->BRW = 26; // 3、000、000 / 115200 = 26 P1->SEL0 |= 0x0C; //对于 UART、P1.3、P1.2 P1->SEL1 &=~0x0C; EUSCI_A0->CTLW0 &=~1; //使 UART 退出复位模式 }
由于您计划执行更多的操作、我建议您使用辅助函数来帮助您跟踪:
void pi_setup (unsigned char pinmask) { P3->SEL0 &=~Ω 引脚掩码;// GPIO、非 P3->SEL1 &=~Ω 引脚掩码;//替代功能 P3->DIR &=~引脚掩码;//输入 P3->OUT |= pinmask;//上拉,而不是下拉 P3->REN |= pinmask;//启用上拉 P3->IES |= pinmask;//高->低转换 p3->IFG &=~pinmask;//清除可能的过时 IFG P3->IE |= pinmask;//启用 IFG 返回; }
例如、使用"pi_setup (BIT2);"来调用它。 这不是最快的方法、但您只能在启动时执行一次。