STM32定时器时钟频率不变,保持在1.6MHz
Posted
技术标签:
【中文标题】STM32定时器时钟频率不变,保持在1.6MHz【英文标题】:STM32 timer clock frequency doesn't change and stay at 1.6MHz 【发布时间】:2021-04-22 01:02:21 【问题描述】:这几天我一直在阅读参考手册并更改代码以配置 STM32F401RE 定时器时钟。好像SYSCLK设置为84MHZ,PCLK1为42MHZ,PCLK2为84MHZ。但是每次我想用TIM2,时钟都设置在1.6MHZ。我用我的手机从开启和关闭状态开始计时,使用 PSC 和 ARR 我假设时钟频率约为 1.6MHZ
这里是时钟配置
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
PWR->CR &= ~PWR_CR_VOS_Msk;
PWR->CR |= PWR_CR_VOS_1; // scale mode 2
// flash
FLASH->ACR &= ~FLASH_ACR_LATENCY;
FLASH->ACR |= FLASH_ACR_LATENCY_2WS;
// HSI CONFIGURATION
RCC->CR |= RCC_CR_HSION;
while( !(RCC->CR & RCC_CR_HSIRDY) )
// PLL CONFIGURATION
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLSRC; // PLL SRC= HSI
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLM_Msk;
RCC->PLLCFGR |= 16 << RCC_PLLCFGR_PLLM_Pos;
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLN_Msk;
RCC->PLLCFGR |= 336 << RCC_PLLCFGR_PLLN_Pos;
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLP_Msk;
RCC->PLLCFGR |= RCC_PLLCFGR_PLLP_0; // div4
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLQ_Msk;
RCC->PLLCFGR |= 4 << RCC_PLLCFGR_PLLQ_Pos;
RCC->CR |= RCC_CR_PLLON;
while( !(RCC->CR & RCC_CR_PLLRDY) )
// CPU, AHB, APB buses clocks
RCC->CFGR &= ~RCC_CFGR_SW_Msk;// PLL CLK SRC
RCC->CFGR |= RCC_CFGR_SW_PLL;
while( !(RCC->CFGR & RCC_CFGR_SWS_PLL) )
// flash
FLASH->ACR &= ~FLASH_ACR_LATENCY;
FLASH->ACR |= FLASH_ACR_LATENCY_2WS;
RCC->CFGR &= ~RCC_CFGR_HPRE; // AHB DIV 1
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
RCC->CFGR &= ~RCC_CFGR_PPRE1_Msk; // APB1 DIV 2
RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;
RCC->CFGR &= ~RCC_CFGR_PPRE2_Msk; // APB2 DIV 1
RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;
SystemCoreClockUpdate();
这是 timer2 的配置
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
TIM2->CR1 |= TIM_CR1_CKD_1;
TIM2->PSC = 1093-1;
TIM2->ARR = 1024 - 1;
TIM2->CNT = 0;
TIM2->DIER |= TIM_DIER_UIE;
NVIC_EnableIRQ(TIM2_IRQn);
TIM2->CR1 |= TIM_CR1_CEN;
我在配置中有什么遗漏或误解的吗?
【问题讨论】:
您尚未显示切换 LED 的代码,因此我们无法确定这是否正确 - 即我们不知道您在计时。您要设置什么定时器频率?您的 PSC/ARR 建议 ~74.9823Hz,这可能不是有意的。SystemCoreClockUpdate();
在我使用 RCC 魔法之后确实看起来很可疑。它可能以不同的方式设置时钟。
@0___________ 该函数仅更新在供应商提供的 init 文件中定义的 SystemCoreClock
全局变量。如果在 RCC 魔法 之后立即调用它,如果固件没有等待实际发生更改,它可能会计算错误的值。但由于 OP 不使用 HAL 库,我认为即使是损坏的 SystemCoreClock
在这种情况下也不会导致问题。
【参考方案1】:
您的代码似乎大部分是正确的。我可以检测到 2 个问题,但我不确定它们是否是真正的原因。
PLL-Q 分频器应为 7。但这可能无关紧要,因为您可能不使用 USB 外围设备。不过,最好是在时钟限制内。 在切换时钟源后设置外设分频器 (APB1)。这意味着在您设置之前,APB1 的时钟频率为 84 MHz,超出规格。我不确定是否还有其他错误,但我已经在 F4 Discovery 板上测试了以下代码。它有一个STM32F407,但是这个uC和你的很相似。
FLASH->ACR |= FLASH_ACR_LATENCY_2WS; // 2 wait state for 84 MHz
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLQ;
RCC->PLLCFGR |= (7 << RCC_PLLCFGR_PLLQ_Pos); // PLL-Q: /7
RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC_HSI; // PLL source is HSI
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLP;
RCC->PLLCFGR |= (0b01 << RCC_PLLCFGR_PLLP_Pos); // PLL-P: /4
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLN;
RCC->PLLCFGR |= (336 << RCC_PLLCFGR_PLLN_Pos); // PLL-N: x336
RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLM;
RCC->PLLCFGR |= (16 << RCC_PLLCFGR_PLLM_Pos); // PLL-M: /16
RCC->CR |= RCC_CR_PLLON; // Activate the PLL (Output: 84 MHz)
while ((RCC->CR & RCC_CR_PLLRDY) == 0); // Wait until PLL is ready
RCC->CFGR |= RCC_CFGR_HPRE_DIV1 // AHB divider: /1 (84 MHz)
| RCC_CFGR_PPRE1_DIV2 // APB1 divider: /2 (42 MHz)
| RCC_CFGR_PPRE2_DIV1; // APB2 divider: /1 (84 MHz)
RCC->CFGR |= RCC_CFGR_SW_PLL; // Switching to PLL clock source
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); // Wait until switching is complete
这就是我如何配置 TIM2 以触发 1 Hz 频率的中断
TIM2->PSC = 42000 - 1;
TIM2->ARR = 2000 - 1; // 1 sec. overflow time @ 84 MHz
TIM2->EGR |= TIM_EGR_UG; // Event generation to update prescaler
TIM2->DIER |= TIM_DIER_UIE; // Enable update interrupt in peripheral
TIM2->CR1 |= TIM_CR1_CEN; // Start timer
NVIC_EnableIRQ(TIM2_IRQn); // Enable interrupt in NVIC
【讨论】:
以上是关于STM32定时器时钟频率不变,保持在1.6MHz的主要内容,如果未能解决你的问题,请参考以下文章