STM32CUBEMX配置教程(四)定时器中断配置

基于STM32H743VI 使用STM32CUBEMX两年了,始终觉得这个工具非常的方便,但因为不是经常使用,导致有些要点总是会有些遗忘,因此写下这一系列教程以供记忆,顺便让我这个大萌新给广大小萌新提供一些学习帮助。

本次配置的工程链接在最下方,有需要自取。 0基础可以从第一个教程开始阅读STM32CUBEMX配置教程(一)基础配置STM32CUBEMX配置教程(二)时钟等内部参数配置STM32CUBEMX配置教程(三)通用GPIO配置

此次教程的具体效果为定时器控制IO口点灯闪烁。

1 新建工程

参考STM32CUBEMX配置教程(一)基础配置

2 修改时钟树

参考STM32CUBEMX配置教程(二)时钟等内部参数配置

3 GPIO输出配置

配置PA0为输出模式,低速,推挽输出。 参考STM32CUBEMX配置教程(三)通用GPIO配置

4 定时器原理与分类

部分原理参考【STM32】HAL库 STM32CubeMX教程六----定时器中断

STM32定时器分为基本定时器、通用定时器和高级定时器,部分型号还具有低功耗定时器等等。

STM32基本定时器具有以下功能:

16位向上、向下、向上/下自动装载计数器

16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535之间的任意数值

定时触发ADC或者DAC以达到固定频率采用或者还原的目的(部分基本定时器具有此功能)

STM32通用定时器具有以下功能:

16位向上、向下、向上/下自动装载计数器

16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535之间的任意数值

4 个独立通道(TIMx_CH1~4)可以用作: 测量输入信号的脉冲长度( 输入捕获) 输出比较 单脉冲模式输出 PWM输出(边缘或中间对齐模式)

支持针对定位的增量(正交)编码器和霍尔传感器电路

如下事件发生时产生中断/DMA: 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内 部/外部触发) 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数) 输入捕获 输出比较

STM32高级定时器具有以下功能: 高级定时器具有基本、通用定时器的所有的功能,

还具有控制交直流电动机所有的功能,

输出6路互补带死区的信号,刹车功能等等

5 定时器配置实战

在此使用基础定时器的中断来控制灯的翻转,以TIM6为例。先在cubemx中的左侧找到Timers选项并选中TIM6:

cubemx 配置定时器输入捕获 cubemx配置定时器中断_stm32

在左侧方框中的Activated前的方框中打勾以激活该定时器,此时下方方框就会显示定时器的相关配置参数。

cubemx 配置定时器输入捕获 cubemx配置定时器中断_单片机_02

其中参数含义分别为:

Prescaler 分频系数

Counter Mode 计数模式(分为向上和向下)

Count Period 计数周期

auto-reload preload 自动重装载

TRGO Event Selection 触发事件其中分频系数和计数周期较为常用,可用于设置定时器溢出时间,一般来说溢出也代表定时器中断的产生(如果配置了中断)。溢出时间计算公式如下:

cubemx 配置定时器输入捕获 cubemx配置定时器中断_嵌入式_03

上面那个公式中arr为Count Period的设置数值,psc为Prescaler的设置数值。

Tclk为定时器挂载的时钟线的频率。对于STM32H743而言最高为240Mhz(根据自己的设置有关),不记得可以看看自己配置的时钟树。

下图中的TO APB1 Timer clocksClocks和TO APB2 Timer clocksClocks都是240Mhz。(虽然TIM6挂在哪个总线上忘记了,但是这里只有240M,有知道的小伙伴可以评论留言)。

cubemx 配置定时器输入捕获 cubemx配置定时器中断_stm32_04

如果我想要让灯每隔500ms切换一次状态,也就是每隔500ms进入一次中断,也就是Tout(上上一个图公式)为500ms。则需要设置psc为2399,arr为49999。那么溢出时间为:

2400*50000/240(us)=500ms

除了分频系数和计数周期这两个参数,计数模式(Counter Mode )使用默认的UP即可,auto-reload preload配置为Enable使能以使不停产生500ms的定时器中断,TRGO Event Selection 触发事件在配置定时器中断时无需修改,这个参数功能往往被用来控制ADC、DAC的固定频率采样

最终配置图如下:

cubemx 配置定时器输入捕获 cubemx配置定时器中断_嵌入式_05

还有一个非常重要的配置,打开定时器中断,找到并打开NVIC Settings一栏,在Enabled的方框下打勾以使能TIM6 global interrupt。,到此配置结束,点击生成代码。

cubemx 配置定时器输入捕获 cubemx配置定时器中断_初始化_06

6 启动定时器与修改中断函数

配置完成,需要在程序中手动启动定时器,系统才能进入定时器中断。 此函数为:

HAL_TIM_Base_Start_IT(&htim6);

注意,如果使用HAL_TIM_Base_Start(&htim6);函数打开定时器,则定时器会启动,但不会进入定时器中断。

主函数代码:

int main(void)
{

  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_TIM6_Init();
  HAL_TIM_Base_Start_IT(&htim6);

  while (1)
  {
  }
}

那么如何在中断到来时控制灯翻转呢?在keil工程中的main文件的目录下找到stm32h7xxit.c这个文件,我们配置的所有中断函数都能在此找到。

cubemx 配置定时器输入捕获 cubemx配置定时器中断_cubemx 配置定时器输入捕获_07

打开这个c文件,找到TIM6的中断,在其中添加翻转PA0的代码即可:

有同学可能疑问为什么还有DAC等字样,TIM6可以做DAC触发源,我们在此没用到不用管即可。

/**
  * @brief This function handles TIM6 global interrupt, DAC1_CH1 and DAC1_CH2 underrun error interrupts.
  */
void TIM6_DAC_IRQHandler(void)
{
  /* USER CODE BEGIN TIM6_DAC_IRQn 0 */
  HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_0);//翻转gpio
  /* USER CODE END TIM6_DAC_IRQn 0 */
  HAL_TIM_IRQHandler(&htim6);
  /* USER CODE BEGIN TIM6_DAC_IRQn 1 */

  /* USER CODE END TIM6_DAC_IRQn 1 */
}

在此看看效果,实际我的PA0上没有灯,给大家看看波形,可以看到输出了1HZ的方波,也就是每隔500ms翻转一次,如果有灯的话就能看到一闪一闪亮晶晶了!

cubemx 配置定时器输入捕获 cubemx配置定时器中断_单片机_08