STM32G474单片机开发入门(六)定时器TIMER详解及实战含源码
文章目录
- 一.概要
- 二.通用定时器内部结构
- 1.时基单元
- 2.时钟源
- 3.输入捕获
- 4.输出比较
- 三.通用定时器内部特色
- 四.CubeMX配置一个TIME1定时1ms中断例程
- 1.硬件准备
- 2.创建CubeMX工程
- 3.添加代码
- 4.主要代码
- 五.小结
一.概要
定时器的简介
定时器就是计数器,应用在我们生活的方方面面,比如有闹钟、计时器等。STM32G474RET6定时器分为3类,即高级控制定时器(TIM1,TIM8,TIM20)、通用定时器(TIM2,TIM3,TIM4,TIM5,TIM15,TIM16,TIM17),基本定时器(TIM6,TIM7),高精度定时器(HRTIM),低功耗定时器(LPTIM1)要学会定时器要懂得分频设置、计数器设置。
1、高级控制定时器
高级控制定时器由一个16位的自动装载计数器组成,它由一个可编程的预分频器驱动。它适合多种用途,包含测量输入信号的脉冲宽度(输入捕获),或者产生输出波形(输出比较、PWM、嵌入死区时间的互补PWM等)。使用定时器预分频器和RCC时钟控制预分频器,可以实现脉冲宽度和波形周期从几个微秒到几个毫秒的调节。高级控制定时器(TIM1,TIM8,TIM20)和通用定时器(TIM2,TIM3,TIM4等)是完全独立的,它们不共享任何资源。它们可以同步操作
2、通用定时器
通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成,也有32位的自动装载计数器(TIM2,TIM5),它适用于多种场合,包括测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)。使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。每个定时器都是完全独立的,没有互相共享任何资源。它们可以一起同步操作。
3、基本定时器
基本定时器 包含一个 16 位自动重载计数器,该计数器由可编程预分频器驱动。此类定时器不仅可用作通用定时器以生成时基,还可以专门用于驱动数模转换器 (DAC) 。此类定时器内部连接到 DAC 并能够通过其触发输出驱动 DAC 。
4、高精度定时器
STM32G474的HRTIM(高分辨率定时器)主要具有以下特点:分辨率与精度HRTIM具有184皮秒(ps)的分辨率,并针对电压和温度变化进行补偿,确保高精度定时控制,高达12 路PWM输出。
我们以通用定时器为例,通用定时器能应付我们一般使用场景,后面对定时器的内部构造,配置使用,实际使用进行一一讲解
二.通用定时器内部结构
通用定时器由4部分组成:①时基单元 ②时钟源 ③输入捕获 ④输出比较。
1.时基单元
可编程通用定时器的主要部分是一个16位计数器和与其相关的自动装载寄存器。这个计数器可以向上计数、向下计数或者向上向下双向计数。此计数器时钟由预分频器分频得到。 计数器、自动装载寄存器和预分频器寄存器可以由软件读写,在计数器运行时仍可以读写。
时基单元包含:
● 计数器寄存器(TIMx_CNT) :向上计数、向下计数或者中心对齐向计数,最常用是向上对齐。
● 预分频器寄存器 (TIMx_PSC) :可将时钟频率按1到65536之间的任意值进行分频,可在运行时改变其设置值。
● 自动装载寄存器 (TIMx_ARR) :
在向上计数模式中,计数器(TIMx_CNT)从0计数到自动装载寄存器值(TIMx_ARR计数器的内容),然后重新从0开始计数并且产生一个计数器溢出事件。
自动装载寄存器是预先装载的,写或读自动重装载寄存器将访问预装载寄存器。
通过以上3个寄存器,就能实现时间计时,比如我们单片机系统主频是170MHZ,我们分频给他分成170分频,那定时器时钟就是1MHZ,TIMx_CNT一般都是从0开始自动计数,假如我们想TIMx_CNT从0递增至999时溢出,产生中断,然后自动又从0开始计数,在产生溢出中断的时候,计数频率就是(170000000/170)/1000=1000HZ,周期就是1ms了,所以自动装载TIMx_ARR需赋值为999,分频TIMx_PSC为169,以上两个数就能产生1ms周期的时间中断。中断产生时候,比如定时器2,单片机就会1ms自动调用一次定时器中断服务程序TIM2_IRQHandler,我们可以在TIM2_IRQHandler里面添加我们需要的应用程序代码。
接下去介绍下影子寄存器
ARR,PSC,捕获/比较等寄存器在物理上对应了两个寄存器,一个是开放出来给程序员可以写入和读出的预装载寄存器(preloadregister),另一个并没有开放出来,即程序员看不见的、但在操作中真正起作用的影子寄存器(shadowregister),预加载寄存器为用户用来配置的寄存器(用户用来读写值),而影子寄存器是真正起作用的寄存器。
设计预装载寄存器 (preloadregister) 和影子寄存器 (shadowregister)的好处:
通过更新事件(UEV)触发机制,所有影子寄存器(如ARR、PSC、CCR)可同时从对应的预装载寄存器加载新值,确保多通道参数(如PWM频率和占空比)的修改严格同步,例如,修改ARR和CCR时,若ARPE/OCxPE=1,新值需等待更新事件后生效,避免因异步更新导致波形畸变。在电机驱动或LED调光等场景中,影子寄存器缓冲机制可防止参数修改时输出瞬时跳变,例如,PWM占空比更新时,新值仅在下一个周期生效,消除毛刺干扰。
ARPE=0,规定当ARR值被修改时,同时马上更新影子寄存器的值;
ARPE=1,规定当ARR值被修改时,必须在下一次事件UEV发生后才能更新影子寄存器的值
ARR寄存器工作模式如下:
如下图所示,就是ARPE为1,需要更新事件标志更新后,才更新影子寄存器。
2.时钟源
计数器时钟可由下列时钟源提供:
① 内部时钟 (tim_pclk)
② 外部时钟模式 2 :外部触发输入 (TIM_ETR)
③ 内部触发输入 (tim_itr[15:0]) :使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器 Timer1 而作为另一个定时器 Timer2 的预分频器。
我们常用内部时钟 (tim_pclk)作为时钟源,从APB时钟分频得到。
3.输入捕获
输入捕获就是通过检测捕获通道上(TI1,TI2,TI3,TI4)的边沿信号。在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCR)里面,完成一次捕获,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数。
4.输出比较
输出比较可以通过比较CNT(计数器)与CCR(捕获/比较)寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形。
三.通用定时器内部特色
STM32G474RET6的通用定时器(TIM2-TIM5、TIM15-TIM17)具有以下核心特色:
- 高精度与灵活配置
支持16位向上/向下/中央对齐计数模式,预分频器(PSC)可编程,时钟源可选内部或外部。
通过预分频器和自动重载寄存器(ARR)可实现微秒级至毫秒级的定时精度,例如配置170MHz主频时,预分频系数17000可将计数器时钟降至10kHz。 - 多功能PWM输出
支持独立通道的PWM生成,占空比通过比较寄存器(CCR)动态调整,适用于电机控制、LED调光等场景。
互补PWM输出需配合高精度定时器(HRTIM),但通用定时器仍可生成单通道PWM。 - 输入捕获与编码器接口
可测量外部信号脉宽或频率,通过捕获/比较寄存器记录边沿时间。
支持正交编码器接口,用于电机转速检测。 - 同步与级联能力
可通过外部时钟同步(ETR)或内部互联总线与其他定时器同步,实现复杂时序控制。
支持主从模式,从定时器可响应主定时器的触发事件。 - 低功耗与中断管理
在低功耗模式下仍可运行,配合DMA减少CPU干预。
提供更新中断、捕获/比较中断等事件,支持实时响应。 - 与其他外设协同
可触发ADC/DAC转换,实现定时采样或波形生成。
注:通用定时器功能虽不及高级定时器(如死区控制),但凭借灵活性和低资源占用,仍广泛应用于工业控制、传感器接口等场景
四.CubeMX配置一个TIME1定时1ms中断例程
1.硬件准备
STLINK接STM32G474RET6开发板,STLINK接电脑USB口。
2.创建CubeMX工程
如下图所示,打开STM32CubeMX软件,新建工程。
如下图所示,Part Number处输入STM32G474RE,再双击就创建新的工程。
如下图所示,配置下载口引脚,PA13为SWD的SWDIO脚,PA14为SWD的SWCLK脚。
如下图所示,PC8配置成推挽输出,用来驱动LED灯闪烁。
如下图所示,配置定时器溢出中断周期为1ms。
定时器1溢出中断使能。
如下图所示,配置系统主频170Mhz,使用内部16MHZ晶振。
配置工程文件名,保存路径,KEIL5工程输出方式,生成工程。
3.添加代码
用Keil5打开工程,main中添加代码,启动定时器1,并启动中断。
如下图所示,在中断服务程序文件stm32g4xx_it.c中,修改定时器1溢出中断服务程序void TIM1_UP_TIM16_IRQHandler(void),在定时器1ms中断产生的时候,单片机会自动调用这个函数。我们在里面增加计数到500次,那就是500ms时LED翻转输出,这样LED灯就会闪烁了。
4.主要代码
void TIM1_UP_TIM16_IRQHandler(void)
{/* USER CODE BEGIN TIM1_UP_TIM16_IRQn 0 *//* USER CODE END TIM1_UP_TIM16_IRQn 0 */HAL_TIM_IRQHandler(&htim1);/* USER CODE BEGIN TIM1_UP_TIM16_IRQn 1 */TimeCounter++;//计数加1if(TimeCounter>=500)//到500ms{TimeCounter=0;HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_8);//PC8引脚翻转输出}/* USER CODE END TIM1_UP_TIM16_IRQn 1 */
}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();//SysTick配置成1ms中断/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();//内部16MHZ晶振,170MHZ系统主频/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();//PC8配置成推挽输出MX_TIM1_Init();//定时器1使能,产生中断时间为1ms/* USER CODE BEGIN 2 */HAL_TIM_Base_Start_IT(&htim1);//开启定时器1,并使能定时器1的溢出中断,中断产生会调用void TIM1_UP_TIM16_IRQHandler(void)中断服务函数/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */HAL_Delay(100);//等待100ms,这个可以不加}/* USER CODE END 3 */
}
五.小结
学会定时器周期时间的配置,通过定时器周期性地产生中断信号,可以实现系统定时和时间戳等功能。例如,在智能家居系统中,可以使用定时器控制各种设备的开关,在工业控制系统中,定时器可以用于检测传感器数据并执行相应的动作,定时器还可以配合PWM模块实现对电机等设备的精确控制。通过定时器产生固定频率的方波信号,然后使用PWM模块将其转化为可调节占空比的脉冲信号,从而实现对电机速度和输出功率的控制。