[蓝桥杯嵌入式有手就行]10_TIM(上)

[蓝桥杯嵌入式有手就行]系列文章

第一章 开发环境的配置
第二章 从点灯开始
第三章 学会看手册
第四章 GPIO(上)
第五章 GPIO(下)
第六章 LCD
第七章 串口
第八章 I2C
第九章 ADC
第十章 TIM(上)
第十一章 TIM(下)
第十二章 RTC
第十三章 14届模拟题1
第十四章 14届模拟题2
第十五章 14届真题解析
未完待续…



前言

注:本系列基于2023年蓝桥杯实战情况就行编写,所有软件均采用2023年赛点资源包
其实定时器本质上应该属于一种特殊的计数器,其本质是按照特定的频率和计数方式进行计数,当计数值达到预设值的时候就会产生一个事件触发中断或者DMA请求。
因为定时器部分内容较多,因此本章节只讨论输出部分。因方波也是一种特殊的pwm波,因此下文中主要以pwm波为主。


一、内部结构

1、分类

在这里插入图片描述
在这里插入图片描述
这边需要注意只有定时器2是32位的。
关于计数方式,可以分为中心计数,向上计数和向下计数三种。在手册里已经给出了示意图。
在这里插入图片描述
注意:图中的RCR寄存器(重复次数寄存器)是高级定时器才有的,对于其他类型的定时器,我们认为其就是这种情况

2、框图

在这里插入图片描述
看不清的话可以去参考手册28.3.1节查询。图中粉色荧光笔部分为输入捕获,放入下一节中讲述。
在这里插入图片描述
这个是通用定时器
在这里插入图片描述
这个是基本定时器。其中CK_CNT=CK_PSC/(PSC[15:0]+1)。
注意:PSC和ARR寄存器的框下面有阴影,表示存在影子寄存器,只有当更新事件发生的时候,重装载寄存器的值才会传递到影子寄存器,影子寄存器才是真正起作用的寄存器

其实高级定时器-刹车部分=通用定时器通用定时器-中间荧光笔标记的部分=基本定时器。因此本文直接用高级定时器做分析。

二、定时器输出的原理

1、计数(基本定时器)

1、过程

我们看上面基本定时器的结构图,可以发现来自APB总线的时钟信号进入了定时器的触发控制器,每来一个时钟信号,计数器加一,然后计数器的值来到了下方的预分频器,输出分频后的计数值进入 CNT counter即计数器。而计数器上方是自动重装载寄存器,当CNT内的值与ARR内的值相等的时候,就会触发更新事件,停止计数,并清空CNT。以此往复,便实现了定时的功能。

2、举例

这里以定时器6定时1s举例。
我一般使用100M主频,因此APB1总线上的频率为100Mhz。查阅手册得知(不会的去看第三节中的时钟树),定时器6挂载在APB1总线上,因此输入定时器的时钟信号也就为100M。
通过手册我们可以知道,定时器6是一个16位的向上计数的定时器,一秒将产生100M个事件,也就是ARR寄存器至少要27位才能装下,但是显然不可能做到。因此,我们需要预分频,预分频寄存器也是16位的。也就是说,我最多可以计2^32个数了,满足要求了。那么接下来对于PSC和ARR两个寄存器的值我们就需要好好考虑一下了(尤其是在资源受限的条件下,我们不可能一个定时器只用一个引脚)。

PSC*ARR计数间隔
65534*1525655us
39999*2499400us
19999*4999200us
9999*9999100us
4999*1999950us
2499*3999925us
1525*6553415us

至于为什么PSC和ARR不是整数,请看第一个问题
通过计算,我们可以发现在当前主频下,我们计数间隔(产生事件的间隔)在15~655us间,我们最长只能计时42.9s。但是这个时候的间隔为655us,将导致之后调用这个定时器的时候很难实现精确的定时,甚至整个1s也是有偏差的。相对来说上图标注的两个值比较合理,也方便后期计算时间。

2、PWM波输出

在上面的基础上,我们需要引入两个概念,分别是占空比和周期。

1、名词解释

