芯源半导体CW32
直播中

王树林

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

滴答定时器放在基本定时器前面就不工作是什么原因?

有个奇怪现象,滴答定时器放在基本定时器前面为啥就不工作,是因为初始化不对吗?


回帖(1)

从未拥有

3 天前

滴答定时器(SysTick)在基本定时器之前初始化时不工作,通常由以下原因导致:


1. 时钟系统未就绪



  • 核心问题:SysTick 依赖于内核时钟(如 HCLK)。若基本定时器的初始化代码中隐式配置了系统时钟(如配置 PLL、时钟分频等),而 SysTick 在此时钟配置前初始化,则 SysTick 会使用错误的时钟频率(如默认内部低速时钟)。

  • 现象:SysTick 的计数值因时钟频率过低(如 8 MHz → 1 kHz)或过高(如超范围)而无法正常触发中断。

  • 解决

    确保 SysTick 初始化之前,系统主时钟已正确配置(如调用 SystemClock_Config() 完成时钟树初始化)。




2. 中断优先级冲突



  • 核心问题:若基本定时器初始化时全局中断被关闭(如调用 __disable_irq()),而 SysTick 初始化后中断仍未开启,则 SysTick 中断无法触发。

  • 现象:SysTick 的计数器运行正常,但中断服务函数从未执行。

  • 解决:  

    • 检查中断开关状态:在 SysTick 初始化后确认 __enable_irq() 被调用。  

    • 调整优先级:避免抢占优先级冲突,确保 SysTick 中断未被屏蔽。





3. 硬件依赖顺序



  • 核心问题:某些单片机要求外设时钟使能顺序严格。若基本定时器初始化时使能了定时器时钟(如 RCC_APB1ENR |= RCC_APB1ENR_TIM6EN),而 SysTick 直接依赖系统时钟,可能因时钟域未同步导致异常。

  • 解决

    将 SysTick 初始化放在所有外设时钟使能完成之后,确保时钟树稳定。




4. SysTick 配置被覆盖



  • 核心问题:基本定时器初始化可能意外修改 SysTick 寄存器(如通过复用寄存器操作)。

  • 现象:SysTick 的 CTRL 寄存器值被篡改(如使能位被清除)。

  • 解决:  

    • 使用调试器检查 SysTick 寄存器值是否被意外修改。  

    • 隔离外设初始化:确保不同外设的配置无冲突。





快速验证步骤




  1. 调整初始化顺序

    将 SysTick 初始化移到系统时钟配置函数之后:


    SystemClock_Config();  // 先配置系统时钟
    MX_TIM6_Init();        // 初始化基本定时器
    HAL_SYSTICK_Config();  // 再初始化SysTick



  2. 检查时钟频率

    在 SysTick 初始化前验证 HCLK 的频率:


    uint32_t sysclk = HAL_RCC_GetHCLKFreq(); // 必须与预期一致



  3. 中断状态确认:  



    • 在 SysTick 中断服务函数中设置断点,观察是否触发。  

    • 检查 NVIC 中 SysTick 中断是否使能。






示例修正代码(STM32 HAL库)


int main(void) {
  HAL_Init();                       // HAL初始化(内部会初始化SysTick,但可能被覆盖)
  SystemClock_Config();             // 关键!先配置系统时钟
  MX_TIM6_Init();                   // 初始化基本定时器

  // 重新配置SysTick(可选,若HAL_Init()已配置则无需重复)
  HAL_SYSTICK_Config(HCLK_FREQ / 1000);  // 1ms中断
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); // 设置优先级

  while (1) { ... }
}


关键点:SysTick 的可行性取决于系统时钟的稳定性。务必在系统主时钟就绪后初始化 SysTick,并确保中断路径畅通。通过调整初始化顺序,90% 的类似问题可被解决。若仍不工作,需用调试器检查寄存器状态。


举报

更多回帖

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