STM32定时器各种功能实验

前言

TIM定时器有很多种应用,这里挑五个比较典型的实验展示。

1.脉宽测量输入捕获实验

1.1 硬件设计

根据开发板引脚使用情况,我们选用通用定时器 TIM5 的 CH1, 就 PA0 这个 GPIO 来测量信号的脉宽。在开发板中 PA0 接的是一个按键,默认接 GND, 当按键按下的时候 IO口会被拉高,这个时候我们可以利用定时器的输入捕获功能来测量按键按下的这段高电平的时间,通过串口显示出来。按键的具体原理图见图,包含硬件消抖。
在这里插入图片描述

1.2 软件设计

编程要点:
(1) 定时器用到的 GPIO 初始化
(2) 定时器时基结构体 TIM_TimeBaseInitTypeDef 初始化
(3) 定时器输入捕获结构体 TIM_ICInitTypeDef 初始化
(4) 编写中断服务函数,读取捕获值, 计算出脉宽的时间
软件部分见如下链接工程(MDK5环境下)
链接: 嵌入式定时器应用之脉宽测量输入捕获实验.

2.PWM 输出

2.1 硬件设计

使用pwm输出达到部分点亮绿色led的效果,pwm输出最终引到pb0脚,低电平有效,输出pwm波为20Khz,占空比为94%。观察led亮暗程度,可知占空比越小,灯越亮。

2.2 软件设计

注意:定时器比较输出是不需要中断的
编程要点:
(1) 定时器用到的 GPIO 初始化
(2) 定时器时基结构体 TIM_TimeBaseInitTypeDef 初始化
(3) 定时器输入捕获结构体TIM_OCInitTypeDef初始化
软件部分见如下链接工程(MDK5环境下)
链接: 嵌入式定时器应用之输出pwm波形.

3.PWM 互补输出

3.1 硬件设计

输出比较模式比较多,这里我们以 PWM 输出为例讲解,并通过示波器来观察波形。实验中不仅在主输出通道输出波形,还在互补通道输出与主通道互补的的波形,并且添加了断路和死区功能。
使用高级定时器TIM1 的通道 1 及其互补通道作为本实验的波形输出通道,对应选择 PA8 和 PB13 引脚。将示波器的两个输入通道分别与 PA8 和 PB13 引脚连接,用于观察波形,还有注意共地。 在指南者开发板里面, PA8 通过一个调帽默认连接了蜂鸣器, 如果调帽不拔掉的话, PA8 输出的 PWM 信号会让蜂鸣器响。
为增加断路功能,需要用到 TIM1_BKIN 引脚,这里选择 PB12 引脚。程序我们设置该引脚为高电平有效,当 BKIN 引脚被置高低电平的时候,两路互补的 PWM 输出就被停止,就好像是刹车一样。

3.2 软件设计

编程要点:
(1) 定时器用到的 GP IO 初始化
(2) 定时器时基结构体 TIM_TimeBaseInitTypeDef 初始化
(3) 定时器输出比较结构体 TIM_OCInitTypeDef 初始化
(4) 定时器刹车和死区结构体 TIM_BDTRInitTypeDef 初始化
软件部分见如下链接工程(MDK5环境下)
链接: 嵌入式定时器应用之PWM 互补输出实验.

4.PWM 输入

4.1 硬件设计

输入捕获的一个特例—PWM 输入。普通的输入捕获可以使用定时器的四个通道,一路捕获占用一个捕获寄存器,而 PWM 输入则只能使用两个通道,即通道 1 和通道 2, 且一路 PWM 输入要占用两个捕获寄存器,一个用于捕获周期,一个用于捕获占空比。

在本节实验中,我们用通用定时器产生一路 PWM 信号,然后用高级定时器的通道 1 或者通道 2 来捕获。

实验中用到两个引脚,一个是通用定时器 TIM3 的通道 1, 即 PA6, 用于输出PWM 信号,另一个是高级控制定时器 TIM1 的通道 1, 即 PA8, 用于 PWM 输入捕获,实验中直接用一根杜邦线短接即可 PA6 和 PA8 即可,同时可用示波器监控 PA6 的波形,看看实验捕获的数据是否正确。

4.2 软件设计

编程要点:
(1) 通用定时器产生 PWM 配置
(2) 高级定时器 PWM 输入配置
(3) 编写中断服务程序, 计算测量的频率和占空比,并打印出来比较
编程的要点主要分成两部分,一个是通用定时器的 PWM 信号输出, 另一个是 PWM信号输入捕获。
软件部分见如下链接工程(MDK5环境下)
链接: 嵌入式定时器输入捕获应用之捕获pwm.

4.电容按键检测

电容按键不需要任何外部机械部件,使用方便,成本低,很容易制成与周围环境相密封的键盘,以起到防潮防湿的作用。电容按键优势突出使得越来越多电子产品使用它代替传统的机械按键.

5.1 硬件设计

在这里插入图片描述

在电路板未上电时,可以认为电容 Cx 是没有电荷的,在上电时,在电阻作用下,电容 Cx 就会有一个充电过程,直到电容充满,即 Vc 电压值为 3.3V,这个充电过程的时间长短受到电阻 R 阻值和电容 Cx 容值的直接影响。
但是在我们选择合适电阻 R 并焊接固定到电路板上后,这个充电时间就基本上不会变了,因为此时电阻 R 已经是固定的,电容 Cx在无外界明显干扰情况下基本上也是保持不变的。

