打印

求助:STM32串口实验出现奇怪现象

[复制链接]
1256|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
fl090726|  楼主 | 2013-10-26 11:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
各位大侠前辈,我刚刚开始学stm32,在做串口发送数据实验时出现了很奇怪的现象:
一.程序在开发板中执行时:

1).直接开发板运行,向串口发送ABCDEFGHIJKLMNOPQRST,但是串口助手显示的是BCDEFGHIJKLMNOPQRST,丢掉了第一个'A';
2).使用Jlink全速运行时,串口调试助手显示的是BCDEFGHIJKLMNOPQRST,丢掉了第一个'A',和上面一样的现象;
3).使用Jlink单步调试时,串口调试助手显示的是ABCDEFGHIJKLMNOPQRST,没有丢失数据

二.直接使用keil4仿真器时,USART1仿真的结果实ACDEFGHIJKLMNOPQRST,丢失了'B'
真是搞不明白,希望前辈们指点指点,代码如下:
int main(void)
{
float DIV;
u16 M,F,BRR;
u16 Baud;
int i;
u8 data;
RCC_Configuration();
GPIO_Configuration();
/*CR1中UE位使能,M位定义字长,TE发送使能,CR2中选择停止位        */
USART1->CR1 |=(1<<13);
USART1->CR1 &= ~(1<<12);
USART1->CR2 &=~((1<<12)|(1<<13));
USART1->CR1 |=(1<<3);                                          
/*设置波特率*/
Baud=9600;
DIV=(float)(72*1000*1000)/(Baud*16);
M=DIV;
F=(DIV-M)*16;
BRR=(M<<4)+F;
USART1->BRR=BRR;
/*发送数据    向寄存器DR写入数据ABCDEFGHIJKLMNOPQRST
*/
data='A';
for(i=0;i<20;i++)
{        
         USART1->DR=data;
         data++;
         while((USART1->SR &0x40)==0) ;        //判断是否发送完成
}
}
沙发
戈卫东| | 2013-10-27 13:16 | 只看该作者
你应该检测TXE标志,而不是TC标志. 数据刚写到DR, TC标志不会马上更新(它可能要等待UART时钟), TXE会马上更新.

使用特权

评论回复
板凳
fl090726|  楼主 | 2013-10-27 15:04 | 只看该作者
戈卫东 发表于 2013-10-27 13:16
你应该检测TXE标志,而不是TC标志. 数据刚写到DR, TC标志不会马上更新(它可能要等待UART时钟), TXE会马上更 ...

恩恩 按照你说的我试了下,数据不丢失了,但是为什么使用TC位就会丢失呢,TC不是数据发送完成标志位吗?能帮细细讲解下吗

使用特权

评论回复
地板
lhchen922| | 2013-10-27 17:30 | 只看该作者
看数据手册,上面有说。  下面是香版的博客说的。
http://bbs.**/BLOG_ARTICLE_183997.HTM
在USART的发送端有2个寄存器,一个是程序可以看到的USART_DR寄存器(下图中阴影部分的TDR),另一个是程序看不到的移位寄存器(下图中阴影部分Transmit Shift Register)。

对应USART数据发送有两个标志,一个是TXE=发送数据寄存器空,另一个是TC=发送结束;对照下图,当TDR中的数据传送到移位寄存器后,TXE被设置,此时移位寄存器开始向TX信号线按位传输数据,但因为TDR已经变空,程序可以把下一个要发送的字节(操作USART_DR)写入TDR中,而不必等到移位寄存器中所有位发送结束,所有位发送结束时(送出停止位后)硬件会设置TC标志。

另一方面,在刚刚初始化好USART还没有发送任何数据时,也会有TXE标志,因为这时发送数据寄存器是空的。

TXEIE和TCIE的意义很简单,TXEIE允许在TXE标志为'1'时产生中断,而TCIE允许在TC标志为'1'时产生中断。

至于什么时候使用哪个标志,需要根据你的需要自己决定。但我认为TXE允许程序有更充裕的时间填写TDR寄存器,保证发送的数据流不间断。TC可以让程序知道发送结束的确切时间,有利于程序控制外部数据流的时序。

使用特权

评论回复
5
戈卫东| | 2013-10-28 00:58 | 只看该作者
ST的USER-MANUAL说了,TC标志需要读SR然后写DR才会清除,你的第一个字节写之后,TC不会清除,然后读了SR,第二次写DR的时候,才清除了TC.

使用特权

评论回复
6
戈卫东| | 2013-10-28 00:59 | 只看该作者
TXE则要简单些,写DR就会清除它.

使用特权

评论回复
7
香水城| | 2013-10-28 14:38 | 只看该作者
本帖最后由 香水城 于 2013-10-28 14:54 编辑

2楼正解。

另外,既然LZ是刚开始接触STM32,建议还是从官方例程库开始,它对每个外设都有若干例程参考。运行正确了,再在其上修改,增加自己的应用要求。

使用特权

评论回复
8
fl090726|  楼主 | 2013-10-28 17:03 | 只看该作者
戈卫东 发表于 2013-10-28 00:59
TXE则要简单些,写DR就会清除它.

恩谢谢啦,我在看看

使用特权

评论回复
9
fl090726|  楼主 | 2013-10-28 17:04 | 只看该作者
香水城 发表于 2013-10-28 14:38
2楼正解。

另外,既然LZ是刚开始接触STM32,建议还是从官方例程库开始,它对每个外设都有若干例程参考。运 ...

恩恩 谢谢香版主

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

55

帖子

1

粉丝