周期:PWM波可以认为是由一段又一段重复的波形组成的,而每段波持续的时间就是周期,上一节中我们实现的1s定时,周期为1s。也就是通过改变ARR寄存器的值调节周期(一般情况下我们程序运行过程中修改频率是一件很危险的事,当然也有例外,看下方问题区)。
务必注意:一个定时器共用一个PSC和ARR寄存器,也就是各个通道的计数的时间间隔是一样的,我们只能通过CCR寄存器来调整各个通道的输出周期
占空比:在一个周期内有效电平(一般我们认为高电平有效)持续时间占总周期的比值。

2、举例

在程序中,假设我们需要输出一个1hz高电平有效30%占空比的PWM波。我们通过预分频,将计数频率降低到10000hz,此时我们数10000个数就是1s。而当计数器数到3000的时候,就会翻转电平,这样我们就获得了想要的PWM波。

根据傅里叶变换,方波是由基波和无数个奇次谐波组成。而方波正是一种特殊的PWM波,也就是说,理论上我们产生PWM波后,就可以通过多个PWM波来合成我们所需要的任意的波形了。

3、输出比较

输出比较一共可以分为5种模式,区别如下

模式说明
冻结模式作为普通定时器使用
比较输出模式1匹配时输出有效/无效电平模式
比较输出模式2也叫电平翻转模式,方波输出
强制输出模式强制为无效/有效电平模式
PWM模式PWM1和PWM2

关于PWM1和PWM2的区别
一般我们都使用PWM1模式,简单的说就是当cnt回到初始值后,在到达ccr设定的值之前为有效电平的就是PWM1,否则就是PWM2。

三、代码示例(基本定时器)

1、cubemx配置

在这里插入图片描述
在这里插入图片描述

2、上代码(流水灯)

记得在开始的时候开启定时器6的中断。

void HAL_Tim_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  static uint16_t counter = 0;
  static uint16_t led = 0x0001, i = 0, dir = 0;

  if (++counter == 100)
  {
    counter = 0;
    GPIOD->BSRR |= 0x0004;          // PD2置1
    GPIOC->ODR = ~(led << (8 + i)); // pc8~15输出反相的led
    __nop();                        // delay一个cpu时钟周期
    GPIOD->BRR |= 0x0004;           // PD2置0
    
    if (dir == 0)
    {
      if (++i == 7)
        dir = 1;
    }
    else
    {
      if (--i == 0)
        dir = 0;
    }
  }
  HAL_TIM_Base_Start_IT(&htim6);
}

四、代码示例(高级定时器)

1、cubemx配置

在这里插入图片描述
在这里插入图片描述

2、上代码

按需组合使用下面几行代码就可以

  TIM3->PSC=99;//AHB clock prescaler/100
  TIM3->ARR=999;//auto reload register
  TIM3->CCR2=500;//compare capture register,duty=CCR2/ARR=50%
  HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);//start pwm
  HAL_Delay(1000)
  HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_2);//stop pwm

五、问题

1、注意点

1、PSC和ARR寄存器的值为什么最后一位常常是9

务必注意这个寄存器值为0时,实际是1。也就是如果我们需要100分频,PSC的值应该设置成100-1即99。ARR同理。

2、既然周期是由PSC和ARR寄存器共同决定的,我们能不能调节PSC寄存器来改变周期

一般情况下,我们习惯调整ARR寄存器的值来改变周期,因为相对计算简单,就像上面100M主频,PSC=10000的情况下,每次CNT+1需要经过0.1ms,我想要1hz,只需要ARR=10000,想要10hz,只需要ARR=1000。
但是,就是14届比赛的时候,碰到一个很神奇的东西。题目要求pwm波以不超过200hz的变化幅度在规定时间内变换至指定周期,占空比还不能变。这个时候你会发现占空比是CCR和ARR的比值,ARR变了,CCR的值就要重算,虽然就是多一行程序,但是实际上示波器测量发现占空比还是有波动的。这个时候,我们调整PSC相对来说就容易的多了。
那么怎么选择呢,很简单,记住一句话改周期就改ARR,改频率就改PSC

总结

定时器部分我个人偏向于寄存器编程,因为只需要记住9个字母(PSC、ARR、CCR)就可以完成大部分功能的编写,比又臭又长的hal库函数好记多了,重点是keil调试的时候是可以直接查看这三个寄存器的值的,这极大的方便了找bug。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

工具人呵呵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值