背景

上一讲 STM32 CubeMX 学习:外部中断的使用 介绍了如何配置以及操作GPIO外部中断。

这一讲我们介绍定时器的有关概念,并对其中一种进行示范。

HOST-OS : Windows-10

STM32 Cube :v5.6

MCU : STM32F429

LIB : stm32cube_fw_f4_v1250

知识

STM32中,有基本定时器(Basic timer)、通用定时器(General-purpose timer)、高级定时器(Advanced-control timer)三类TIM定时器。

  • 基本定时器 是16位的只能向上计数的定时器,只能用于定时。
  • 通用定时器和高级定时器有更多的功能,如还可以进行输出比较、输入捕捉等功能。
定时器种类 位数 计数器模式 产生DMA请求 捕获/比较通道 互补输出 特殊应用场景
高级定时器 16 向上,向下,向上/下 可以 4 带可编程死区的互补输出
通用定时器 32 向上,向下,向上/下 可以 4 通用。定时计数,PWM输出,输入捕获,输出比较
通用定时器 16 向上,向下,向上/下 可以 4 通用。定时计数,PWM输出,输入捕获,输出比较
通用定时器 16 向上 没有 2 通用。定时计数,PWM输出,输入捕获,输出比较
基本定时器 16 向上,向下,向上/下 可以 0 主要应用于驱动DAC(TIM 6,7 独有)

如何知道STM32什么芯片拥有多少个定时器,每一个定时器对应了什么什么种类的定时器。

  • ST官网查找有关的芯片手册,根据下载的芯片手册中的目录(Contents)可以看到:
  • SMT32F4系列共有15个定时器:高级定时器(TIM1、TIM8);通用定时器(TIM 2 ~ 5、TIM 9 ~ 14);基本定时器(TIM6、TIM7)。
Contents STM32F427xx STM32F429xx
3.22 Timers and watchdogs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.22.1 Advanced-control timers (TIM1, TIM8) . . . . . . . . . . . . . . . . . . . . . . . 36
3.22.2 General-purpose timers (TIMx) . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.22.3 Basic timers TIM6 and TIM7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.22.4 Independent watchdog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.22.5 Window watchdog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.22.6 SysTick timer. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

定时器的有关功能

基本定时器就是单纯的定时计数器;通用定时器多了四个通道,相对应的增加了功能;高级定时器具有基本,通用定时器的所有的功能,并且添加了其他功能。

基本定时器功能(TIM6、TIM7):

  • 16位向上、向下、向上/下自动装载计数器
  • 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535之间的任意数值
  • 触发DAC的同步电路 (此项是TIM6/7独有功能)
  • 位于APB1总线上

通用定时器(TIM2~TIM5)的主要功能:

  • 16位向上、向下、向上/下自动装载计数器
  • 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65535之间的任意数值
  • 4 个独立通道(TIMx_CH1~4)可以用作:
  • 测量输入信号的脉冲长度( 输入捕获)
  • 输出比较
  • 单脉冲模式输出
  • PWM输出(边缘或中间对齐模式)
  • 支持针对定位的增量(正交)编码器和霍尔传感器电路
  • 如下事件发生时产生中断/DMA:
  • 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
  • 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
  • 输入捕获
  • 输出比较
  • 位于APB1总线上

高级定时器(TIM1,TIM8)的主要功能:

  • 高级定时器具有基本,通用定时器的所有的功能,
  • 还具有控制交直流电动机所有的功能,
  • 输出6路互补带死区的信号,刹车功能等等
  • 位于APB2总线上

STM32 APB1和APB2的区别如下:(要结合时钟树来理解APB, Advanced Peripheral Bus)

一般APB1和APB2上的时钟都是系统时钟经过 AHB(Advanced High performance Bus) Prescaler 分频得到 HCLK(High performance Bus Clock 高级高性能总线时钟)。

  • HCLK 经过APB1 Prescaler 得到APB1时钟,而总线下TIMER的时钟源为APB1的2倍
  • HCLK 经过APB2 Prescaler 得到APB2时钟,而总线下TIMER的时钟源为APB2的2倍

