今天用串口收发数据的时候发现第一字节的数据无法收到。
实际为第一字节收到,但是无法打印在调试助手上。
问题变成,为什么无法打印第一个字节。
这个问题以前碰到过,硬件复位的时候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);//等待发送结束
在这里已经等待了标志位发送完成,不会造成数据寄存器被覆盖的情况,求解惑?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
不管是库函数开发还是寄存去的开发,寄存器都是要了解的。
以下是《中文手册》的定义:
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
位 7 TXE:发送数据寄存器为空 (Transmit data register empty)
当 TDR 寄存器的内容已传输到移位寄存器时,该位由硬件置 1。如果 USART_CR1 寄存器
中 TXEIE 位 = 1,则会生成中断。通过对 USART_DR 寄存器执行写入操作将该位清零。
0:数据未传输到移位寄存器
1:数据传输到移位寄存器
注意:单缓冲区发送期间使用该位。
位 6 TC:发送完成 (Transmission complete)
如果已完成对包含数据的帧的发送并且 TXE 置 1,则该位由硬件置 1。如果 USART_CR1 寄存
器中 TCIE = 1,则会生成中断。该位由软件序列清零(读取 USART_SR 寄存器,然后写入
USART_DR 寄存器)。TC 位也可以通过向该位写入‘0’来清零。建议仅在多缓冲区通信
时使用此清零序列。
0:传送未完成
1:传送已完成
《《《《《《《《《《《《《《《《《《《《《《《《《《《《《
结合图片不难明白:
在发送数据的时候,只要数据从TDR寄存器发送到了移位寄存器上,TXE必定由硬件置1(TDR的值为空,可以在往里写值,准备下一字节的传输,这就是我们理解的“传输完成”),
接下来数据会自动的往TX线上发送出去,而不占内存,但是会消耗一定的时间, 在数据从移位寄存器移动到TX线的期间,往TDX写入数值,会使得TXE置0,
但是要是在这期间没有值往TDX里写,数据完全发送到TX线的同时(此时TXE=1),TC便会由硬件置1.
一周热门 更多>