单片机中断能够及时响应外部触发事件,在中断函数中处理外部事件,处理完成之后退回到中断点。中断服务函数应该能最快速的解决触发事件,快速退出中断,不宜在中断中处理复杂的运行算法。所以中断函数的编写尽量简单明了快速,下面以串口接收中断为例来说明中断处理函数的写法。
1.设置一个全局标志,触发中断之后在中断函数内把该标志设置为1,清除中断标志位,然后退出中断。在主函数内判断该标志位是否置1,如果置1就处理中断事件,最后把该标志位清除。该方式适合中断处理的事件比较耗时,运行大量计算时使用。
uint8_t flag=0;//全局变量标志位初始置0
//中断服务函数
void USART3_IRQHandler(void)
{
if(USART_GetITStatus( USART3,USART_IT_RXNE)!=RESET)
{
flag=1;//置1中断标志
USART_ClearITPendingBit(USART3, USART_IT_RXNE);
}
}
//主函数
int main(void)
{
bsp_int();
while(1)
{
if(flag==1)
{
....//中断处理
flag=0;//清除中断标志
}
}
}
2.串口接收数据发生中断时,接收完数据帧第一个字节之后,关闭串口接收中断。循环判定接收寄存器非空标志是否置位,读取剩余数据,直到数据接收完成。最后,清除中断标志,重新开启串口接收中断,退出中断等待下次中断触发。该方式适合接收固定长度少量数据的情况。
//中断服务函数
void USART3_IRQHandler(void)
{
u16 i=0xFFFF;
if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET)
{
USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);//关闭串口中断
GPS_RX[GPS_Cnt++]= USART_ReceiveData(USART2);
do
{
if(USART_GetFlagStatus(USART2,USART_FLAG_RXNE)!=RESET)
{
GPS_RX[GPS_Cnt++]= USART_ReceiveData(USART2);
USART_ClearFlag(USART2,USART_FLAG_RXNE);
}
if(GPS_RX[GPS_Cnt-1]==0x0a)break;
}while(i--);
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
}
GPS_Iint();//重新开启串口中断
}