串口加printf重定向一些问题,解决一半,还剩一半

2019-07-20 05:50发布

今天用串口收发数据的时候发现第一字节的数据无法收到。
实际为第一字节收到,但是无法打印在调试助手上。
问题变成,为什么无法打印第一个字节。
这个问题以前碰到过,硬件复位的时候SR的TC为置位导致无法发送第一个字节,清除即可,但是我碰到的不是这个情况。下面背景描述:
首先板B向板A串口3发 0x42 0x0d 0x0a;
板A串口3收到数据后,通过串口1发送给PC串口助手显示,这里串口助手仅能显示0d 0a。下附程序部分:
[mw_shl_code=c,true]        while(1)
        {
                if(USART_RX_STA&0x8000)
                {                                          
                        len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
                        //USART_ClearFlag(USART1,USART_FLAG_TC);   //方案1
                        for(t=0;t<len;t++)
                        {
                               
                                USART_SendData(USART1, USART_RX_BUF[t]);         //向串口1发送数据
                                while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
                        }
                        //delay_ms(1);    //方案2
                        printf(" ");//插入换行
                       
                        USART_RX_STA=0;
                }else
                {
                        times++;
                        if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行.
                        delay_ms(10);   
                }
        }[/mw_shl_code]
以下是printf的重定向输出函数:
[mw_shl_code=c,true]//重定义fputc函数
int fputc(int ch, FILE *f)
{        
        while((USART1->SR&USART_FLAG_TC)==0);//循环发送,直到发送完毕
        USART1->DR = (u8) ch;
      
//while((USART1->SR&USART_FLAG_TC)==0);//循环发送,直到发送完毕    //方案3
        return ch;
}[/mw_shl_code]

在这个情况下,接收器仅能收到上述代码中的:
printf(" ");//插入换行
串口3接收到的回车和换行没有算在数据当中,被中断函数过滤了。

三种方案解决了这个问题,
1、//USART_ClearFlag(USART1,USART_FLAG_TC);
在发送数据前清空TC位,但是每次发送都要清空
2、//delay_ms(1);   
在发送数据后延时一小会,我觉得不可取
3、//while((USART1->SR&USART_FLAG_TC)==0);//循环发送,直到发送完毕
在重定向函数fputc中将TC标志位等待放到发送数据后面

三种方案之后都可以接收到数据,但是还是不理解为什么原来的情况无法接收到数据,按理说
USART_SendData(USART1, USART_RX_BUF[t]); //向串口1发送数据
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
在这里已经等待了标志位发送完成,不会造成数据寄存器被覆盖的情况,求解惑?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
14条回答
Bigflish
1楼-- · 2019-07-20 09:20
 精彩回答 2  元偷偷看……
正点原子
2楼-- · 2019-07-20 12:21
 精彩回答 2  元偷偷看……
fghlw
3楼-- · 2019-07-20 18:05
这个问题碰到过,但忘记咋解决的了。DMA接收,缺一个字节
WengYuH
4楼-- · 2019-07-20 23:58
 精彩回答 2  元偷偷看……
WengYuH
5楼-- · 2019-07-21 05:04
Bigflish 发表于 2017-11-11 17:34
标志位错了,把你代码里的两处
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET)
全改为

换成这个确实好使,还有一点就是判断标志位的和发送数据的顺序要一致,如果使用TC标志位且判断标志位在发送数据后,需要在初始化里清楚标志位,否则复位后第一个字符发不出来。
WengYuH
6楼-- · 2019-07-21 10:59
Bigflish 发表于 2017-11-11 17:34
标志位错了,把你代码里的两处
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET)
全改为

不过我的问题还是没有解决,想知道为什么原来的不行,谁能分析一下吗?

一周热门 更多>