HAL库使用定时器作为Systick时钟的方法

7 篇文章 23 订阅
3 篇文章 1 订阅

前言

记录一下,在使用CubeMx生成的裸机模版移植完STemWin后,想再移植官方下载FreeRTOS的时候,遇到的一些问题。主要现象是编译没有错误,然后下载程序后,没办法运行对应程序,调试后发现进入HardFault_Handler,经过排查发现是FreeRTOS的心跳时钟与SysTick心跳有冲突。即SysTick没选择其他方式作为心跳源。

一、STM32CubeMX生成模版代码中的Systick的配置

1、Systick的初始化位于 HAL_Init()  中

2、具体位于HAL_InitTick( TICK_INT_PRIORITY ); 中

3、HAL_InitTick 中的详细代码

  • __weak 关键字:若两个或两个以上全局符号(函数或变量名)名字一样,而其中之一声明为weak属性,则这些全局符号不会引发重定义错误。链接器会忽略弱符号,去使用普通的全局符号来解析所有对这些符号的引用,但当普通的全局符号不可用时,链接器会使用弱符号。当有函数或变量名可能被用户覆盖时,该函数或变量名可以声明为一个弱符号
  • 我们所需要做的就是重新写一个HAL_InitTick( ) ,然后在里面配置我们定时器,然后在定时器中断服务函数中添加HAL_IncTick() 就行了。
__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
  /* Configure the SysTick to have interrupt in 1ms time basis*/
  if (HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)) > 0U)
  {
    return HAL_ERROR;
  }

  /* Configure the SysTick IRQ priority */
  if (TickPriority < (1UL << __NVIC_PRIO_BITS))
  {
    HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
    uwTickPrio = TickPriority;
  }
  else
  {
    return HAL_ERROR;
  }

  /* Return function status */
  return HAL_OK;
}

二、STM32CubeMX生成的TIM2作为Systick心跳的模版代码

HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
  RCC_ClkInitTypeDef    clkconfig;
  uint32_t              uwTimclock = 0;
  uint32_t              uwPrescalerValue = 0;
  uint32_t              pFLatency;
  
  /*Configure the TIM2 IRQ priority */
  HAL_NVIC_SetPriority(TIM2_IRQn, TickPriority ,0); 
  
  /* Enable the TIM2 global Interrupt */
  HAL_NVIC_EnableIRQ(TIM2_IRQn); 
  
  /* Enable TIM2 clock */
  __HAL_RCC_TIM2_CLK_ENABLE();
  
  /* Get clock configuration */
  HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
  
  /* Compute TIM2 clock */
  uwTimclock = 2*HAL_RCC_GetPCLK1Freq();
   
  /* Compute the prescaler value to have TIM2 counter clock equal to 1MHz */
  uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000) - 1);
  
  /* Initialize TIM2 */
  htim2.Instance = TIM2;
  
  /* Initialize TIMx peripheral as follow:
  + Period = [(TIM2CLK/1000) - 1]. to have a (1/1000) s time base.
  + Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
  + ClockDivision = 0
  + Counter direction = Up
  */
  htim2.Init.Period = (1000000 / 1000) - 1;
  htim2.Init.Prescaler = uwPrescalerValue;
  htim2.Init.ClockDivision = 0;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  if(HAL_TIM_Base_Init(&htim2) == HAL_OK)
  {
    /* Start the TIM time Base generation in interrupt mode */
    return HAL_TIM_Base_Start_IT(&htim2);
  }
  
  /* Return function status */
  return HAL_ERROR;
}

//TIM2中断服务函数
void TIM2_IRQHandler(void)
{
  HAL_TIM_IRQHandler(&htim2);
}

//TIM中断回调函
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if(htim->Instance == TIM2)
  {
        HAL_IncTick();      //Systick的心跳
  }
}

三、步骤总结

  • 重写 HAL_InitTick 
  • 在 HAL_InitTick 中配置对应定时器、使能定时器基本功能中断功能
  • 在中断服务函数中使用HAL提供的统一回调函数(会自动清除对应标志位),然后在里面添加HAL_IncTick()
HAL库中的滴答定时器是指SysTick定时器,它是CM4内核中的一个外设,内嵌在NVIC中。SysTick定时器是一个24bit的向下递减的计数器,计数器每计数一次的时间为1/SYSCLK,一般我们设置系统时钟SYSCLK等于180M。当重装载数值寄存器的值递减到0的时候,系统定时器就产生一次中断,以此循环往复。SysTick定时器常用来延时,或者实时系统的心跳时钟,以节省MCU资源,不用浪费一个定时器。在HAL库中,可以通过HAL_InitTick()函数来配置滴答定时器的重装载值和中断优先级。该函数会根据系统时钟频率SystemCoreClock来重新配置滴答定时器的重装载值,以决定产生每个中断的时间。同时,该函数还会设置定时器的中断优先级。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *3* [STM32F407HAL库-10.滴答定时器](https://blog.csdn.net/qq_41422043/article/details/100106891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [【STM32HAL库-系统滴答定时器SysTick](https://blog.csdn.net/qq_45607873/article/details/124654107)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不吃鱼的猫丿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值