完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
最近要使用STM32F4芯片做开发,根据自己的编程习惯,做一些学习记录,以便于自己以后查阅。我们在设计电路的时候,一般都会设计MCU使用外部晶振,笔者工作中曾经遇到外部晶振故障芯片无法正常启动问题(无内部晶振老的MCU),使用示波器发现的,在更换了外部晶振以后,问题就解决了。由此笔者想到,STM32F4系列自带内部晶振,在外部晶振故障的时候完全可以使用内部晶振,确保软件能够正常工作。因为F4外部晶振通常使用168Mhz,而内部晶振默认并不是168Mhz,参考了网上一些资料,查阅了芯片手册,设计了一个软件保护,当外部晶振故障的时候,自动使用内部晶振锁定为168Mhz。
STM32官方巡回演讲里面介绍说内部晶振现在已经能够可靠使用了,我决定实测一下,结果发现这个说法不太准确。使用系统滴答定时器中断里普通IO用100HZ方波间接测量,示波器实测使用外部晶振100HZ很稳定,使用内部晶振在100--103HZ跳动,所以最新官方演讲说内部晶振稳定性很好可以直接使用这个说法有待商酌。 具体实现思路如下,编写外部晶振软件设定函数,编写内部晶振软件设定函数,在时钟安全中断里做好时钟切换工作。代码如下 void NMI_Handler(void) { if(RCC_GetITStatus(RCC_IT_CSS)!= RESET) { HSI_SetSysClock(); //外部晶振故障时启用内部晶振 RCC_ClearITPendingBit(RCC_IT_CSS); //清除时钟安全系统中断的挂起位 } } / * *使用HSI时,设置系统时钟的步骤 * 1,开启HSI,并等待HSI稳定 * 2,设置AHB,APB2,APB1的预分频因子 * 3,设置PLL的时钟来源 *设置VCO输入时钟分频因子m *设置VCO输出时钟倍频因子 *设置SYSCLK时钟分频因子p *设置OTG FS,SDIO,RNG时钟分频因子q * 4,开启PLL,并等待PLL稳定 * 5,把PLLCK切换为系统时钟SYSCLK * 6,读取时钟切换状态位,确保PLLCLK被选为系统时钟 * / void HSI_SetSysClock(void) { __IO uint32_t HSIStartUpStatus = 0; RCC_DeInit(); //复位RCC寄存器 RCC_HSEConfig(RCC_HSE_OFF); //关闭外部晶振(HSE) RCC_HSICmd(ENABLE); //使能HSI,HSI = 16M while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY)== RESET); //等待使能HSI成功 //调压器电压输出级别配置为1,以便在器件为最大频率 //工作时使性能和功耗实现平衡 RCC-> APB1ENR | = RCC_APB1ENR_PWREN; PWR-> CR | = PWR_CR_VOS; RCC_HCLKConfig(RCC_SYSCLK_Div1); //设置ABH时钟HCLK =系统时钟HCLK = SYSCLK RCC_PCLK2Config(RCC_HCLK_Div2); //设置高速APB时钟PCLK2 =系统时钟2分频PCLK2 = SYSCLK / 2 RCC_PCLK1Config(RCC_HCLK_Div4); //设置低速APB时钟PCLK1 =系统时钟4分频PCLK = SYSCLK / 4 //默认VCO输入频率=外部晶振频率/外部晶振频率= 1Mhz,所以PLLM =频率,注意的是2 <= PLLM <= 63 //默认VCO输出频率= VCO输入频率* PLLN,并且192 <= PLLN <= 432,默认设置PLLN = 336,正好使VCO输出频率两分频后为168Mhz //默认PLL输出时钟频率= VCO输出频率/ PLLP,并且PLLP = 2,4,6,8默认设置为2,使得PLL输出频率为168Mhz //默认USB OTG FS时钟频率= VCO输出频率/ PLLQ,并且2 <= PLLQ <= 15默认设置为7,使得输出频率为48Mhz RCC_PLLConfig(RCC_PLLSource_HSI,16,336,2,7); RCC_PLLCmd(ENABLE); while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)== RESET); //等待PLL稳定 / *配置Flash预取,指令缓存,数据缓存和等待状态* / FLASH-> ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS; RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //当PLL稳定之后,把PLL时钟切换为系统时钟SYSCLK while(RCC_GetSYSCLKSource()!= 0x08); //读取时钟切换状态位,确保PLLCLK被选为系统时钟 } / * *使用HSE时,设置系统时钟的步骤 * 1,开启HSE,并等待HSE稳定 * 2,设置AHB,APB2,APB1的预分频因子 * 3,设置PLL的时钟来源 *设置VCO输入时钟分频因子m *设置VCO输出时钟倍频因子 *设置PLLCLK时钟分频因子p *设置OTG FS,SDIO,RNG时钟分频因子q * 4,开启PLL,并等待PLL稳定 * 5,把PLLCK切换为系统时钟SYSCLK * 6,读取时钟切换状态位,确保PLLCLK被选为系统时钟 * / void HSE_SetSysClock(uint32_t frequency) { __IO uint32_t HSEStartUpStatus = 0; RCC_DeInit(); //复位RCC寄存器 RCC_HSEConfig(RCC_HSE_ON); //设置外部晶振HSE HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待HSE起振 if(HSEStartUpStatus == SUCCESS) { RCC_ClockSecuritySystemCmd(ENABLE); //启动时钟安全系统CSS //调压器电压输出级别配置为1,以便在器件为最大频率 //工作时使性能和功耗实现平衡 RCC-> APB1ENR | = RCC_APB1ENR_PWREN; PWR-> CR | = PWR_CR_VOS; RCC_HCLKConfig(RCC_SYSCLK_Div1); //设置ABH时钟HCLK =系统时钟HCLK = SYSCLK RCC_PCLK2Config(RCC_HCLK_Div2); //设置高速APB时钟PCLK2 =系统时钟2分频PCLK2 = SYSCLK / 2 RCC_PCLK1Config(RCC_HCLK_Div4); //设置低速APB时钟PCLK1 =系统时钟4分频PCLK = SYSCLK / 4 //默认VCO输入频率=外部晶振频率/外部晶振频率= 1Mhz,所以PLLM =频率,注意的是2 <= PLLM <= 63 //默认VCO输出频率= VCO输入频率* PLLN,并且192 <= PLLN <= 432,默认设置PLLN = 336,正好使VCO输出频率两分频后为168Mhz //默认PLL输出时钟频率= VCO输出频率/ PLLP,并且PLLP = 2,4,6,8默认设置为2,使得PLL输出频率为168Mhz //默认USB OTG FS时钟频率= VCO输出频率/ PLLQ,并且2 <= PLLQ <= 15默认设置为7,使得输出频率为48Mhz RCC_PLLConfig(RCC_PLLSource_HSE,频率,336,2,7); RCC_PLLCmd(ENABLE); //使能PLL while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)== RESET); //等待PLL稳定 / *配置Flash预取,指令缓存,数据缓存和等待状态* / FLASH-> ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS; RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //当PLL稳定之后,把PLL时钟切换为系统时钟SYSCLK while(RCC_GetSYSCLKSource()!= 0x08); //读取时钟切换状态位,确保PLLCLK被选为系统时钟 } else {// HSE启动出错使用系统内部HSI时钟 HSI_SetSysClock(); } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1784 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1621 浏览 1 评论
1088 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
729 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1680 浏览 2 评论
1938浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
734浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
570浏览 3评论
596浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
559浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 19:43 , Processed in 0.770516 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号