【HAL库】STM32 Timer定时器开机立即进入中断问题


学习过程中发现配置号Timer定时器功能之后,原本应该定时到指定的时间再进入中断,结果MCU开机就会进入一次中断,不符合逻辑,所以尝试解决这个问题。

拜读各大佬的博客后发现没有HAL库的解决办法,于是转身向Google走去,找到了解决办法,分享给大家。


解决办法

在TIM初始化函数  HAL_TIM_Base_Init()   与   HAL_TIM_Base_Start_IT();

之间加一条语句 __HAL_TIM_CLEAR_FLAG(&htim7, TIM_SR_UIF); //注意将htim7改成自己的timer

其中TIM_SR_UIF是 Update interrupt Flag 寄存器。

原因就是HAL库中定时器初始化后没有更新中断标志位,__HAL_TIM_CLEAR_FLAG(&htim7, TIM_SR_UIF)后清除了更新中断标志位,此时TIM_SR_UIF为0,中断产生后TIM_SR_UIF为1。

另外

细心的朋友会发现TIM_SR_UIF其实是SR(定时器状态寄存器)的最低位,初始化时若TIM_SR_UIF为1则SR也为1,若TIM_SR_UIF为0则SR也为0,因此存在另一种解决办法:将__HAL_TIM_CLEAR_FLAG(&htim7, TIM_SR_UIF);换成htim7.Instance->SR = 0也是可以的。

示范

/**
  * @brief TIM7 Initialization Function
  * @param None
  * @retval None
  */
void MX_TIM7_Init(uint16_t arr, uint16_t psc)
{

  /* USER CODE BEGIN TIM7_Init 0 */

  /* USER CODE END TIM7_Init 0 */

  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM7_Init 1 */
	//(uint32_t)ceil(SECOND_WAKEUP) * 10000 / 2, 8400 - 1
  /* USER CODE END TIM7_Init 1 */
  htim7.Instance = TIM7;
  htim7.Init.Prescaler = psc;
  htim7.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim7.Init.Period = arr;
  htim7.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim7) != HAL_OK)// 定时器初始化
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM7_Init 2 */

   __HAL_TIM_CLEAR_FLAG(&htim7, TIM_SR_UIF);//添加这条语句解决问题
   //htim7.Instance->SR = 0; //这是另一种解决办法

   HAL_TIM_Base_Start_IT(&htim7);//开启定时器中断

  /* USER CODE END TIM7_Init 2 */
}

 

HAL库(Hardware Abstraction Layer)是STM32系列微控制器提供的标准软件包,它提供了一种标准化的方式来访问硬件资源,包括定时器。对于STM32F407这种基于ARM Cortex-M4的处理器,想要用Timer 2实现1ms的定时,可以按照以下步骤操作: 1. **初始化定时器**: - 首先,你需要配置定时器2( TIM2 )作为通用定时器模式,例如使用`TIM_TimeBaseInit`函数初始化它的基本定时结构。 ```c TIM_HandleTypeDef htim2; TIMClockConfigTypeDef sClockSourceConfig; htim2.Instance = TIM2; sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; // 使用内部时钟 HAL_TIM_Base_Init(&htim2); HAL_TIM_Base_SetPrescaler(&htim2, (TIM Prescaler)8); // 设置分频系数,假设系统时钟为168MHz,需要1/256分频到1MHz HAL_TIM_Base_ConfigClockSource(&htim2, &sClockSourceConfig); ``` 2. **设置周期和溢出事件**: - 然后,选择1ms周期,因为STM32的时钟频率通常很高,所以可能需要调整计数器的大小,比如设置为999(因为1ms * 1000 > 1us * 168M)。同时,开启溢出中断以在计数值到达设定值时触发。 ```c uint16_t uwPeriod = 999; HAL_TIM_Base_SetAutoreload(&htim2, uwPeriod); HAL_NVIC_EnableIRQ(TIM2_IRQn); // 启动定时器2中断 HAL_TIM_Base_Start_IT(&htim2); // 开始定时 ``` 3. **处理溢出中断**: - 创建一个中断服务程序(ISR),每当定时器溢出时执行,这里以Cortex-M为例: ```c void TIM2_IRQHandler(void) { HAL_TIM_IRQHandler(&htim2); if(__HAL_TIM_GET_FLAG(&htim2,.TIM旗帜__) == TIM_FLAG_Update) { // 操作完成,清除标志并准备下一次计时 __HAL_TIM_CLEAR_FLAG(&htim2, TIM_FLAG_Update); // 执行1ms后的任务... } } ```
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值