现在,我们来看看当我们用手指触摸时会是怎样一个情况?如图 ,当我们用手指触摸时,金属感应片除了与地信号形成一个等效电容 Cx 外,还会与手指形成一个 Cs 等效电容。

此时整个电容按键可以容纳的电荷数量就比没有手指触摸时要多了,可以看成是 Cx和 Cs 叠加的效果。在相同的电阻 R 情况下,因为电容容值增大了,导致需要更长的充电时间。也就是这个充电时间变长使得我们区分有无手指触摸,也就是电容按键是否被按下。
在这里插入图片描述

现在最主要的任务就是测量充电时间。充电过程可以看出是一个信号从低电平变成高电平的过程,现在就是要求出这个变化过程的时间。我们可以利用定时器输入捕获功能计算充电时间,即设置 TIMx_CH 为定时器输入捕获模式通道。这样先测量得到无触摸时的充电时间作为比较基准,然后再定时循环测量充电时间与无触摸时的充电时间作比较,如果超过一定的阈值就认为是有手指触摸。
图 为 Vc 跟随时间变化情况,可以看出在无触摸情况下,电压变化较快;而在有触摸时,总的电容量增大了,电压变化缓慢一些。

为测量充电时间,我们需要设置定时器输入捕获功能为上升沿触发, 图 中 VH 就是被触发上升沿的电压值,也是 STM32 认为是高电平的最低电压值,大约为 1.8V。 t1 和t2 可以通过定时器捕获/比较寄存器获取得到。
不过,在测量充电时间之前,我们必须想办法制作这个充电过程。之前的分析是在电路板上电时会有充电过程,现在我们要求在程序运行中循环检测按键,所以必须可以控制充电过程的生成。我们可以控制 TIMx_CH 引脚作为普通的 GPIO 使用,使其输出一小段时间的低电平,为电容 Cx 放电,即 Vc 为 0V。当我们重新配置 TIMx_CH 为输入捕获时电容Cx 在电阻 R 的作用下就可以产生充电过程。

5.1 软件设计

编程要点:
(1) 编写定时器输入捕获相关函数
(2) 测量电容按键空载的充电时间 T1
(3) 测量电容按键有手触摸的充电时间 T2
(4) 只需要比较 T2 与 T1 的时间即可检测出按键是否有手指触摸

软件部分见如下链接工程(MDK5环境下)
链接: 利用定时器输入捕获检测电容按键.

后记

这几个实验可以帮助我们理解STM32定时器的注意功能,即:
输入捕获
输出比较
断路功能

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以帮你解答这个问题。 首先,PWM(Pulse-Width Modulation)是一种调制技术,可以用来控制电路中的电压或电流。在呼吸灯实验中,我们可以使用 PWM 技术来控制 LED 的亮度,实现呼吸灯效果。 在 STM32 中,可以使用定时器模块来实现 PWM 功能。具体步骤如下: 1. 选择一个可用的定时器模块,并配置其时钟源和预分频器。 2. 配置定时器模块为 PWM 模式,并设置 PWM 的周期和占空比。 3. 配置定时器模块的输出通道,将其连接到 LED 灯的控制引脚上。 4. 启动定时器模块,开始 PWM 输出。 下面是一个简单的呼吸灯实验代码示例: ```c #include "stm32f10x.h" #define LED_PIN GPIO_Pin_13 #define LED_PORT GPIOC void delay(uint32_t ms) { uint32_t i; while (ms--) { for (i = 0; i < 1000; i++); } } void led_pwm_breath(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStructure; // 使能定时器时钟和 GPIO 时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // 配置 LED 控制引脚为推挽输出 GPIO_InitStructure.GPIO_Pin = LED_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LED_PORT, &GPIO_InitStructure); // 配置定时器基本参数 TIM_TimeBaseStructure.TIM_Period = 1000; TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); // 配置定时器输出通道为 PWM 模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 500; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM1, &TIM_OCInitStructure); // 启动定时器 TIM_Cmd(TIM1, ENABLE); while (1) { // 增加占空比 for (int i = 0; i <= 1000; i += 10) { TIM_SetCompare1(TIM1, i); delay(10); } // 减小占空比 for (int i = 1000; i >= 0; i -= 10) { TIM_SetCompare1(TIM1, i); delay(10); } } } int main(void) { led_pwm_breath(); return 0; } ``` 在上面的代码中,我们使用 TIM1 定时器模块来控制 LED 的亮度。首先,我们配置 TIM1 的时钟源和预分频器,使其时钟频率为 1MHz。然后,我们将 LED 控制引脚 PC13 配置为推挽输出模式,将其连接到 TIM1 的通道 1 上。 接着,我们配置 TIM1 的输出通道 1 为 PWM1 模式,并设置 PWM 的周期为 1000(即 1kHz),占空比为 50%。最后,我们启动 TIM1 定时器,并在一个无限循环中不断增加和减小 PWM 的占空比,实现呼吸灯效果。 希望这个例子对你有帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值