STM32 串口接收 检测到溢出错误 无法清标志

一、问题背景
单片机 重定向c库函数printf到串口 方便了很多调试工作! 但今天要用到一个重定向c库函数scanf到串口,于是就用了下面函数。开始用的也挺好!但遇到特殊场合就很难用,还有各种问题!发现百度也说了scanf 函数 的一些问题! 折腾了很久决定放弃!自己编写接收函数!
scanf 问题:scanf函数 点击链接…

/**
 *******************************************************************************
 * @brief   重定向c库函数scanf到串口
 * @param   
 * @return  
 * @note    
 *******************************************************************************
 */
int fgetc(FILE *stream)
{
	while( !(UART8->ISR & (1 << 5)) ); //等待数据接收完成
	return UART8->RDR;
}

二、问题发现 清 溢出错误标志 错误方式
自己编写的串口接收函数 发现 死在里面出不去,发现是 检测到溢出错误标志 无法清除!

UART8->ISR &= ~(1<<3) //清ORE位. 实际无法清除

三、问题解决方法清 溢出错误标志 正确方式

UART8->ICR |= 1<<3; //清除溢出错误,否则可能会卡死. 向此位写入“1”时, ISR 寄存器中的 ORE 标志将清零.

在这里插入图片描述

四、解决问题后的代码实例串口 接收函数 替代 scanf函数
方法一:

/**
 *******************************************************************************
 * @brief   串口扫描接收 函数
 * @param   [in] char *pdata    - 字符串 缓存 地址
 * @param   [in] u32 maxSize    - 允许接收的最大字节数
 * @return  实际接收的字节数
 * @note    0x0D0A 结束符
 *******************************************************************************
 */
u32 UartScanRx(char *pdata, u32 maxSize)
{
    u8 rxOK;
    u8 rxData;
    u32 rxCnt = 0;
    do
    {
        rxOK = 0;
        if(rxCnt >= maxSize) rxCnt = 0; //超出最大接收缓存
        if(UART8->ISR & (1<<3)) rxCnt = 0; //ORE==1,上溢错误
        
        if( UART8->ISR & (1 << 5) ) //RXNE==1,读取数据寄存器不为空。表示接收到数据
        {
            rxData = UART8->RDR; //读取DR,同时也清了ISR中的标志。
            pdata[rxCnt++] = rxData; //接收到的字符存起来
            
            if(rxData == 0x0A) //0x0D0A 结束符判断
            {
                if(rxCnt >= 2)
                {
                    if(pdata[rxCnt-2] == 0x0D) rxOK = 1;
                }
            }
        }
        UART8->ICR|=1<<3; //清除溢出错误,否则可能会卡死. 向此位写入“1”时, ISR 寄存器中的 ORE 标志将清零.
    }while( !rxOK );
    
    return rxCnt-2;
}

方法二: 比 方法一 更灵活, 接收 结束标志 自由定义

/**
 *******************************************************************************
 * @brief   串口扫描接收 函数
 * @param   [in] u16 endFlg     - 接收结束标志(注意大小端,低字节先收,高字节在后收到)
 * @param   [in] char *pdata    - 字符串 缓存 地址
 * @param   [in] u32 maxSize    - 允许接收的最大字节数
 * @return  实际接收的字节数
 * @note    
 *******************************************************************************
 */
u32 UartScanRx(u16 endFlg, char *pdata, u32 maxSize)
{
    u8 rxEnd = 0;
    u32 rxCnt = 0;
    do
    {
        if(rxCnt >= maxSize) rxCnt = 0; //超出最大接收缓存
        if(UART8->ISR & (1<<3)) rxCnt = 0; //ORE==1,上溢错误
        
        if(UART8->ISR & (1<<5)) //RXNE==1,读取数据寄存器不为空。表示接收到数据
        {
            u8 rxData = UART8->RDR; //读取DR,同时也清了ISR中的标志。
            pdata[rxCnt++] = rxData; //接收到的字符存起来
            
            if(rxCnt >= 2)
            {
                if(*(u16 *)&pdata[rxCnt-2] == endFlg) rxEnd = 1; //结束判断
            }
        }
        UART8->ICR |= 1<<3; //清除溢出错误,否则可能会卡死. 向此位写入“1”时, ISR 寄存器中的 ORE 标志将清零.
    }while(rxEnd);
    
    return rxCnt-2;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值