请选择 进入手机版 | 继续访问电脑版

你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32 系统时钟读取问题

[复制链接]
shenxiaolin_mai 提问时间:2018-7-10 12:19 /
在使用系统时钟读取函数的时候出现实际的时钟和读取到的时钟不匹配的情况,请问各位大侠知道是怎么回事么?

1.png
微信截图_20180710121301.png

这是仿真的时候读取到的
我使用的是25M 的有源晶振,所以在晶振的配置的时候选择的RCC_HSE_Bypass

时钟的配置如下
  1. /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
  2. #define PLL_M      25
  3. #define PLL_N      336

  4. /* SYSCLK = PLL_VCO / PLL_P */
  5. #define PLL_P      2

  6. /* USB OTG FS, SDIO and RNG Clock =  PLL_VCO / PLLQ */
  7. #define PLL_Q      7
复制代码

  1. static void SetSysClock(void)
  2. {
  3. /******************************************************************************/
  4. /*            PLL (clocked by HSE) used as System clock source                */
  5. /******************************************************************************/
  6.   __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  7.   
  8.   /* Enable HSE */
  9.   RCC->CR |= ((uint32_t)RCC_CR_HSEON|RCC_HSE_Bypass);
  10.   /* Wait till HSE is ready and if Time out is reached exit */
  11.   do
  12.   {
  13.     HSEStatus = RCC->CR & RCC_CR_HSERDY;
  14.     StartUpCounter++;
  15.   } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

  16.   if ((RCC->CR & RCC_CR_HSERDY) != RESET)
  17.   {
  18.     HSEStatus = (uint32_t)0x01;
  19.   }
  20.   else
  21.   {
  22.     HSEStatus = (uint32_t)0x00;
  23.   }

  24.   if (HSEStatus == (uint32_t)0x01)
  25.   {
  26.     /* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */
  27.     RCC->APB1ENR |= RCC_APB1ENR_PWREN;
  28.     PWR->CR |= PWR_CR_VOS;

  29.     /* HCLK = SYSCLK / 1*/
  30.     RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
  31.       
  32.     /* PCLK2 = HCLK / 2*/
  33.     RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
  34.    
  35.     /* PCLK1 = HCLK / 4*/
  36.     RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;

  37.     /* Configure the main PLL */
  38.     RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
  39.                    (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);

  40.     /* Enable the main PLL */
  41.     RCC->CR |= RCC_CR_PLLON;

  42.     /* Wait till the main PLL is ready */
  43.     while((RCC->CR & RCC_CR_PLLRDY) == 0)
  44.     {
  45.     }
  46.    
  47.     /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
  48.     FLASH->ACR = FLASH_ACR_PRFTEN|FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;

  49.     /* Select the main PLL as system clock source */
  50.     RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
  51.     RCC->CFGR |= RCC_CFGR_SW_PLL;

  52.     /* Wait till the main PLL is used as system clock source */
  53.     while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
  54.     {
  55.     }
  56.   }
  57.   else
  58.   { /* If HSE fails to start-up, the application will have wrong clock
  59.          configuration. User can add here some code to deal with this error */
  60.   }

  61. }
复制代码


收藏 评论10 发布时间:2018-7-10 12:19

举报

10个回答
wenyangzeng 最优答案 回答时间:2018-7-10 13:19:29
本帖最后由 wenyangzeng 于 2018-7-10 13:21 编辑

读取的频率只不过是寄存器里的设置值,而非实际的频率。STM32无法直接读取那么高的时钟频率,况且至少要有定时器捕捉输入口的连接。

评分

参与人数 2ST金币 +2 蝴蝶豆 +3 收起 理由
zero99 + 3
xiaoshen-372360 + 2

查看全部评分

weiwei4 最优答案 回答时间:2018-7-11 09:19:23
有个外部时钟频率要设置一下吧
读取出来的只不过是寄存器跟设置的外部时钟频率的计算值,并不是直接测出来的频率

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

七哥 回答时间:2018-7-10 13:35:51
本帖最后由 toofree 于 2018-7-10 13:37 编辑

你用的什么芯片?
如果是STM32L4XX,并且是用STM32CubeMX生成的话,系统时钟配置有问题,是BUG。

我用STM32L496时,发现少配置了一个寄存器(忘了是哪个了,关于时钟的),而这个寄存器不配置的话,按默认值,会导致整个系统时钟超出2的32次方,因此溢出了。这时就相于取模,只取了时钟的低32位数据。

一看你的时钟这么奇怪,你就照着最大时钟溢出,这条线去查吧

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

shenxiaolin_mai 回答时间:2018-7-10 13:36:39
STM32F407IGT6
shenxiaolin_mai 回答时间:2018-7-10 13:36:56
toofree 发表于 2018-7-10 13:35
你用的什么芯片?
如果是STM32L4XX,并且是用STM32CubeMX生成的话,系统时钟配置有问题,是BUG。

STM32F407IGT6
jakecumt 回答时间:2018-7-10 22:33:05
能用一个GPIO反转 输出频率和预设频率之间的差值,计算出CPU时钟,在去设置寄存器值,看看能不能改过来

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

shenxiaolin_mai 回答时间:2018-7-11 10:18:11
weiwei4 发表于 2018-7-11 09:19
有个外部时钟频率要设置一下吧
读取出来的只不过是寄存器跟设置的外部时钟频率的计算值,并不是直接测出来的 ...

就是你说的这个问题,系统的频率是设置的,不是采集的,里面有一个HSE_Value的变量,设置为晶振的频率就可以了
jcx0324 回答时间:2018-7-11 11:37:49
是不是库里面有一个时钟宏定义,看下是不是跟你实际的一样

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

cloudcn 回答时间:2018-7-11 23:11:26
Watch 1里面 RCC_Clocks 后面的值是0x000000 啊 你看的值根就不对

void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks);
这个是函数原形
你传入的指针是个野指针 程序没崩溃就不错了

正常写法
RCC_ClocksTypeDef RCC_Clocks;
int main(void)
{
RCC_GetClocksFreq(&RCC_Clocks);
}

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

shenxiaolin_mai 回答时间:2018-7-12 08:55:34
cloudcn 发表于 2018-7-11 23:11
Watch 1里面 RCC_Clocks 后面的值是0x000000 啊 你看的值根就不对

void RCC_GetClocksFreq(RCC_ClocksType ...

我在外面定义了结构体的,现在问题解决了,这个始终频率是需要手动修改的,是直接定死的一个define ,还是谢谢你

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版