xiaoshen-372360 发表于 2018-7-10 12:19:52

STM32 系统时钟读取问题

在使用系统时钟读取函数的时候出现实际的时钟和读取到的时钟不匹配的情况,请问各位大侠知道是怎么回事么?




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

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

/* SYSCLK = PLL_VCO / PLL_P */
#define PLL_P      2

/* USB OTG FS, SDIO and RNG Clock =PLL_VCO / PLLQ */
#define PLL_Q      7

static void SetSysClock(void)
{
/******************************************************************************/
/*            PLL (clocked by HSE) used as System clock source                */
/******************************************************************************/
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;

/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON|RCC_HSE_Bypass);
/* Wait till HSE is ready and if Time out is reached exit */
do
{
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
    StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
    HSEStatus = (uint32_t)0x01;
}
else
{
    HSEStatus = (uint32_t)0x00;
}

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

    /* HCLK = SYSCLK / 1*/
    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
      
    /* PCLK2 = HCLK / 2*/
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
   
    /* PCLK1 = HCLK / 4*/
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;

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

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

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

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

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

}

wenyangzeng 发表于 2018-7-10 13:19:29

本帖最后由 wenyangzeng 于 2018-7-10 13:21 编辑

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

weiwei4 发表于 2018-7-11 09:19:23

有个外部时钟频率要设置一下吧
读取出来的只不过是寄存器跟设置的外部时钟频率的计算值,并不是直接测出来的频率

toofree 发表于 2018-7-10 13:35:51

本帖最后由 toofree 于 2018-7-10 13:37 编辑

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

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

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

xiaoshen-372360 发表于 2018-7-10 13:36:39

STM32F407IGT6

xiaoshen-372360 发表于 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时钟,在去设置寄存器值,看看能不能改过来

xiaoshen-372360 发表于 2018-7-11 10:18:11

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

就是你说的这个问题,系统的频率是设置的,不是采集的,里面有一个HSE_Value的变量,设置为晶振的频率就可以了

jcx0324 发表于 2018-7-11 11:37:49

是不是库里面有一个时钟宏定义,看下是不是跟你实际的一样

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] 2
查看完整版本: STM32 系统时钟读取问题