AHB,是Advanced High performance Bus的缩写,译作高级高性能总线,这是一种“系统总线”,主要用于高性能模块(如CPU、DMA和DSP等)之间的连接。

1)所负责端口不同:

  • APB2负责AD,I/O,高级TIM,串口1。
  • APB1负责DA,USB,SPI,I2C,CAN,串口2345,普通TIM。

    2)所支持速度不同:APB2支持高速状态下的工作,APB1支持低速状态下的工作。

时钟源

时钟需要时钟源来驱动。计数器时钟可以由下列时钟源提供:

  • 内部时钟(CK_INT)
  • 外部时钟模式1:外部捕捉比较引脚(TIx)
  • 外部时钟模式2:外部触发输入(ETR) (仅适用于TIM 2,3,4)
  • 内部触发输入(ITRx):使用一个定时器作为另外一个定时器的预分频器(例如配置TimerA作为TimerB的预分频器)

定时器有关框图

基本定时器主要由下面三个寄存器组成。

  • 计数器寄存器 (TIMx_CNT)
  • 预分频器寄存器 (TIMx_PSC)
  • 自动重载寄存器 (TIMx_ARR)

关于定时器配置的一些参数

虽然有3类定时器但,不管怎样,只要是配置作为定时器,那么便 总是 与 基本定时器是类似的。

在下文配置的时候要注意:我们配置的是进入定时器中断的频率,然后要定的时间要跟据这个频率来定时的。

Prescaler(PSC): 定时器预分频设置,用来设置TIMx_PSC的值,16位,设置 0~65535 以达到 1 至 65536 的分频。

Couter Mode : 定时器的计数方式,基本定时器只能向上(UP)计数(即TIMx_CNT只能从0开始递增,无须初始化)

http://www.waveshare.net/study/article-642-1.html

定时器有如下3种计数模式:

  • 递增计数模式:计数器从 0 计数到自动重载值(TIMx_ARR寄存器的值),然后重新从 0 开始计数并生成计数器上溢事件。
  • 递减计数模式:计数器从自动重载值(TIMx_ARR)开始递减到 0,然后重新从自动重载值开始计数并生成计数器下溢事件。
  • 中心对齐模式:也叫 向上向下计数,计数器从 0 开始计数到自动重载值(TIMx_ARR) – 1 ,生成计数器上溢事件;然后从自动重载值开始向下计数到 1 并生成计数器下溢事件。之后从0 开始重新计数。

Couter Period : 定时器周期,16位,设置 0~65535 以达到 1 至 65536 的周期。每当定时器达到 设定值时,置位。

假设现在HCLK为 168 MHZ,设置了下面的值:

  • 预分频(PSC):167,那么分频以后的时钟是: 168 MHz / (167 + 1 ) = 1 MHz

  • 如果 定时器周期(Period) 的 值 设置为999,定时器产生中断的频率 为:1MHz/1000 = 1Khz,即 1 ms 的定时周期。

    那么也就有:

\[发生中断的时间 = (PSC + 1) * ( Period + 1)/定时器的频率
\]

InternalCLock Division(CKD): 内部时钟分频因子,与PWM输出实验其实是没关系的,指设置定时器时钟(CK_INT)频率与数字滤波器(ETR,TIx)使用的采样频率之间的分频比例的(与输入捕获相关)。

Auto-reload preload :自动重载。一般每次触发以后需要重新填充。

ARM中,有的逻辑寄存器在物理上对应2个寄存器,一个是程序员可以写入或读出的寄存器,称为preload register(预装载寄存器),另一个是程序员看不见的、但在操作中真正起作用的寄存器,称为shadow register(影子寄存器);

设计preload register和shadow register的好处是:所有真正需要起作用的寄存器(shadow register)可以在同一个时间(发生更新事件时)被更新为所对应的preload register的内容,这样可以保证多个通道的操作能够准确地同步。如果没有shadow register,或者preload register和shadow register是直通的,即软件更新preload register时,同时更新了shadow register,因为软件不可能在一个相同的时刻同时更新多个寄存器,结果造成多个通道的时序不能同步,如果再加上其它因素(例如中断),多个通道的时序关系有可能是不可预知的。

