当前位置: 首页 > news >正文

单片机-STM32部分:9、定时器

飞书文档https://x509p6c8to.feishu.cn/wiki/A749wx8T0ioqfgkzZKlc9poknUf

SMT32F1系列共有8个定时器:

  • 基本定时器(TIM6TIM7
  • 通用定时器(TIM2TIM3TIM4TIM5
  • 高级定时器(TIM1TIM8

高级定时器(TIM1TIM8)的主要功能:

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

基本定时器功能(TIM6TIM7):

功能对比

定时器种类位数计数器模式捕获/比较通道互补输出特殊应用场景
高级定时器16向上,向下,中心对齐4定时计数,DAC/ADC时钟、PWM输出,输入捕获,输出比较,带可编程死区的互补输出
通用定时器16向上,向下,中心对齐4定时计数,DAC/ADC时钟、PWM输出,输入捕获,输出比较
基本定时器16向上0定时计数,DAC时钟

基本定时器框图说明

基础定时器只有定时功能,使用基础定时器进行定时的工作流程如下:
1、控制器除了控制定时器复位、使能、计数等功能之外,还可以用于触发DAC转换。
2、内部时钟信号CK_INT经过控制器后成为CK_PSC进入预分频器,CK_INT和CK_PSC在频率上相等
3、预分频器对CK_PSC时钟信号进行分频,输出 CK_CNT是分频后的时钟
4、计数器对时钟信号CK_CNT从0开始计数,自动重装载寄存器存储一个值。当计数器的值达到改值时就产生U事件,然后计数器归零又重新开始计数。
5、开启定时器全局中断和U事件中断后,在发生计数溢出时产生U事件中断,利用中断进行定时处理。

定时器配置的一些参数

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

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

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

Counter Mode : 定时器的计数方式,基本定时器只能向上(UP)计数

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

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

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

InternalCLock Division(CKD): 内部时钟分频因子,指设置定时器时钟频率与数字滤波器使用的采样频率之间的分频比例的(与输入捕获相关)。

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

Disable:自动重装载寄存器写入新值后,计数器立即产生计数溢出,然后开始新的计数周期
Enable:自动重装载寄存器写入新值后,计数器完成当前旧的计数后,再开始新的计数周期

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

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

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

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

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

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

基本定时器的使用:

创建工程,设置SWD调试,HSE时钟,系统时钟为72MHz

然后打开Timers配置TIM6,设置为Activated激活定时器

Activated:
激活TIM6,把前面的方框选中局表示激活了TIM6

One Pulse Mode
只会计数到预设的值时产生一个脉冲输出信号,而不是周期性的信号输出。产生一个脉冲信号后,然后计数器会停止计数。这种模式通常用于需要生成单个脉冲信号的应用场景,例如PWM控制、测量脉冲宽度等。在STM32F103系列中,定时器的One Pulse Mode可以通过设置TIM_CR1寄存器中的OPM位来实现。


 

然后如何设置定时器的定时时间呢?首先我们要知道定时器的时钟来自哪里?

从芯片手册的时钟树中可以知道,STM32F103定时器的时钟源:

TIM1、TIM8:来自APB2总线上的TIMxCLK

TIM2到TIM7:来自APB1总线上的TIMxCLK

所以TIM6的APB1时钟是72MHz。

Counter Setting:计数设置
Prescaler(PSC -16 bits value):预分频器
简写PSC,16位,可设置的值范围是0--65535。在STM32F103中,计数器的时钟源可以是内部时钟源或外部时钟源。当使用内部时钟源时,PSC可以将时钟信号频率除以一个固定的分频系数,以降低计数器的时钟频率,从而扩大计数器的计时范围。
例如,如果使用内部时钟源,并将PSC设置为7199,
则定时器的时钟频率将为72 MHz / (7199 + 1) = 10 kHz。
这意味着计数器每计数10次,就会过去1毫秒。如果需要更长的计时范围,可以将PSC设置为更大的值。

Counter Mode计数模式
基本定时器TIM6只能向上计数(UP)。

Counter Period(Auto Reload Register - 16 bit value):计数周期
Auto Reload寄存器用于设置定时器的计数周期。当定时器的计数器达到ARR的值时,定时器会自动重新加载ARR的值并继续计数。这样可以实现定时器的周期性计数,从而实现定时和计时的功能。

Auto-Reload Preload:自动重载预装载使能。
自动重载预装载功能是用来控制定时器计数器的自动重装载和预装载的。

Trigger Output(TRGO)Parameter:触发器输出参数
当一个定时器的计数器计数到预设值时,就会产生一个触发输出,可以将该输出信号连接到其他定时器或外设的启动输入端,以实现多个定时器或外设同步工作(如:定时器更新产生TRGO信号来触发ADC的同步转换)。

TIM_TRGO_RESET-复位 – 使用TIMx_EGR寄存器的UG位作为触发输出(TRGO)。例如:溢出时会设置UG为1,计数器重新从0开始计数。
TIM_TRGO_ENABLE-使能 – 计数器使能信号CNT_EN被用作为触发输出(TRGO)。例如:可用于在同一时刻启动多个定时器,或控制使能从定时器的时机。
TIM_TRGO_UPDATE-更新 – 更新事件被用作为触发输出(TRGO),例如:事件用于触发ADC的同步转换。

如果想要使其50ms触发一次定时中断,可以把72MHz通过7200分频后,使其速度降为10KHz,也就意味着每计数10次需要1ms,那么50ms就需要计数500次。因为是从0为第一位开始计数,所以参数都需要减一。

72000000Hz/7200 = 10000Hz = 10KHz = 1s 10000次 = 1ms 10次

也可以通过公式计算
Tout= ((PSC+1)*(Period+1))/Tclk
Tclk:TIM的输入时钟频率(单位为hz)。
Tout:TIM的溢出时间(单位为s)。
PSC: 分频 7199
Period:计数周期 499
50ms=0.05s=((7200)*(500))/72000000Hz

然后设置定时器中断

关于中断优先级,在实际工程项目中,根据具体业务需要,当中断过多时,才需要设置中断优先级,测试工程无需设置。

同时,为了方便查看效果,添加LPA6为LED1

点击生成代码

main.c
void MX_TIM6_Init(void)
{TIM_MasterConfigTypeDef sMasterConfig = {0};htim6.Instance = TIM6;htim6.Init.Prescaler = 7200-1;htim6.Init.CounterMode = TIM_COUNTERMODE_UP;htim6.Init.Period = 500-1;htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;if (HAL_TIM_Base_Init(&htim6) != HAL_OK){Error_Handler();}sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK){Error_Handler();}
}stm32f1xx_it.c
/*** @brief This function handles TIM6 global interrupt.*/
void TIM6_IRQHandler(void)
{HAL_TIM_IRQHandler(&htim6);
}进入HAL_TIM_IRQHandler(&htim6)函数,这里面的代码很长,就是不同的中断类型,进入不同的中断回调函数,这里找到HAL_TIM_PeriodElapsedCallback(htim);
进入这个回调函数,我们看到是个虚函数,需要我们重写,在main.c中添加。
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){  if(htim == &htim6)  //判断中断是否来自于定时器6{//do something//例如:HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);  //翻转LED灯的状态//可以把500-1改为5000-1设置500ms的定时中断}
}最后,需要启动定时器,需要在main函数里使能中断/* USER CODE BEGIN 2 */HAL_TIM_Base_Start_IT(&htim6);/* USER CODE END 2 */

同理,其它定时器的定时器中断可以通过同样的方式设置

记得设置完参数后,打开中断哦,否则将不会产生中断。

基本定时器

高级定时器

然后代码中也要手动启动定时器

  main.c/* USER CODE BEGIN 2 */HAL_TIM_Base_Start_IT(&htim6)/* USER CODE END 2 */

相关文章:

  • ui生成提示词
  • pm2 list查询服务时如何通过name或者namespace进行区分
  • 笔试专题(十六)
  • 电力电子simulink练习09:复合控制_闭环控制与开环控制结合
  • 高频交直流传感技术在射频器件与微系统测试中的创新实践
  • Windows命令行软件管理器:Chocolatey
  • CH32V208GBU6沁恒绑定配对获取静态地址
  • 【日撸 Java 三百行】Day 6(For语句)
  • python里面的class,类,方法,函数,def
  • 第一次被AI指点出文章的问题
  • 5月8号.
  • 精读计算机体系结构基础 第一章 引言
  • 3.2.3 掌握RDD转换算子 - 4. 按键归约算子 - reduceByKey()
  • C++复习类与对象基础
  • 《信息论与编码课程笔记》——信源编码(1)
  • chili调试笔记14 画线 页面布置 线条导出dxf
  • linux nginx配置访问目录,访问文件直接下载,linux配置nginx直链下载
  • UVa1065/LA3809 Raising the Roof
  • 将通过qDebug、qWarning等输出的信息保存到日志文件中
  • 用递归实现各种排列
  • 习近平会见委内瑞拉总统马杜罗
  • 山东14家城商行中,仅剩枣庄银行年营业收入不足10亿
  • 上海杨浦:优秀“博主”购房最高可获200万补贴
  • 泽连斯基称与特朗普通话讨论停火事宜
  • 高盛上调A股未来12个月目标点位,沪深300指数潜在回报15%
  • 华为招聘:未与任何第三方开展过任何形式的实习合作