3回答

0收藏

【魔方团】解决串口波特率的诡异问题--F407官方库初探

#竞赛 #竞赛 4588 人阅读 | 3 人回复 | 2013-08-13

本帖最后由 CoreCode 于 2013-8-13 18:15 编辑

收到了F407之后,第一步就是调串口~
跑了跑官方例程没问题,使用自己从官网下载的库,配置完了,写个串口程序发现串口是乱码。
既然是乱码第一点就想到了是波特率的问题,但是库函数配置的确实是115200,与例程一样,甚至把例程的代码拷贝过来还是不行。
那么问题在哪里,最终发现一个惊人的问题!!!
追踪USART_Init函数看看波特率的寄存器到底是怎么得出的。
  1. /*---------------------------- USART BRR Configuration -----------------------*/
  2.   /* Configure the USART Baud Rate */
  3.   RCC_GetClocksFreq(&RCC_ClocksStatus);

  4.   if ((USARTx == USART1) || (USARTx == USART6))
  5.   {
  6.     apbclock = RCC_ClocksStatus.PCLK2_Frequency;
  7.   }
  8.   else
  9.   {
  10.     apbclock = RCC_ClocksStatus.PCLK1_Frequency;
  11.   }
  12.   
复制代码
这是个中间步骤,但是很显然他跟系统的时钟有关系,那么串口乱码跟系统时钟设置不正确有很大关系!
stm32库中关于时钟设置在文件system_stm32f4xx.c中,我发现
  1.     * 4. The default value of HSE crystal is set to 25MHz, refer to "HSE_VALUE" define
  2.   *    in "stm32f4xx.h" file. When HSE is used as system clock source, directly or
  3.   *    through PLL, and you are using different crystal you have to adapt the HSE
  4.   *    value to your own configuration.
复制代码
很显然discovery上的晶振是8M的,所以我就瞎了。。。
再到stm32f4xx.h中一看,果然我想的是对的
  1. #if !defined  (HSE_VALUE)
  2.   #define HSE_VALUE    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
  3. #endif /* HSE_VALUE */
复制代码
所以把define HSE_VALUE    ((uint32_t)25000000)改为define HSE_VALUE    ((uint32_t)8000000)
还有
system_stm32f4xx.c中
  1. /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
  2. #define PLL_M      25
  3. #define PLL_N      336
复制代码
#define PLL_M      25
改为
#define PLL_M 8
这个大家都明白吧
一样的原因,于是串口正常!
调用库函数查看各总线频率也是正常的。

最后中国动画片标准结局
这个故事告诉我们,官方的资料不是拿来就能用的。

很多同学自己移植工程不好用很可能就死这个原因~(那两个文件是只读的,修改之前别忘了修改属性,改完了最好也把只读加上去)

对于这几个文件 其中还有很多有意思的东西, 包括让系统从外部地址启动的内容很值得研究一下。

最后补充一下 这是f1的资料但是名称都是一样的,这回就栽在HSE上了。。。
①、HSI是高速内部时钟,RC振荡器,频率为8MHz。
②、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。
③、LSI是低速内部时钟,RC振荡器,频率为40kHz。
④、LSE是低速外部时钟,接频率为32.768kHz的石英晶体。
⑤、PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍。
分享到:
回复

使用道具 举报

回答|共 3 个

倒序浏览

沙发

詠筠

发表于 2013-8-13 18:18:36 | 只看该作者

支持一下,感谢分享
板凳

853728579

发表于 2013-8-13 21:13:53 | 只看该作者

这得看你外部晶振是多大的,如果是25MHZ那么那里就改成25,如果接的是8MHZ那么就改成8,  这个文件本来就是用来改的,你没看到官方没有把这个文件设置为只读。(这个.c文件可改,其他.c文件不可改)。这个不是官方库的原因·············
地板

corecode

发表于 2013-8-13 21:43:20 | 只看该作者

本帖最后由 CoreCode 于 2013-8-13 21:46 编辑
853728579 发表于 2013-8-13 21:13
这得看你外部晶振是多大的,如果是25MHZ那么那里就改成25,如果接的是8MHZ那么就改成8,  这个文件本来就是 ...

是啊,没注意到这点所以吃亏了。很多移植教程里都没提到这点,现在有了那个自动生成工具,这个问题应该不会再有了。
而且那个.h文件,貌似应该可以在preprocessor symbol里define 但是怎么预定义一个带数的 不知道怎么弄就像
#define value 3000
这样的

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条