在不使用FreeRTOS的时候,SysTick是默认的HAL基础时钟源,但是在SYS模块中,也可以选择其他定时器作为基础时钟源,例如可以选择基础定时器TIM6作为HAL的基础时钟源。
图1 选用TIM6作为HAL的基础时钟
选择TIM6作为基础时钟源后,TIM6就不能在作为其他用途,在STM32CubeMX中不能再对TIM6做任何设置。在NVIC中,TIM6的中断被自动启用,优先级被设置为最高。可以修改TIM6的中断优先级,但是不能关闭TIM6的中断。同时,SysTick定时器的中断也还是被自动启用的,且不能关闭,如图2所示。
图2 使用TIM6作为HAL基础时钟源时的NVIC设置
1. 基础时钟的初始化
在使用定时器TIM6作为HAL的基础时钟源并用STM32CubeMX生成代码后,\Src目录下新增了一个文件stm32f4xx_hal_timebase_TIM.c,这个文件里重新实现了文件stm32f4xx_hal.c中的3个弱函数,用定时器TIM6替代了SysTick的功能。文件stm32f4xx_hal_timebase_TIM.c的完整代码如下:
/* 文件: stm32f4xx_hal_timebase_TIM.c -----------------------------------------*/ #include "stm32f4xx_hal.h" #include "stm32f4xx_hal_tim.h" TIM_HandleTypeDef htim6; HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) { RCC_ClkInitTypeDef clkconfig; uint32_t uwTimclock = 0; uint32_t uwPrescalerValue = 0; uint32_t pFLatency; HAL_NVIC_SetPriority(TIM6_DAC_IRQn, TickPriority ,0); //设置TIM6的中断优先级 HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn); //开启TIM6中断 __HAL_RCC_TIM6_CLK_ENABLE(); //开启TIM6的时钟 HAL_RCC_GetClockConfig(&clkconfig, &pFLatency); //获取时钟配置 uwTimclock = 2*HAL_RCC_GetPCLK1Freq(); //计算TIM6的时钟频率,是PCLK1的2倍 /* 计算分频系数,使TIM计数器时钟信号为1MHz*/ uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000) - 1); /* 初始化 TIM6,使其定时周期为 1ms */ htim6.Instance = TIM6; htim6.Init.Period = (1000000 / 1000) - 1; htim6.Init.Prescaler = uwPrescalerValue; htim6.Init.ClockDivision = 0; htim6.Init.CounterMode = TIM_COUNTERMODE_UP; if(HAL_TIM_Base_Init(&htim6) == HAL_OK) { return HAL_TIM_Base_Start_IT(&htim6); //以中断方式启动TIM6 } return HAL_ERROR; } void HAL_SuspendTick(void) { /* 禁止 TIM6 的UEV中断 */ __HAL_TIM_DISABLE_IT(&htim6, TIM_IT_UPDATE); } void HAL_ResumeTick(void) { /* 卡其 TIM6 的UEV中断 */ __HAL_TIM_ENABLE_IT(&htim6, TIM_IT_UPDATE); }
函数HAL_InitTick()是在HAL_Init()中被调用的,重新实现的这个函数对定时器TIM6进行了初始化配置,设置其中断优先级,配置其分频系数、计数周期等,使其定时器周期为1ms。
重新实现的函数HAL_ResumeTick()和HAL_SuspendTick()也是对TIM6的操作。
2. 基础时钟的中断处理
在使用定时器TIM6作为HAL的基础时钟源并用STM32CubeMX生成代码后,在文件stm32f4xx_it.c中没有了SysTick的ISR函数,有TIM6的ISR函数。TIM6的ISR函数代码如下:
void TIM6_DAC_IRQHandler(void) { HAL_TIM_IRQHandler(&htim6); }
定时器的UEV事件的回调函数是HAL_TIM_PeriodElapsedCallback,在文件main.c中就重新实现了这个函数,其功能就是执行函数HAL_IncTick(),代码如下:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM6) { HAL_IncTick(); } }
所以,在使用TIM6作为HAL的基础时钟时,TIM6完全替代了SysTick的功能。
下一篇 FreeRTOS的基础时钟
主题 HAL和FreeRTOS的基础时钟
---------------------
作者:HongAndYi
来源:CSDN
原文:https://blog.csdn.net/HongAndYi/article/details/103414576?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_title~default-0.pc_relevant_default&spm=1001.2101.3001.4242.1&utm_relevant_index=1
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件