解决问题
正在开发一个双脉冲发生器,主控MCU用到了STM32F103RBT6,写入程序后发现原本设置的1000ms的延时不起作用,没有任何响应,起初还以为式程序卡死了,在代码上检查了一会儿,并没有发现明显的错误,抱着试试的想法把1000ms的延时改成了100ms,发现有相应的现象了,但是LED闪烁的频率明显是对应着1000ms延时。
浏览器查找相关资料,看到正点原子的论坛里也有人遇到同类的问题,这下就放心了哈哈,不是我第一个遇到就好,论坛中给出的解释是外部时钟没有正常启用,导致MCU使用内部时钟。仔细分析就是:外部时钟是8MHz,经过9倍频后给到处理器,也就是72MHz,这也是我所需要的时钟频率,但是外部时钟源有问题,所以处理器只好使用内部的8MHz时钟,也就是慢了9倍,给人一种慢了“10倍”的感觉。并且之前出现的延时不起作用一事也有了合理的解释,那就是延时1000ms实际上是延时了9s,在短时间内没有响应,让人误以为程序没有运行。
至此,基本可以断定是硬件BUG,即外部时钟电路有问题。翻开原理图看一眼就发现了问题,电容用的是100nF,电阻是1kΩ,难怪外部时钟不太行,将电容替换为22pF,电阻替换为1MΩ,上电一看,解决!
外部时钟电路
为什么要使用外部时钟
一般STM32的时钟源有两种主时钟方案,一个是依靠内部RC振荡器的HSI(内部高速时钟),另一个是HSE(外部高速时钟)。内部高速时钟源HSI,英文全称:HIGH-SPEED INTERNAL OSCILLATOR。一般情况下,内部HSI都会在ST出厂时已校准,但是精度不高,在0到70℃下误差范围可能达到-1.3%到2%,即便是在标准的25℃下,也有 -1.1%到1.8% 的误差(如下图)
因此,对于高波特率的异步串口通讯,或者需要高精度定时的场合,用HSI就有隐患,甚至根本达不到设计要求。因此要使用外部高速时钟源(HSE),英文全称:HIGH-SPEED EXTERNAL OSCILLATOR。
为了获取更高的时钟精度,我们就要用到由石英晶振提供的HSE作为主时钟源,这样就可以很容易达到±30ppm(工作温度区间:-40 °C to +85 °C)。
在构成时钟电路时,需要把外接电容(C1、C2)与无源贴片晶振8MHz的负载电容CL进行匹配:
一般取C1 = C2,这两个电容和晶体Q构成三点式电容振荡器。以选择8MHz晶振负载电容CL=20PF为例:
PCB杂散电容CS一般可以估值4pF到6pF,
由于我们取了C1 = C2,公式就可以变为:C1 = C2 = 2 * (CL – Cs)
代入公式:
若Cs =6Pf,则C1=28PF;
若Cs =4Pf,则C1=32PF
因此,为了保险起见,理论上我们一般外接电容(C1=C2)取值在 27PF ~33PF之间。
最后需要指出的是,因PCB设计及复杂性差异,杂散电容CS也会存在差异,所以调整外接电容值的大小应该以晶振实际输出频率为准。
外部晶振起振
至于晶振如何起振,找到一篇文章,暂时还没有时间看……
面包板社区:晶振是如何起振的