野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 8029|回复: 4

HSI配置为系统时钟,稳定判断问题

[复制链接]
发表于 2017-11-17 15:35:28 | 显示全部楼层 |阅读模式
本帖最后由 拖延症晚期 于 2017-11-17 15:49 编辑

学习火哥的教程到RCC这一章,例程的 bsp_clkconfig.c 中分别有使用 HSE 和 HSI 配置为系统时钟的函数

第一步都是开启时钟,等待时钟稳定,稳定后进行后续的一系列配置,我对比了判断 HSE 和 HSI 稳定的过程,如下



一、HSE
  1. void HSE_SetSysClock(uint32_t m, uint32_t n, uint32_t p, uint32_t q)        
  2. {
  3.   __IO uint32_t HSEStartUpStatus = 0;
  4.   
  5.   // 使能HSE,开启外部晶振,秉火F407使用 HSE=25M
  6.   RCC_HSEConfig(RCC_HSE_ON);
  7.         
  8.   // 等待HSE启动稳定
  9.         HSEStartUpStatus = RCC_WaitForHSEStartUp();

  10.   if (HSEStartUpStatus == SUCCESS)
  11.   {......}
复制代码
判断稳定这一步调用了RCC_WaitForHSEStartUp(),查到该函数定义为


  1. ErrorStatus RCC_WaitForHSEStartUp(void)
  2. {
  3.   __IO uint32_t startupcounter = 0;
  4.   ErrorStatus status = ERROR;
  5.   FlagStatus hsestatus = RESET;
  6.   /* Wait till HSE is ready and if Time out is reached exit */
  7.   do
  8.   {
  9.     hsestatus = RCC_GetFlagStatus(RCC_FLAG_HSERDY);
  10.     startupcounter++;
  11.   } while((startupcounter != HSE_STARTUP_TIMEOUT) && (hsestatus == RESET));

  12.   if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET)
  13.   {
  14.     status = SUCCESS;
  15.   }
  16.   else
  17.   {
  18.     status = ERROR;
  19.   }
  20.   return (status);
  21. }
复制代码
函数体中用了一个do{}while()循环,轮询RCC寄存器相应状态位,直到状态位指示稳定,跳出循环


可见HSE启动到稳定需要一定的时间,而HSI的函数如下


二、HSI
  1. void HSI_SetSysClock(uint32_t m, uint32_t n, uint32_t p, uint32_t q)        
  2. {
  3.   __IO uint32_t HSIStartUpStatus = 0;
  4.         
  5.   // 把RCC外设初始化成复位状态
  6. RCC_DeInit();
  7.   
  8.   //使能HSI, HSI=16M
  9.   RCC_HSICmd(ENABLE);
  10.         
  11.   // 等待 HSI 就绪
  12. HSIStartUpStatus = RCC->CR & RCC_CR_HSIRDY;
  13.         
  14. // 只有 HSI就绪之后则继续往下执行
  15.   if (HSIStartUpStatus == RCC_CR_HSIRDY)
  16.   {......}
复制代码
    这里首先调用了RCC_DeInit(),这里其实已经使能了HSI,rcc初始化默认配置HSI为系统时钟,然后使能HSI,下一行注释是等待HSI就绪,然而只有一条读取 RCC_CR的HSIRDY 位的操作,并没有类似于HSE中轮询等待的步骤,相当于使能完就直接读取状态位,没有等待稳定的时间,如果这时HSI没有稳定,if 后面的语句不就不执行了吗?

   这是我的一点疑惑,另外RCC_DeInit()函数中已经使能了HSI,还有一些设置默认系统时钟、分频系数的语句,难道是因为调用了RCC_DeInit()后,到读取状态位HSIStartUpStatus = RCC->CR & RCC_CR_HSIRDY这一步,这段时间已经足够HSI稳定了吗?






回复

使用道具 举报

发表于 2017-11-17 15:38:37 | 显示全部楼层
你理解的都对
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-11-17 15:42:48 | 显示全部楼层

额,秒回啊,难道真是调用 RCC_DeInit() 的时间足够HSI稳定?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-11-17 15:53:46 | 显示全部楼层
我自己在HSI的稳定判断这里加一个do{}while()循环是否可行呢
各位大佬帮忙啊
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-11-17 20:01:26 | 显示全部楼层

火哥,发现了一个小漏洞,例程里void HSE_SetSysClock(uint32_t m, uint32_t n, uint32_t p, uint32_t q) 中配置HSE前,没有调用 RCC_DeInit() 初始化哦,这样RCC寄存器好像不能更改吧,可能是漏写了吧
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-10-6 00:30 , Processed in 0.036091 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表