APM32F072程序开发的时候,测试的时候会出现死机的情况,具体表现为上位机通过串口发送数据,连续点击按钮(一直发送数据)会导致主程序中的呼吸灯不闪烁(主程序不运行。)
有问题先debug看一下,发现主程序不运行之后,TImer定时器中断还在正常进入中断;
串口中断接收也一直进入中断,拔掉通信线,仍然一直进入串口中断,但是不是接收中断。凭借我多年的经验,应该是出现了别的说明其他的中断,该中断标志需要软件清除,接收中断的话读出接收寄存器就会清除中断标志。
我的中断函数如下:
void USART_CONFIG_Receive_Isr(void)
{
uint8_t RX_CONFIG_Buffer;
if (USART_ReadStatusFlag(USART_CONFIG, USART_FLAG_RXBNE) == SET)
{
RX_CONFIG_Buffer = (uint8_t)USART_RxData(USART_CONFIG);
USARTCONFIG_RX_Buff[USARTCONFIG_RxEnd++] = RX_CONFIG_Buffer;
USARTCONFIG_RxEnd &= (USARTCONFIG_RX_LENGTH - 1);
// printf("%c", RX_CONFIG_Buffer);
}
}
查看配置文件,我也没有打开其他的中断啊,只打开了接收中断,就是这一句USART_EnableInterrupt(COM_USART[COM], USART_INT_RXBNEIE)。
void USART_Init(COM_T COM,uint16_t bauds)
{
GPIO_Config_T gpioConfig;
USART_Config_T usartConfigStruct;
/* Enable GPIO clock */
RCM_EnableAHBPeriphClock(COM_TX_PORT_CLK[COM] | COM_RX_PORT_CLK[COM]);
/* Enable COM1 or COM2 clock */
if (COM == COM1)
{
RCM_EnableAPB2PeriphClock(COM_USART_CLK[COM]);
}
else
{
RCM_EnableAPB1PeriphClock(COM_USART_CLK[COM]);
}
/* Connect PXx to USARTx_Tx */
GPIO_ConfigPinAF(COM_TX_PORT[COM], COM_TX_PIN_SOURCE[COM], COM_TX_AF[COM]);
/* Connect PXx to USARTx_Rx */
GPIO_ConfigPinAF(COM_RX_PORT[COM], COM_RX_PIN_SOURCE[COM], COM_RX_AF[COM]);
/* Configure USART Tx as alternate function push-pull */
gpioConfig.mode = GPIO_MODE_AF;
gpioConfig.pin = COM_TX_PIN[COM];
gpioConfig.speed = GPIO_SPEED_50MHz;
gpioConfig.outtype = GPIO_OUT_TYPE_PP;
gpioConfig.pupd = GPIO_PUPD_PU;
GPIO_Config(COM_TX_PORT[COM], &gpioConfig);
/* Configure USART Rx as input floating */
gpioConfig.pin = COM_RX_PIN[COM];
GPIO_Config(COM_RX_PORT[COM], &gpioConfig);
usartConfigStruct.baudRate = bauds;
usartConfigStruct.mode = USART_MODE_TX_RX;
usartConfigStruct.hardwareFlowCtrl = USART_FLOW_CTRL_NONE;
usartConfigStruct.parity = USART_PARITY_NONE;
usartConfigStruct.stopBits = USART_STOP_BIT_1;
usartConfigStruct.wordLength = USART_WORD_LEN_8B;
USART_Config(COM_USART[COM], &usartConfigStruct);
/* Enable USART_Interrupt_RXBNEIE */
USART_EnableInterrupt(COM_USART[COM], USART_INT_RXBNEIE);
if (COM_USART[COM] == USART1)
{
NVIC_EnableIRQRequest(USART1_IRQn, 1);
}
else if (COM_USART[COM] == USART2)
{
NVIC_EnableIRQRequest(USART2_IRQn, 2);
}
if (COM_USART[COM] == USART3)
{
NVIC_EnableIRQRequest(USART3_4_IRQn, 3);
}
/* Enable USART */
USART_Enable(COM_USART[COM]);
}
但是肯定就是产生了其他中断,进了串口中断,但是USART_ReadStatusFlag(USART_CONFIG, USART_FLAG_RXBNE)的结果并没有置位,不是接收中断,根据连点产生这种情况的现象,大胆猜测一下应该是溢出中断,但是为啥呢?查手册!!!!!!!!!
好家伙,别人置0都是禁止使能中断,唯独溢出中断置0是使能,寄存器的复位值是0,原来溢出中断是打开的。
所以,两种方法:
1.设置溢出中断使能位为1,禁止溢出中断;
2.在串口中断中,软件清除溢出中断标志位。
验证(我比较懒,懒得查怎么关闭中断):
我直接在串口中断中判断是否溢出中断,如果产生了溢出中断,就清除中断标志位。
void USART_CONFIG_Receive_Isr(void)
{
uint8_t RX_CONFIG_Buffer;
if (USART_ReadStatusFlag(USART_CONFIG, USART_FLAG_RXBNE) == SET)
{
RX_CONFIG_Buffer = (uint8_t)USART_RxData(USART_CONFIG);
USARTCONFIG_RX_Buff[USARTCONFIG_RxEnd++] = RX_CONFIG_Buffer;
USARTCONFIG_RxEnd &= (USARTCONFIG_RX_LENGTH - 1);
// printf("%c", RX_CONFIG_Buffer);
}
if (USART_ReadStatusFlag(USART_CONFIG, USART_FLAG_OVRE) == SET)//溢出中断
{
USART_ClearIntFlag(USART_CONFIG,USART_INT_FLAG_OVRE);
}
}
如上改动之后,再次测试,没有发生死机现象,问题解决。