Trigger Output Parameters : 触发输出 (TRGO) ,当定时器的定时时间到达的时候输出一个信号(如:定时器更新产生TRGO信号来触发ADC的同步转换)

Repetition Counter:重复计数器(RCR -8 bits),属于高级控制寄存器专用寄存器位,利用它可以非常容易控制输出 PWM 的个数。

Master/Slave Mode(MSM bit) :主从模式

定时器一般是通过软件设置而启动,STM32的每个定时器也可以通过外部信号触发而启动,还可以通过另外一个定时器的某一个条件被触发而启动。这里所谓某一个条件可以是定时到时间、定时器超时、比较成功等许多条件。

这种通过一个定时器触发另一个定时器的工作方式称为定时器的同步,发出触发信号的定时器工作于主模式,接受触发信号而启动的定时器工作于从模式。

定时器的四种主从机模式:外部触发模式1、IRC重置模式、门控模式、触发模式。

CubeMx 对 定时器的配置 (以TIM6 为例)

1)在Pinout & Configuration中,选择一个 定时器 (例如 TIM6)

2)"Mode":勾选 "Activated"

3)"Configuration " - "Parameter Settings"中 :

  • PSC : 167
  • Counter Mode: Up
  • Counter Period: 999
  • auto-reload preload: Enable
  • Trigger Event Selection : Reset
  1. "Configuration " - "NVIC Settings"中 : 勾选 "Enabled" (开启中断)

    5)右上角,"GENERATE CODE"

源码分析

通过配置以后,在main函数中会有对应的定时器初始化函数,在新版的CubeMx中如果配置了中断,那么响应的中断函数HAL_TIM_Base_Start_IT也可以看到。

