本文章学习STM32HAL库通过定时器pwm模式生成pwm波,实现呼吸灯功能,并通过逻辑分析仪观察波形,并设计超声波模块测距方案。
文章目录
一、预备知识
(1)定时器原理
STM32的定时器是一种非常常见且重要的外设,它可以用来生成精确的时间间隔,以及控制各种信号的产生和采集。STM32F103系列的单片机提供了多个独立的16位和32位定时器,其中包括3个基本的16位定时器(TIM2-TIM4)和1个高级的16位定时器(TIM1),以及2个16位高级控制定时器(TIM8和TIM5)和2个通用32位定时器(TIM6和TIM7)。
定时器的原理是基于一个内部的计数器来实现,计数器在每个时钟周期自动增加一个单位,从而可以测量时间间隔。定时器的时钟源可以是内部的时钟源(如APB1和APB2时钟),也可以是外部的时钟源(例如TIM1和TIM8的ETR输入)。定时器还可以通过预分频器来降低时钟频率,从而可以实现更长的时间间隔。
定时器可以通过多种模式来实现不同的应用场景,如定时模式、计数模式、输入捕获模式等。定时模式和计数模式是最基本的模式,定时模式可用于生成精确的时间延迟,计数模式可用于计算频率或计数信号的脉冲数。输入捕获模式可以捕获外部信号的电平信息,从而可以测量各种信号的时序和周期.
(2)通用定时器(TIM2、TIM3、TIM4和TIM5)
通用TIMx (TIM2、TIM3、TIM4和TIM5)定时器功能包括:
● 16位向上、向下、向上/向下自动装载计数器
● 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65536之间的任意
数值
● 4个独立通道:
─ 输入捕获
─ 输出比较
─ PWM生成(边缘或中间对齐模式)
─ 单脉冲模式输出
● 使用外部信号控制定时器和定时器互连的同步电路
● 如下事件发生时产生中断/DMA:
─ 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
─ 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
─ 输入捕获
─ 输出比较
● 支持针对定位的增量(正交)编码器和霍尔传感器电路
● 触发输入作为外部时钟或者按周期的电流管理
(3)什么是PWM波
脉冲宽度调制(PWM),简单来说就是调节信号周期内的占空比(高电平持续时间)来获得我们需要的波形。例如我们需要呼吸灯功能,用PWM波来实现就是在微小的时间周期(利用人眼视觉停留效果)内不断增加输出信号的占空比,也就是电压的大小来控制灯的亮度,达到呼吸灯的效果。
PWM的频率:
是指在1秒钟内,信号从高电平到低电平再回到高电平的次数,也就是说一秒钟PWM有多少个周期,单位Hz。
PWM的周期:
T=1/f,T是周期,f是频率。
如果频率为50Hz ,也就是说一个周期是20ms,那么一秒钟就有 50次PWM周期。
占空比:
是一个脉冲周期内,高电平的时间与整个周期时间的比例
例如下图(占空比不断增大):
二、CubeMX创建工程
关于CubeMX创建新工程的方法,在前面的博客中有详细提及,下面介绍相关配置:
1.开启外部高速时钟:
2.TIM3 CH2通道开启
TIM2 CH1通道开启
.打开串口usart1
3.设置计数器值和预分频值(PSC)
4.时钟源配置
5.生成工程
三、代码编写
(1)HAL库TIM相关函数
HAL_TIM_PWM_Start(&htimx,TIM_CHANNEL_x)
开启定时器PWM输出
__HAL_TIM_SetCompare(&htimx,TIM_CHANNEL_x,pwmVal)
设置PWM波的占空比为pwmVal(自定)
TIM_RESET_CAPTUREPOLARITY(&htimx,TIM_CHANNEL_x)
输入捕获清除原先捕获模式
HAL_TIM_IC_Start_IT(&htimx, TIM_CHANNEL_x);
启动输入捕获
HAL_TIM_SET_CAPTUREPOLARITY(&htimx,TIM_CHANNEL_x,TIM_ICPOLARITY_FALLING//RISING)
设置捕获上升沿或者下降沿
HAL_TIM_ReadCapturedValue(&htimx,TIM_CHANNEL_x);
获取当前捕获值
HAL_TIM_IC_Stop_IT(&htimx,TIM_CHANNEL_x);
停止捕获
HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
输入捕获中断函数
(2)参数定义
uint16_t pwmVal = 500; //占空比
uint32_t capture_Buf[3] = {0}; //存放计数值
uint8_t capture_Cnt = 0; //状态标志位
uint32_t high_time; //高电平时间
(3)呼吸灯效果
通过不断改变占空比实现:
while(pwmVal)
{
pwmVal-=5;
__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,pwmVal);
HAL_Delay(10);
}
while(pwmVal<500)
{
pwmVal-=5;
__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,pwmVal);
HAL_Delay(10);
}
(4)输入捕获
主函数中:
case 0:
capture_Cnt++;
TIM_RESET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1);
__HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_1, TIM_ICPOLARITY_RISING);
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); //启动输入捕获
break;
case 3:
high_time = capture_Buf[1]- capture_Buf[0]; //高电平时间
printf ( "高电平时间 :%d us\n",high_time);
// HAL_UART_Transmit(&huart1, (uint8_t *)high_time, 1, 0xffff); //发送高电平时间
capture_Cnt = 0; //清空标志位
HAL_Delay(10);
break;
捕获中断函数:
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//输入捕获中断函数
{
if(htim->Instance == TIM2)//是否是定时器2触发中断
{
switch(capture_Cnt){
case 1:
capture_Buf[0] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//获取当前的捕获值.
TIM_RESET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1);//清空状态
__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING); //设置为下降沿捕获
capture_Cnt++;
break;
case 2:
capture_Buf[1] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//获取当前的捕获值.
HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_1); //停止捕获
capture_Cnt++;
}
}
}
四、仿真波形
可以看见高电平时间即(占空比)逐渐减小的过程
五、板级验证
呼吸灯效果:
输入捕获效果:
六、HC-SR04超声波测距模块
(1)HC-SR04测距原理
外部 MCU 给模块 Trig 脚一个大于 10uS 的高电平脉冲;模块会给出一个与距离等比的高电平脉冲信号,可根据脉宽时间“T”算出:
距离=T*C/2 (C 为声速)
声速温度公式:c=(331.45+0.61t/℃)m•s-1 (其中 330.45 是在 0℃)
0℃声速: 330.45M/S
20℃声速: 342.62M/S
40℃声速: 354.85M/S
(2)使用STM32实现测距方案
通过本次定时器的学习,
在实现HC-SR04的超声波模块测距我们可以用到定时器的PWM输出功能和输入捕获功能:
一方面,trig信号通过调节PWM波的占空比来输出;
另一方面,输入捕获模块返回的回响信号,记录高电平时间;随后计算,向串口打印输出。
主函数代码编写:
__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,10);//10us trig信号输入
case 0:
capture_Cnt++;
TIM_RESET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1);
__HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_1, TIM_ICPOLARITY_RISING);
HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1); //启动输入捕获
break;
case 3:
high_time = capture_Buf[1]- capture_Buf[0]; //高电平时间
printf ( "高电平时间 :%d us\n",high_time);
capture_Cnt = 0; //清空标志位
HAL_Delay(10);
break;
配合定时器捕获中断函数,实现测距功能。
七、总结
本次实验,通过定时器来输出PWM波和实现输入捕获。在实现输入捕获功能时,由于在捕获到相应信号时,由于没有清除原始捕获状态,导致功能不能完全实现。避免下次踩雷。