专注电子技术学习与研究
当前位置:单片机教程网 >> STM32 >> 浏览文章

STM32F107VCT6开发板学习问题笔记

作者:佚名   来源:本站原创   点击数:  更新时间:2014年08月18日   【字体:

1:使用开发板的USART作为UART通信,在前调用BSP_Init()函数初始化开发板,串口上传输的数据出错:'a'变成0xfa或0xfe;

   【在这个问题解决之后,回头总结下,在解决问题时:1.预计有可能造成出错的原因(这个可能需要一些经验,但是思维方式需要这样的猜测,从系统内外,可以先罗列出尽可能有的原因,后面再一一排除) 2.尽可能的定位出错的地方(比如这里通过在线调试,确定在修改时钟后,可以解决数据发送的不正确) 3.推测并排除次因,找出主因,往深一步探测 】
   1:猜测原因。   外因:串口接收的过程受干扰
                  内因:A.端口设置有问题 B.USART的波特率设置有问题
   2:定位错误  
     在刚开始时通过屏蔽BSP_Init()发现功能正常,再具体定位到BSP_Init()里面的SYSCLK_Frequency时钟设置,发现例程中默认的是72M,但是改为36M,就没有问题,应该是时钟方面的设置问题,具体的问题做何解析?
   3:推测排除,深究
     外因内因很好排除,数据既然在波特率低时能正常通信,可能不是端口设置的问题,应该是波特率的问题,常看用户手册该节的资料: 
注: 1.  CPU 的时钟频率越低,则某一特定波特率的误差也越低。可以达到的波特率上限可以由这组数据得到。 
     2.  只有USART1 使用PCLK2(最高72MHz)。其它USART使用PCLK1(最高36MHz)。
     USART的波特率的计算公式:
       USARTDIV是一个无符号的定点数。这12位的值设置在USART_BRR寄存器。那么USARTDIV与USART_BRR的关系又是怎么样的?
      加入USARTDIV = 27.75;那么 USART_BRR = 0x1B(27) + 0XC(0.75 * 16) = 0X1BC;同理可以从USART_BRR 推出USARTDIV的值;
     假设fck = 36000000; Tx=115200; =>USARTDIV = 19.53125;所以0x13 + (0.53125 * 16 = 8.5) =>0x13 + 0x9 = 0x139; 所以实际上是0x139产生的波特率:115015.97(误差率为 0.15%);
===》理论最大波特率:36000000 / (16 * 1.0) = 2.25M(USARTDIV最小为1.0)
   继续往下查,对于SYSCLK_Frequency最高72M,运行应该没有问题,但是目前有问题;顺藤摸瓜,查看各个时钟控制器,发现时钟设置路径: HSE-->PREDIV2-->PLL2-->PREDIV1-->PLL-->SYSCLK;
发现其中有问题:HSE(25M),PREDIV2(源代码设置是2分频),PLL2(8倍频),PREDIV1(9倍频),SYSCLK是算不出72M的,这时72M的算法其实已经超过72M,所以给USART2时,波特率计算时会出现问题;将PREDIV2(改为5分频就对了);
   这就是为什么调用BSP_Init()或者SystemInit会出问题,他们都调用SetSysClock(),再调用SetSysClockTo72()【宏定义72M】,同时将系统时钟改为36M时不会出问题,因为此时调用的不是出问题的SetSysClockTo72(),而在之前用的是出错的SetSysClockTo72()却没有发现问题,是因为系统时钟虽没有在预设值,但是系统还足以正常工作,但是一旦添加串口,波特率设置就会有很大的偏差,数据传输就出错。
    1:参考代码其实里面是有很多问题的
    2:我们应该尽可能的多阅读参考代码,利用其中的资源,避免重复造轮子。
                           
2:用串口终端软件显示字符串,连续发送几个字符串时,“xxxx\n”,包含了换行转义字符,但是就是不会换行?
   通过调试,发现在存储空间,转义字符‘\n’是正确的0x0a,
   USART_SendString(USART2,Menu[0]);
   USART_SendString(USART2,Menu[1]);
   USART_SendString(USART2,Menu[2]);
   USART_SendString(USART2,Menu[3]);

    但是不连续发送就不会出现这种现象,或者一句句调试打印也不会出现不换行的现象,断定是连续发送的时间间隔太短,软件还没来得及换行,就又重新显示新数据,那么就在USART_SendString的尾部加了延时,就解决问题了。

关闭窗口

相关文章