int main(void)
{
/* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */
SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM6_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_Base_Start_IT(&htim6);
/* USER CODE END 2 */ /* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */ /* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
   9 static void TIM_DMAPeriodElapsedCplt(DMA_HandleTypeDef *hdma)
8 {
7 TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
6
5 htim->State = HAL_TIM_STATE_READY;
4
3 #if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
2 htim->PeriodElapsedCallback(htim);
1 #else
5747 HAL_TIM_PeriodElapsedCallback(htim);
1 #endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
2 }

由于 DMA的机制这里还未涉及,所以不讨论 DMA 中断的机制。有关文件:Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.cDrivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c

HAL_TIM_DMABurst_WriteStart 中注册了 TIM_DMAPeriodElapsedCplt 作为 hdma->XferCpltCallback的回调函数

HAL_DMA_IRQHandler() -> hdma->XferCpltCallback(hdma); -> TIM_DMAPeriodElapsedCplt() -> HAL_TIM_PeriodElapsedCallback()

添加代码

/* USER CODE BEGIN 0 */

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {

    if (htim->Instance == TIM6){
// do_something();
}
} /* USER CODE END 0 */

运行,即可

STM32 CubeMX 学习:003-定时器的更多相关文章

  1. cubemx+stm32串口学习汇总资料

    这篇文章是串口中断的文章--STM32基于CubeMX的高速串口收发程序(中断模式)比较有帮助. http://www.stmcu.org.cn/module/forum/thread-616613- ...

  2. STM32定时器学习---基本定时器

    STM32F1系列的产品,除了互联网产品外,工作8个,3种定时器,其中一种就是基本定时器.那么STM32单片机的基本定时器如何操作以及编程呢? 下面我们就来详细的了解一下 STM32F1系列的产品,除 ...

  3. STM32学习笔记——定时器中断(向原子哥学习)

    定时器中断 STM32 的定时器功能十分强大,有 TIME1 和 TIME8 等高级定时器,也有 TIME2~TIME5 等通用定时器,还有 TIME6 和TIME7 等基本定时器.在本章中,我们将利 ...

  4. JavaScript学习05 定时器

    JavaScript学习05 定时器 定时器1 用以指定在一段特定的时间后执行某段程序. setTimeout(): 格式:[定时器对象名=] setTimeout(“<表达式>”,毫秒) ...

  5. STM32 FSMC学习笔记+补充(LCD的FSMC配置)

    STM32 FSMC学习笔记+补充(LCD的FSMC配置) STM32 FSMC学习笔记 STM32 FSMC的用法--LCD

  6. stm32之Cortex系统定时器(SysTick)

    转载自:http://www.21ic.com/app/mcu/201811/781135.htm   SysTick时钟,俗称“嘀嗒定时器”,它能按设定的时间产生一次中断.控制工程代码中随处可见形如 ...

  7. 基于STM32的学习型通用红外遥控设备的设计实现(三)

    CPU: STM32 调试平台: STM32F103ZET和STM32F103VBT 软件平台: Keil uVision4 电路设计: Altium Designer v6.9 http://blo ...

  8. STM32F103单片机学习—— 通用定时器

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/fengshuiyue/article/details/79150724 本篇重点记录的是STM32F ...

  9. Nordic52840SDK学习之定时器

    Nordic 52840 SDK学习之定时器 今天开始学习52840SDK,特在此处记录学习内容,防止以后忘记,或许可以给以后的初学者提供一些帮助.如有错误,请发邮件至843036544@qq.com ...

  10. 【转载-Andrew_qian】stm32中断学习

    [转载]stm32中断学习 中断对于开发嵌入式系统来讲的地位绝对是毋庸置疑的,在C51单片机时代,一共只有5个中断,其中2个外部中断,2个定时/计数器中断和一个串口中断,但是在STM32中,中断数量大 ...

随机推荐

  1. Codeforces Good Bye 2023

    A. 2023 正常签到. void solve() { int n, k, ok = 1; cin >> n >> k; int t = 2023; while(n --) ...

  2. 大模型_2:Prompt Engineering

    目录: 1.提示工程简介 2.如何写好提示词 2.1 描述清晰 2.2 角色扮演 2.3 提供示例 2.4 复杂任务分解 2.5 使用格式符区分语义 2.6 情感和物质激励 2.7 使用英语 2.8  ...

  3. ruby中的Hash排序

    参考: https://blog.csdn.net/xing102172/article/details/9163607 For example: h={'a'=>2, 'c'=>1, ' ...

  4. WEB服务与NGINX(26)- 实现Nginx高并发系统内核参数优化

    1. 实现Nginx高并发系统内核参数优化 由于默认的Linux内核参数考虑的是最通用场景,这明显不符合用于支持高并发访问的Web服务器的定义,所以需要修改Linux内核参数,使得Nginx可以拥有更 ...

  5. C++ 资源大全:标准库、Web框架、人工智能等 | 最全整理

    C++ 资源列表,内容包括: 标准库.Web应用框架.人工智能.数据库.图片处理.机器学习.日志.代码分析等 目录 进程间通信 Json 日志 机器学习 数学 内存分配 多媒体 网络 PDF 物理学 ...

  6. warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result [-Wunused-result] scanf("%d",&f);

    这个是C语言当中常见的错误,意思是 对于输入的scanf参数的内容,没有进行类型判断,所以才会产生这个问题. 解决方法: 1.添加if判断方式 1 if(scanf("%d",&a ...

  7. JSON返回结果修改null为"";json字段为null时输出空字符串

    简介 (Introduction): 背景 json字符串返回的需要"",但是却是null,怎么处理呢,如下 结构图 1 [ 2 { 3 "1":{ 4 &qu ...

  8. pageoffice6提取word指定位置(数据区域)的值

    在实际的开发过程中,经常会遇到提取Word文档中指定位置的数据保存到数据库中的需求,PageOffice客户端控件即支持在线保存Word文件,也支持Word文档中的指定位置的数据或所有的数据提交到服务 ...

  9. 你知道 Java 有哪些引用吗?

    前言 判断对象是否要回收有引用计数法和可达性算法两种方式,无论哪种都离不开引用,本文将介绍Java的四种引用. 一.概述 二.详解 1. 强引用 概述 在Java程序中,强引用是最常见的也是默认的.n ...

  10. C# npoi追加写入时报错 因为文件格式或文件扩展名无效。

    造成原因:workbook对象打开后,没有手动close造成的. 使用的npoi版本:2.6.0 ,环境 win10 .net core 5.0