串口接收超时中断程序思路

方法0:

//通过判断接收连续2个字符之间的时间差不大于10ms来决定是不是一次连续的数据.
//如果2个字符接收间隔超过10ms,则认为不是1次连续数据.也就是超过10ms没有接收到
//任何数据,则表示此次接收完毕.
//接收到的数据状态
//[15]:0,没有接收到数据;1,接收到了一批数据.
//[14:0]:接收到的数据长度
u16 USART2_RX_STA=0;        
void USART2_IRQHandler(void)
{
    u8 res;        
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)//接收到数据
    {     
 
        res =USART_ReceiveData(USART2);        
        if(USART2_RX_STA<USART2_MAX_RECV_LEN)        //还可以接收数据
        {
            TIM_SetCounter(TIM4,0);//计数器清空                         
            if(USART2_RX_STA==0)

                     TIM4_Set(1);         //使能定时器4的中断 
            USART2_RX_BUF[USART2_RX_STA++]=res;        //记录接收到的值     
        }

       else 
        {
            USART2_RX_STA|=1<<15;                    //强制标记接收完成
        } 
    }                                               
}   

//定时器4中断服务程序            
void TIM4_IRQHandler(void)
{     
    if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)//是更新中断
    {                    
        USART2_RX_STA|=1<<15;    //标记接收完成
        TIM_ClearITPendingBit(TIM4, TIM_IT_Update  );  //清除TIMx更新中断标志    
        TIM4_Set(0);            //关闭TIM4  
    }        
}
//设置TIM4的开关
//sta:0,关闭;1,开启;
void TIM4_Set(u8 sta)
{
    if(sta)
    {
       
        TIM_SetCounter(TIM4,0);//计数器清空
        TIM_Cmd(TIM4, ENABLE);  //使能TIMx    
    }else TIM_Cmd(TIM4, DISABLE);//关闭定时器4       
}

方法1:在接收中断中设置定时中断计数初值,开启定时中断

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在M031KG系列微控制器中,可以使用UART_SetTimeoutCnt函数来设置UART串口接收超时时间,并实现超时中断。下面是实现UART1串口接收超时中断的步骤: 1. 首先需要初始化UART1串口,可以使用UART_Open函数进行初始化,设置相应的波特率、数据位、停止位、校验位等参数。 2. 然后使用UART_SetTimeoutCnt函数设置UART1串口接收超时时间,该函数的第一个参数为UART端口号,这里设置为UART_PORT1;第二个参数为超时计数器,即当接收到一个字符后,计数器从该值开始倒计时,如果在倒计时过程中没有再接收到字符,则会触发超时中断;第三个参数为超时中断使能,这里设置为使能。 3. 最后需要配置UART1串口接收中断,使能接收中断超时中断。可以使用NVIC_EnableIRQ函数使能UART1中断,并在中断服务函数中处理接收数据超时中断。 下面是实现UART1串口接收超时中断的示例代码: ``` #include "stdio.h" #include "NuMicro.h" #define RXBUFSIZE 1024 volatile uint8_t comRbuf[RXBUFSIZE]; volatile uint16_t comRbytes = 0; // Available bytes of comRbuf volatile uint16_t comRhead = 0; volatile uint16_t comRtail = 0; void UART1_IRQHandler(void) { uint32_t u32IntSts = UART1->INTSTS; if(u32IntSts & UART_INTSTS_RDAIF_Msk) { /* Get all the input characters */ while(UART_IS_RX_READY(UART1)) { /* Check if buffer full */ if(comRbytes < RXBUFSIZE) { /* Enqueue the character */ comRbuf[comRtail++] = UART_READ(UART1); if(comRtail >= RXBUFSIZE) comRtail = 0; comRbytes++; } else { /* FIFO over run */ } } } if(u32IntSts & UART_INTSTS_RXTOIF_Msk) { /* Timeout counter flag */ /* Reset FIFO */ UART1->FIFO &= ~UART_FIFO_RXRST_Msk; /* Disable RX time-out interrupt */ UART_DisableInt(UART1, UART_INTEN_RXTOIEN_Msk); /* Clear RX time-out interrupt flag */ UART1->INTSTS = UART_INTSTS_RXTOIF_Msk; } } int32_t main (void) { uint32_t u32data; /* Unlock protected registers */ SYS_UnlockReg(); /* Enable UART1 peripheral clock */ CLK_EnableModuleClock(UART1_MODULE); /* Select UART1 module function */ SYS->GPA_MFPH = (SYS->GPA_MFPH & (~SYS_GPA_MFPH_PA10MFP_Msk)) | SYS_GPA_MFPH_PA10MFP_UART1_RXD; SYS->GPA_MFPH = (SYS->GPA_MFPH & (~SYS_GPA_MFPH_PA9MFP_Msk)) | SYS_GPA_MFPH_PA9MFP_UART1_TXD; /* Disable UART1 TX/RX function */ UART1->FUNCSEL = (UART1->FUNCSEL & (~(UART_FUNCSEL_RXDIS_Msk | UART_FUNCSEL_TXDIS_Msk))); /* Set UART1 line configuration */ UART_Open(UART1, 115200); /* Enable UART1 RX time-out interrupt */ UART_SetTimeoutCnt(UART1, 40); UART_EnableInt(UART1, UART_INTEN_RXTOIEN_Msk); NVIC_EnableIRQ(UART1_IRQn); while(1) { /* Get all the input characters */ while(comRbytes) { /* Get a character from the buffer */ u32data = comRbuf[comRhead++]; if(comRhead >= RXBUFSIZE) comRhead = 0; comRbytes--; printf("Received: 0x%02X\n", u32data); } } } ``` 在上面的示例代码中,设置UART1的超时计数器为40,即当接收到一个字符后,计数器从40开始倒计时,如果在倒计时过程中没有再接收到字符,则会触发超时中断中断服务函数中处理接收到的字符和超时中断,在接收到字符时将其存入循环队列中,超时中断时禁用超时中断并清除超时中断标志位。在主函数中循环读取循环队列中的字符并打印。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值