文章目录
一.概要
定时器的简介
定时器就是计数器,应用在我们生活的方方面面,比如有闹钟、计时器等。在STM32F407VET6定时器分为3类,即高级控制定时器(TIM1,TIM8)、通用定时器(TIM2,TIM3,TIM4,TIM5,TIM9,TIM10,TIM11,TIM12,TIM13,TIM14),基本定时器(TIM6,TIM7),要学会定时器要懂得分频设置、计数器设置。
1、高级控制定时器
高级控制定时器由一个16位的自动装载计数器组成,它由一个可编程的预分频器驱动。它适合多种用途,包含测量输入信号的脉冲宽度(输入捕获),或者产生输出波形(输出比较、PWM、嵌入死区时间的互补PWM等)。使用定时器预分频器和RCC时钟控制预分频器,可以实现脉冲宽度和波形周期从几个微秒到几个毫秒的调节。高级控制定时器(TIM1)和通用定时器(TIM2,TIM3,TIM4)是完全独立的,它们不共享任何资源。它们可以同步操作
2、通用定时器
通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成。它适用于多种场合,包括测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)。使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。每个定时器都是完全独立的,没有互相共享任何资源。它们可以一起同步操作。
3、基本定时器
基本定时器 包含一个 16 位自动重载计数器,该计数器由可编程预分频器驱动。此类定时器不仅可用作通用定时器以生成时基,还可以专门用于驱动数模转换器 (DAC) 。此类定时器内部连接到 DAC 并能够通过其触发输出驱动 DAC 。
我们以通用定时器为例,通用定时器能应付我们一般使用场景,后面对定时器的内部构造,配置使用,实际使用进行一一讲解
二.通用定时器内部结构
通用定时器由4部分组成:①时基单元 ②时钟源 ③输入捕获 ④输出比较。
1.时基单元
可编程通用定时器的主要部分是一个16位计数器和与其相关的自动装载寄存器。这个计数器可以向上计数、向下计数或者向上向下双向计数。此计数器时钟由预分频器分频得到。 计数器、自动装载寄存器和预分频器寄存器可以由软件读写,在计数器运行时仍可以读写。
时基单元包含:
● 计数器寄存器(TIMx_CNT) :向上计数、向下计数或者中心对齐向计数,最常用是向上对齐。
● 预分频器寄存器 (TIMx_PSC) :可将时钟频率按1到65536之间的任意值进行分频,可在运行时改变其设置值。
● 自动装载寄存器 (TIMx_ARR) :
在向上计数模式中,计数器(TIMx_CNT)从0计数到自动装载寄存器值(TIMx_ARR计数器的内容),然后重新从0开始计数并且产生一个计数器溢出事件。
ARPE=0,当ARR值被修改时,同时马上更新影子寄存器的值;ARPE=1,当ARR值被修改时,必须在下一次事件UEV发生后才能更新影子寄存器的值,当计数器产生溢出条件时,产生更新事件。
自动装载寄存器是预先装载的,写或读自动重装载寄存器将访问预装载寄存器。根据在
TIMx_CR1寄存器中的自动装载预装载使能位(ARPE)的设置,预装载寄存器的内容被立即或在每次的更新事件UEV时传送到影子寄存器。当计数器达到溢出条件(向下计数时的下溢条件),产生更新事件。
上图中圈出来带了阴影的寄存器表示该寄存器存在影子寄存器,这些有阴影的寄存器在物理上对应了两个寄存器,一个是开放出来给程序员可以写入和读出的预装载寄存器(preloadregister),比如ARR,PSC,捕获/比较等寄存器;另一个并没有开放出来,即程序员看不见的、但在操作中真正起作用的影子寄存器(shadowregister)。
设计预装载寄存器 (preloadregister) 和影子寄存器 (shadowregister)的好处:
每次发生更新事件(UEV)时,所有真正起作用的影子寄存器(shadowregister)可以同时被更新为预装载寄存器 (preloadregister)里面的值,这样可以保证多个通道的操作能够准确同步;如果没有影子寄存器(shadowregister),或者预装载寄存器 (preloadregister) 和影子寄存器 (shadowregister)是直通的,当软件更新了预装载寄存器 (preloadregister),也就立即更新了影子寄存器 (shadowregister),由于软件不能同时更新多个影子寄存器,这就会导致多个通道的时序不能同步。
ARPE=0,当ARR值被修改时,同时马上更新影子寄存器的值;
ARPE=1,当ARR值被修改时,必须在下一次事件UEV发生后才能更新影子寄存器的值
ARR寄存器工作模式如下:
2.时钟源
计数器时钟可由下列时钟源提供:
① 内部时钟 (TIMxCLK)
② 外部时钟模式 1 :外部输入脚 (TIx)
③ 外部时钟模式 2 :外部触发输入 (ETR)
④ 内部触发输入 (ITRx) :使用一个定时器作为另一个定时器的预分频器,如可以配置一个定时器 Timer1 而作为另一个定时器 Timer2 的预分频器。
我们常用内部时钟 (TIMxCLK)作为时钟源
3.输入捕获
输入捕获就是通过检测捕获通道上(TI1,TI2,TI3,TI4)的边沿信号。在边沿信号发生跳变(比如上升沿/下降沿)的时候,将当前定时器的值(TIMx_CNT)存放到对应的通道的捕获/比较寄存器(TIMx_CCR)里面,完成一次捕获,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数。
4.输出比较
输出比较可以通过比较CNT(计数器)与CCR(捕获/比较)寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形。
三.通用定时器内部特色
四.CubeMX配置一个TIME定时1ms中断例程
1.硬件准备
STLINK接STM32F407VET6开发板,STLINK接电脑USB口。
2.创建工程
打开STM32CubeMX软件,新建工程
Part Number处输入STM32F407VE,再双击就创建新的工程
配置下载口引脚
配置外部晶振引脚
可以查看STM32F407VET6开发板原理图,PB4连接LED灯,所以配置PB4为GPIO输出
配置系统主频168Mhz,使用外部晶振
配置TIM3通用定时器,1ms溢出中断事件
TIM3内部时钟APB1 Time Clocks是84MHZ,84分频就是1MHZ,计数1000次中断一次,计数时间就是1ms。
配置中断
配置工程文件名,保存路径,KEIL5工程输出方式
生成工程
用Keil5打开工程
3.添加代码和调试
main中添加代码,启动定时器3,并启动中断。
添加HAL_TIM_PeriodElapsedCallback函数,这个函数会在定时器1ms中断产生的时候在中断服务程序中自动调用。我们在里面增加计数到500次,那就是500ms时LED翻转输出,这样LED灯就是闪烁。
进入调试模式,在HAL_TIM_PeriodElapsedCallback函数中打断点,全速运行,每500ms,就会进入断点一次,调试就完成了。
4.主要代码
uint16_t TimeCounter;
//定时器溢出中断回调函数,1ms进入一次
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* Prevent unused argument(s) compilation warning */
TimeCounter++;
if(TimeCounter>=500)//计数到500ms
{
TimeCounter=0;
HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_4);//LED闪烁
}
/* NOTE : This function should not be modified, when the callback is needed,
the HAL_TIM_PeriodElapsedCallback could be implemented in the user file
*/
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
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();//8M外部晶振,168M主频
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM3_Init();//1ms中断,注意查看芯片手册,TIM3主频最高84M
/* USER CODE BEGIN 2 */
if (HAL_TIM_Base_Start_IT(&htim3) != HAL_OK)//启动TIM3,使能中断,这样1ms就能产生中断一次
{
while(1);
}
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
五.CubeMX工程源代码下载
通过网盘分享的文件:6.定时器1ms中断.zip
链接: https://pan.baidu.com/s/107D-w6mwGwdWkx7joK0Yag 提取码: 6vp2
如果链接失效,可以联系博主给最新链接
程序下载下来之后解压就行
六.小结
通过定时器周期性地产生中断信号,可以实现系统定时和时间戳等功能。例如,在智能家居系统中,可以使用定时器控制各种设备的开关,在工业控制系统中,定时器可以用于检测传感器数据并执行相应的动作,定时器还可以配合PWM模块实现对电机等设备的精确控制。通过定时器产生固定频率的方波信号,然后使用PWM模块将其转化为可调节占空比的脉冲信号,从而实现对电机速度和输出功率的控制。