STM32
直播中

张莹

8年用户 1108经验值
私信 关注
[问答]

求助,关于STM32F407定时器定时时间的问题求解

使用STM32F407的tiM2定时器,使用内部时钟APB1,不分频(晶振25MHz),AHB也不分频,SYSCLK为25MHz,故APB1的时钟为25MHz,作为CK_INT,
由于禁止从模式,所以CK_PSC=CK_INT,设置PSC预分频器为24999,即分频25000,得到的CK_CNT为1KHz,设置技术CNT及自动重载寄存器为1000,向下递减模式,按理说应该1s产生一次中断,但实际上是2s产生一次中断。很郁闷啊……

  • #include
  • /*
  •   定时器中断
  •   SYSCLK:HSE---25MHz
  •   PE2:output
  • */
  • int flag=0;
  • /*
  •   configuration system clock
  •   SYSCLK---HSE---25MHz
  •   AHB not divided     APB1 AND APB2 not divided
  •   AHB:25MHz    APB1:25MHz
  • */
  • void config_clock()
  • {
  •   RCC->CR |= RCC_CR_HSEON;                                      //HSE oscillator ON
  •   while((RCC->CR   RCC_CR_HSERDY) != RCC_CR_HSERDY)             //HSE oscillator ready
  •     ;
  •   RCC->CFGR  = ~RCC_CFGR_PPRE1;                                 //reset PPRE1(APB1 PRESC)
  •   RCC->CFGR |= RCC_CFGR_PPRE1_DIV1;                             //HCLK not divided
  •   RCC->CFGR  = ~RCC_CFGR_SW;                                    //reset SW register
  •   RCC->CFGR |= RCC_CFGR_SW_0;                                   //select HSE as SYSCLK

  •   RCC->APB1RSTR |= RCC_APB1RSTR_TIM2RST;                        //reset TIM2
  •   RCC->APB1RSTR  = ~RCC_APB1RSTR_TIM2RST;                       //don't reset TIM2
  •   RCC->AHB1RSTR |= RCC_AHB1RSTR_GPIOERST;                       //reset GPIOE
  •   RCC->AHB1RSTR  =~RCC_AHB1RSTR_GPIOERST;                       //don't reset GPIOE
  •   RCC->AHB1RSTR |= RCC_AHB1RSTR_GPIOCRST;                       //reset GPIOC
  •   RCC->AHB1RSTR  = ~RCC_AHB1RSTR_GPIOCRST;                      //don't reset GPIOC

  •   RCC->AHB1ENR |= RCC_AHB1ENR_GPIOEEN;                          //enable GPIOE clock
  •   RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;                           //enable TIM2 clock

  • }

  • /*
  •   configuration GPIOs
  •   PE2 as output
  • */
  • void config_GPIOs()
  • {
  •   GPIOE->ODR |= GPIO_ODR_ODR_2;                                 //set output data register 1
  •   GPIOE->MODER |= GPIO_MODER_MODER2_0;                          //set PE2 as output mode
  • }

  • /*
  •   configuration TIM2
  • */
  • void config_TIM2()
  • {
  •   TIM2->CR1  = ~TIM_CR1_ARPE;                               //TIM2_ARR register is buffered
  •   TIM2->CR1  = ~TIM_CR1_CMS;                               //Edge-aligned mode
  •   TIM2->CR1 |= TIM_CR1_DIR;                                //counter used as downcounter
  •   TIM2->CR1 |= TIM_CR1_URS;                                //only counter overflow/underflow-->interrupt/DMA request
  •   //TIM2->CR1  = ~TIM_CR1_UDIS;                              //enable update

  •   TIM2->SMCR  = ~TIM_SMCR_SMS;                             //slave mode disabled use internal clock

  •   TIM2->CNT = 500;
  •   TIM2->PSC = 24999;                                       //Prescaler value(CK_CNT:0.5KHz)
  •   TIM2->ARR = 500;                                         //auto-reload register

  •   TIM2->EGR |= TIM_EGR_UG;

  •   TIM2->SR  = ~TIM_SR_UIF;
  •   TIM2->DIER |= TIM_DIER_UIE;                              //Update interrupt enable

  •   TIM2->CR1 |= TIM_CR1_CEN;                               //counter enable
  • }



  • void main()
  • {
  •   config_clock();
  •   config_GPIOs();
  •   NVIC_EnableIRQ(TIM2_IRQn);
  •   NVIC_SetPriority(TIM2_IRQn,5);
  •   config_TIM2();
  •   while(1)
  •   {
  •   }
  • }


  • void TIM2_IRQHandler()
  • {
  •   TIM2->SR  = ~TIM_SR_UIF;                              //clear interrupt flag
  •   if(flag)
  •   {
  •     GPIOE->ODR  = ~GPIO_ODR_ODR_2;
  •     flag=0;
  •   }
  •   else
  •   {
  •     GPIOE->ODR |= GPIO_ODR_ODR_2;
  •     flag=1;
  •   }
  • }


回帖(1)

王桂英

2024-5-13 17:31:44
首先,让我们分析一下你的问题。你正在使用STM32F407的TIM2定时器,使用内部时钟APB1,晶振25MHz,AHB不分频,SYSCLK为25MHz。你设置了PSC预分频器为24999,技术CNT及自动重载寄存器为1000,向下递减模式。理论上,你应该每1秒产生一次中断,但实际上是2秒产生一次中断。

为了解决这个问题,我们需要检查以下几个方面:

1. 确保定时器配置正确:检查TIM2的初始化代码,确保你已经正确设置了时钟源、预分频器、自动重载寄存器等参数。

2. 检查定时器中断:确保你已经正确配置了NVIC(嵌套向量中断控制器),并启用了TIM2的中断。同时,检查中断服务函数(ISR)是否正确处理了中断。

3. 检查定时器计数模式:你提到使用了向下递减模式,确保这个模式已经被正确设置。

4. 检查定时器时钟:确保APB1时钟已经正确设置,并且与你的预期相符。

5. 检查代码逻辑:检查你的代码逻辑,确保没有其他地方影响了定时器的计数。

以下是一些可能的解决方案:

- 确保你已经正确初始化了TIM2定时器,包括时钟源、预分频器、自动重载寄存器等参数。
- 在中断服务函数(ISR)中,检查是否正确清除了中断标志。例如,使用`__HAL_TIM_CLEAR_IT(&htim2, TIM_IT_UPDATE);`来清除TIM2的更新中断标志。
- 如果你使用的是HAL库,确保你已经正确配置了NVIC,并启用了TIM2的中断。例如,使用`HAL_NVIC_EnableIRQ(TIM2_IRQn);`来启用TIM2中断。
- 检查你的代码逻辑,确保没有其他地方影响了定时器的计数。


举报

更多回帖

发帖
×
20
完善资料,
赚取积分