打印
[STM32F0]

F0C8的usart用外部时钟24MHz

[复制链接]
1165|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tgwfcc|  楼主 | 2015-8-6 10:25 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 tgwfcc 于 2015-8-6 10:44 编辑

最近用F0C8的单片机做个项目,其中用到USART1和USART2,USART的TX、RX是通过USB转串口工具接到电脑的。
在刚开始调串口的时候,遇到USART2不通,USART1通的情况,后来不知怎么USART2又可以了,所以也没在意。
现在用了一段时间,发现USART1、2用外部时钟24M,倍频到48M,不通了;用内部8M倍频到48M是可以的。
用IO拉高拉低延时1ms,产生方波,用示波器量波形是对的,所以判断晶振是起振的。
单步调试看了一下USART的TDR寄存器的值,发现在用外部晶振的时候,TDR的值是对的,感觉是从TDR寄存器发送出来的数据被改变了,不知道怎么分析了,求高人指点,谢谢!


这两个波形一个是左边是内部的,右边是外部的,波形不一样,示波器的时间间隔都是400us。


沙发
mmuuss586| | 2015-8-6 12:36 | 只看该作者
是用外部时钟,你程序确定倍频到48M了吗?

使用特权

评论回复
板凳
songchenping| | 2015-8-6 13:01 | 只看该作者
说的对,你可以量一下时钟信号啊。或者通过其他方式测一下

使用特权

评论回复
地板
tgwfcc|  楼主 | 2015-8-6 13:36 | 只看该作者
mmuuss586 发表于 2015-8-6 12:36
是用外部时钟,你程序确定倍频到48M了吗?

是啊,IO拉高拉低,用滴答定时器延时,1ms是1ms的,

使用特权

评论回复
5
songchenping| | 2015-8-6 14:56 | 只看该作者
tgwfcc 发表于 2015-8-6 13:36
是啊,IO拉高拉低,用滴答定时器延时,1ms是1ms的,

这个和主频是多少没有一点关系的。

使用特权

评论回复
6
tgwfcc|  楼主 | 2015-8-6 15:48 | 只看该作者
songchenping 发表于 2015-8-6 14:56
这个和主频是多少没有一点关系的。

滴答的时钟是系统时钟除以8,怎么和主频没关系呢?

使用特权

评论回复
7
songchenping| | 2015-8-6 16:11 | 只看该作者
我说的是1ms 是1ms和主频没直接关系的。

使用特权

评论回复
8
songchenping| | 2015-8-6 16:12 | 只看该作者
你得通过其他方式来检测

使用特权

评论回复
9
tgwfcc|  楼主 | 2015-8-6 17:59 | 只看该作者
songchenping 发表于 2015-8-6 16:12
你得通过其他方式来检测

我用MCO管脚,测量输出的电平,系统是48M,外部的是24M,可以确定

使用特权

评论回复
10
tgwfcc|  楼主 | 2015-8-7 19:11 | 只看该作者
今天有看了下,单步调试、看寄存器值,最后发现问题出在波特率的设置上。1、USART的初始化是用的库函数,固件库版本是V1.5的,波特率设置为9600,根据波特率的计算公式:
可以算出USARTDIV的值为0x1388,单步调试时查看USART->BRR的值为0x8B,相差甚远。
2、然后在进到串口初始化的函数, ,发现BRR寄存器值的计算这个地方,有个“RCC_GetClocksFreq(&RCC_ClocksStatus);”这个函数,这个函数“If SYSCLK source is PLL, function returns constant HSE_VALUE(**)
  *             or HSI_VALUE(*) multiplied by the PLL factors.”,我用的是PLL时钟作为系统时钟,应该是返回系统时钟48M才对,实际上这个值只有16M。
如果按16M来算,波特率在28000左右,把波特率改成28000,收到的数据就是对的。
3、在USART初始化后,我在单独写BRR寄存器,USART1->BRR = (uint16_t)(0x1388);这样电脑接收到的数据也是对的。
4、之前用示波器量过MCO输出的时钟频率,把内部时钟关掉的话呢,输出的时钟也是对的,可以确定系统时钟是48M,正确的。
现在想不明白的就是为什么那个时钟不对呢?

uart.zip

2.54 KB

使用特权

评论回复
11
tgwfcc|  楼主 | 2015-8-7 21:30 | 只看该作者
找到问题了,串口初始化时,时钟频率调用了一个获取外设时钟的一个函数,默认的是8M,实际上用的是24M,不一致,用外部时钟时,函数获取到的一直是16M,见帖子 https://bbs.21ic.com/icview-291357-1-1.html

使用特权

评论回复
12
309030106| | 2015-8-8 17:01 | 只看该作者
没明白,是不是说得将时钟设置成16M的

使用特权

评论回复
13
Thor9| | 2015-8-9 10:34 | 只看该作者
固件库在计算波特率的时候会调用一个获到外设时钟的一个函数, 在这个获到外设时钟的函数里也是通过计算得到外设时钟值的

使用特权

评论回复
14
tgwfcc|  楼主 | 2015-8-9 11:57 | 只看该作者
309030106 发表于 2015-8-8 17:01
没明白,是不是说得将时钟设置成16M的

这个很好明白啊,如果你的外部时钟用的多少M,就要把那个HSE_VALUE的值设置成你的外部时钟的频率。
这个值和你使用的外部时钟要一致。

使用特权

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

本版积分规则

34

主题

260

帖子

4

粉丝