- 1、STM32F103VBT6使用16M晶振、12M晶振和8M晶振RCC设置有何不同?
原来使用8M晶振,设置如下,通讯发送数据正常。
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);//PLL的输入时钟= HSE时钟频率; PLLCLK = 8MHz * 9 = 72MHz 9倍频
现在改成16M的晶振,设置改成下面,通讯发送数据不正常。
RCC_PLLConfig(RCC_PLLSource_HSE_Div2,RCC_PLLMul_9);//PLL的输入时钟= HSE时钟频率; PLLCLK = 16MHz / 2 * 9 = 72MHz 9倍频
经分析发现,除了上面的修改外,还要在STM32F1x_conf.h中修改如下:
#define HSE_Value ((u32)16000000)
系统正常!
在外接为12Mhz晶振时就需要进行如下设置:
//在RCC_Config()中修改:
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_6);//PLL的输入时钟= HSE时钟频率; PLLCLK = 12MHz * 6 = 72MHz 9倍频
//在stm32f10x.h 中修改:
#define HSE_Value ((u32)12000000)
修改HSE_Value的值为12M之后,串口通信数据正常了,但在MDK中显示的OCS总是8M这是什么原因呢?
在Options for target下的 target 中的Xtal 栏中可以设置晶振为11.0592M,
在Options for target下的 target 中的Xtal 栏中可以设置晶振为11.0592M后,只是调试时keil会在PRCC这个界面中显示正确的各个时钟。
- 2、STM32超频测试
用的是STM32F103C6,修改倍频系数为12,即96MHz的时钟。
//设置PLL时钟源及倍频系数
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_12);
将程序通过仿真灌入,运行几分钟,一模芯片,没什么感觉。
再来,修改倍频系数,104MHz = 8*13的时钟
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_13);
将程序通过仿真器灌入,运行也正常。
来个最高的,修改倍频系数为16,128MHz的时钟
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_16);
将程序通过仿真器灌入,运行也正常,1602LCD显示一切正常,芯片温度没有明显升温。
芯片上装的外部晶振是标准的8MHz,因此能上的最高频率是8*16 = 128MHz,如果要试更改的频率只能更换更高频的晶振了。
看来STM32的超频性能是不错的,但建议大家不要在正式产品中超频使用。
- 3、STM32的32.768K晶振选型必须要小心
STM32的32.768K晶振,必须要小心啊!
这个是很挑剔的,千万记得要使用6pf负载电容的晶振。
- 4、STM32的系统时钟SysTick
系统时钟SysTick
(一)背景介绍
在传统的嵌入式系统软件中通常实现Delay(N)函数 的方法为:
for(i=0;i<=x;i++);
x-----对应N毫秒的循环值。
对于STM32系列微处理器来说,执行一条指令只有几十个ns,进行for循环时,要实现N毫秒的x值非常大,而且由于系统频率的宽广,很难计算出延时N毫秒的精确值,针对STM32微处理器,需要重新设计一个新的方法去实现该功能,以实现在程序中使用Delay(N)。
(二)STM32 SysTick介绍
Cortex-M3的内核中包含一个SysTick时钟,SysTick为一个24位递减计数器,SysTick设定初值并是使能后,每经过1个系统时钟周期,计数值就减1,计数到0时,SysTick计数器自动重装初始值并继续计数,同时内部的COUNTFLAG标志置位,触发中断(如果中断使能情况下)、
在STM32的应用中,使用Cortex-M3内核的SysTick作为定时时钟,设定每一毫秒产生一个中断处理函数里对N减一,在Delay(N)函数中循环检测N师范为0,不为0则进行循环等待,若为0则关闭SysTick时钟,退出函数。
注:全局变量TimingDelay,必须定义为volatile类型,颜色时间将不随系统时钟改变。
(三)STM32 SysTick库文件。
使用ST的函数库SysTick的方法:
1、调用SysTick_CounterCmd()-----失能SysTick计数器。
2、调用SysTick_ITConfig()----失能SysTick中断
3、调用SysTick_CLKSourceConfig()----设置SysTick时钟源。
4、调用SysTick_SetReload()-----设置SysTick重装载值。
5、调用SysTick_ITConfig() ---使能SysTick中断。
6、调用SysTick_CounterCmd()---开启SysTick计数器
(四)SysTenTick工程实战
外部晶振为8MHz,9倍频,系统时钟为72MHz,SysTick的最高频率为9MHz(最大为HCLK/8)在这个条件下,把SysTick校验值设置成9000,将SysTick时钟设置为9MHz,就能够产生1ms的时间基值,即SysTick产生1ms的中断。
RCC_Configuration();
第一步:配置RCC寄存器和SysTick寄存器。
RCC_Configuration:配置RCC寄存器
void RCC_Config(void)
{
ErrorStatus HSEStartUpStatus;
RCC_DeInit(); /* 将外设RCC 寄存器重设为缺省值 */
RCC_HSEConfig(RCC_HSE_ON); /* 设置外部高速晶振 HSE晶振打开 ON*/
HSEStartUpStatus = RCC_WaitForHSEStartUp(); /* 等待HSE起振 */
if(HSEStartUpStatus == SUCCESS) //SUCCESS : HSE晶振稳定且就绪
{
/* 设置 AHB 时钟(HCLK)*/
RCC_HCLKConfig(RCC_SYSCLK_Div1); /* AHB时钟 = 系统时钟 */
/* 设置高速AHB时钟(PCLK2) 注:AHB主要负责外部存储器时钟。APB2负责AD,I/O,高级TIM,串口1*/
RCC_PCLK2Config(RCC_HCLK_Div8); //PCLK2(APB2时钟) = HCLK/8 = 系统时钟/8 = 72MHz / 8 = 9MHz
/* 设置低速AHB时钟(PCLK1) 注:APB1负责DA,USB,SPI,I2C,CAN,串口2345,普通TIM */
RCC_PCLK1Config(RCC_HCLK_Div8); //PCLK1(APB1时钟) = HCLK/8 = 系统时钟/8 = 72MHz / 8 = 9MHz
FLASH_SetLatency(FLASH_Latency_2); /* Flash 2 wait state */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);/* Enable Prefetch Buffer */
/* 设置PLL 时钟源及倍频系数 */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);//PLL的输入时钟= HSE时钟频率; PLLCLK = 8MHz * 9 = 72MHz 9倍频
RCC_PLLCmd(ENABLE); /* Enable PLL */
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)/* 检测指定的RCC标志位(PLL准备好标志)设置与否 */
{
}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); /* 设置系统时钟(SYSCLK) 选择PLL作为系统时钟*/
while(RCC_GetSYSCLKSource() != 0x08) /* PLL返回用作系统时钟的时钟源 */
{
}
}
}
- 5、对于STM32配置时钟的总结
一共有4种时钟,
一、HSE振荡器时钟(外部8M时钟),HSE振荡器时钟就是外部注意时钟,8M晶振
二、HSI振荡器时钟(内部8M时钟),HSI时钟信号由内部8MHz的RC振荡器产生,可直接作为系统时钟或在2分频后作为PLL输入,是没有晶振时候使用内部时钟精度很差,内部PLL可以用来倍频HSI RC的输出时钟或HSE晶体输出时钟。
三、LSE时钟(外部32.768KHz时钟),LSE晶体是一个32.768Khz的低速外部晶体或陶瓷谐振器,
四、LSI时钟(内部40KHz时钟),LSI RC担当一个低功耗时钟源的角色,它可以在停机或待机模式下保持运行,为独立看门狗和自动唤醒单元提供时钟。
AHB预分频器配置高速APB(APB2)和低速APB(APB1)域的频率。总体来说时钟配置流程如下:
首先将HSE外部时钟除以2,然后使用PLL开始倍频。
设置主系统时间为倍频的n/1,一般直接设置为72MHz,然后使用AHB将系统时钟变成各个端口可以使用的速度。
子流程如下:
①、打开晶振
②、等待起振
③、设置代码延时为2
④、AHB时钟=系统时钟
⑤、设置高速AHB(APB2)时钟为72MHz / 8 = 9MHz,(如果APB1/APB2预分频系数=1,则频率不变,否则频率 *2 输出至TIMXCLK)
⑥、设置低速AHB(APB1)时钟为72MHz/8 = 9Mhz
⑦、设置PLL时钟源及倍频系数使主频为72M
⑧、设置使能或者失能APB2外设时钟的IO。
- 6、STM32是否可以用内部晶振40K外加8M晶振的方式?
从手册上看的话应该可以用内部晶振40K加外部8M晶振的组合方式?这样的时候USB通信不会有什么问题吧?
一、STM32没有内部晶振,内部只有两个阻容振荡器,8MHz的HSI和40KHz的LSI。
二、如果不使用独立看门狗和内部RTC,不必使用外部32Khz晶振(LSE),也不必使用内部LSI(40KHz的阻容振荡器);
三、如需要使用LSI,只需要使能LSI即可。
四、不管使用LSE或LSI与否都不会对USB通信有任何影响。只要一个8MHz的外部晶振就可以让整个系统动作起来并能够进行USB通信。
USB通信与低频振荡器(LSI或LSE)无关、
不使用IWDG时,可以使用WWDG作为程序运行监视。
- 7、STM32内部晶振的用法
在STM32上如果不使用外部晶振,OSC_IN和OSC_OUT的接法:
如果使用内部RC振荡器而不使用外部晶振,请按照县方法处理:
1)、对于100脚或者144脚的产品,OSC_IN应接地,OSC_OUT应悬空。
2)、对于少于100脚的产品,有2中接法:
2.1)、OSC_IN和OSC_OUT分明通过10K电阻接地,此方法可提高EMC性能;
2.2)、分别重映射OSC_IN和OSC_OUT至PD0和PD1,再配置PD0和PD1为推挽输出并输出“0”。此方法可以减少功耗。
首先要明确的是STM32没有内部晶振,HSI是内部RC振荡器。
HSI内部8MHz的RC振荡器的误差在1%左右。
内部RC振荡器的精度通常比用HSE(外部晶振)要差上十倍以上。
没有所谓优缺点,最重要的是根据应用场合,对时钟要求不高时也是可以用HSI的,要注意的是当使用HSI时,最高系统时钟的频率是达不到72MHz的。
STM32的ISP就是用(HSI)内部RC振荡器。
- 8、STM32芯片外部时钟能用外部有源晶振吗?
外部时钟源(HSE旁路)在这个模式里,必须提供外部时钟,它的频率最高可达25MHz,用户可通过设置在时钟控制寄存器中的HSEBYP和HSEON位来选择这一模式,外部时钟信号(50%占空比的方波、正玄波或三角波)必须连接到SOC_IN引脚,同时保证OSC_OUT引脚悬空。
HSEBYP=0 无旁路, = 1 被旁路。
只有在外部4~25M振荡器被关闭时才能写入该位!