想用stm32的定时器,定时一分钟,该怎样做呀?尽量描述细点,谢谢了

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了想用stm32的定时器,定时一分钟,该怎样做呀?尽量描述细点,谢谢了相关的知识,希望对你有一定的参考价值。

首先,你做一个100ms的时钟中断,然后设一个int counter = 0;变量,每进入一次中断,对他加1(counter++),直到他等于 60s/0.1s = 600时,就是一分钟了,然后counter清零继续累加。 参考技术A 可用滴答定时,或者用普通定时器定个100ms,进入一定就累加1,10次就一秒,600次就是1分钟 参考技术B 我是用用Systick定时1秒,再加个for循环60次的。。。。我菜鸟,不对之处望指正 参考技术C 关注这个问题

STM32定时器时钟频率不变,保持在1.6MHz

【中文标题】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的定时器,定时一分钟,该怎样做呀?尽量描述细点,谢谢了的主要内容,如果未能解决你的问题,请参考以下文章

STM32F103五分钟入门系列定时器中断

怎样做到stm32 定时器 定时时间可调,(又不用初始化)

怎样使stm32f4内部产生正弦波驱动wm8978发出声音

stm32怎样实现不同定时器产生不同频率的PWM波?

STM32定时器时钟频率不变,保持在1.6MHz

STM32F103五分钟入门系列(十五)输出比较(PWM输出)+各类测试