USART接收不定长数据 -空闲中断

本文介绍了USART的两种数据接收方法:非空中断配合简单协议和IDLE空闲中断配合DMA。特别强调了IDLE空闲中断在不同应用场景下的适用性和代码编写中的注意事项,以及DMA的使用设置。
摘要由CSDN通过智能技术生成

USART 的两种数据接收方式

1:RENE - 非空中断

常配合简单的数据协议,如判断某字符为接收结束标志。正点原子的代码中USART接收就是使用这种方式。每个字节中断一次。系统实时性要求较高时得注意, 如无人机等.

2:IDLE - 空闲中断 + DMA

DMA接收:无需代码干预,DMA自动把接收到的字节,顺序存放到指定数组缓存!
空闲中断:自接收到上个字节完成起(RXNE=1),超过一个字节周期时长没收到新数据,产生硬件中断(USART的SR第4位IDLE被置1),这时USART_IRQHANDLER()函数被调用,用户可在这里识别中断的类型,并做数据处理。

空闲中断-使用场景

适用:绝大部分场景都适用

不适用:接收的字节数据间隔,大于1字节周期时长的! 如正点原子的LORA模块,硬件机制1ms传送1个字节,即115200波特率下接收一字节用90us,但后面900us左右间隔是闲置的,这类机制,不适合使用空闲中断。
在这里插入图片描述lora400T22S也不支持串口空闲中断,我需要在测试下,模块还没到

代码编写注意坑点

1. IDLE的中断清理方式.

USART的非空中断标志位, 是自动清理的, 你只要读出数据, 标志会就自动被清, 不用自己费心.
但IDLE的中断标志位, 必须通过软件序列清零, 步骤如下:

u32 temp;
temp=USART1->SR;
temp=USART1->DR;

这两句顺序还不能错, 之前没细心看手册, 调试差点爆血管. 前人不说, 撞墙也想不出来这前因后果!!

2. DMA 设置

使用DMA时, 一般会设置明确的传输数据量, 就是长度是已知道的; 而IDLE 空闲中断 , 最方便的就是接收不定长数据.
所以NDTR(传输数量)要设得比实际数量要大, 注意单位:你的字长, 如200. 大多少没关系.
中断处理时, 要重新设置DMA的NDTR. 另外: DMA是在关闭的时候才能修改!!

代码结构

USART初始化
DMA初始化(用在裸机)
中断服务函数
void USART1_IRQHandler( void )
{
  #if (USE_SYSTEMVIEW==1)
    SEGGER_SYSVIEW_RecordEnterISR();
#endif
    static u8 RXNE_CNT;
    u8 com_data;
    BaseType_t xHigherPriorityTaskWoken;
    if( USART1->SR & USART_SR_ORE )
    {
        com_data = USART1->DR;
    }
    if( USART_GetITStatus( USART1, USART_IT_RXNE ) )
    {
        USART_ClearITPendingBit( USART1, USART_IT_RXNE );
        com_data = USART1->DR;
        if( usart1CallbackFunc != 0 )
        {
            ( *usart1CallbackFunc )( com_data );
        }
        if((ReceLORA400RTCMSemaphore != NULL)&&((++RXNE_CNT)%8 == 0))
        {
          RXNE_CNT=0;
          xSemaphoreGiveFromISR( ReceLORA400RTCMSemaphore, &xHigherPriorityTaskWoken );
          portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
        }
    }
//    如果这个不能用,累加呗,八个字节进一次,
        if( USART_GetITStatus( USART1, USART_IT_IDLE ) )
    {
        //USART_ClearITPendingBit(USART6,USART_IT_IDLE);
        com_data = USART1->SR;
        com_data = USART1->DR;
        xSemaphoreGiveFromISR( ReceLORA400RTCMSemaphore, &xHigherPriorityTaskWoken );
        portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
    }
    

    #if (USE_SYSTEMVIEW==1)
    SEGGER_SYSVIEW_RecordExitISR();
#endif
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不熬夜,早点睡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值