嵌入式学习五(PWM,输入捕获)
PWM,输入捕获
PWM
硬件配置
使用硬件PWM,通过定时器生成PWM波
1.首先确定自己需要输出的端口,然后找到其对应的定时器和通道
选择通道模式为PWM Generation,时钟选择为内部时钟
2.配置一些参数
a.预分频系数Prescaler,71,减少频率
b.计数模式,一般都使用向上计数
c.重装载值Arr,99
PWM频率的计算公式为:频率/(Prescaler+1)/(Arr+1)
3.其他一些参数
a.PWM输出模式

注意这里所说的高电平其实是有效电平,有效电平可以由CH Polarity设置!
b.脉冲值Pulse,决定占空比,duty=Pulse/(Arr+1)
c.CH Polarity,设为High就是高电平为有效值,设为Low就是低电平为有效值
d.CH Idle State 作用为决定当该通道不输出PWM波时,电平为高或低
函数编写(简易)
设置占空比
void pwm_set_duty(float Duty)
{
// 根据占空比计算捕获/比较寄存器的值
TIM2->CCR2 = (TIM2->ARR + 1) * (Duty / 100.0f);
}
设置频率
void pwm_set_frequency(int Frequency)
{
// 获取定时器的时钟频率(假设TIM2使用的时钟频率为TIM2_CLK)
uint32_t TIM2_CLK = 72000000; // 例如72MHz, 需要根据实际情况调整,这里的值为经过预分频后的时钟频率
// 根据输入的频率计算自动重装载寄存器的值
uint32_t ARR_Value = (TIM2_CLK / Frequency) - 1;
// 设置自动重装载寄存器
TIM2->ARR = ARR_Value;
// 更新捕获/比较寄存器CCR2,保持当前占空比不变
TIM2->CCR2 = (ARR_Value + 1) * (TIM2->CCR2 / (float)(TIM2->ARR + 1));
// 触发更新事件,刷新寄存器
TIM2->EGR = TIM_EGR_UG;
}
API介绍
HAL_TIM_PWM_Start()
启动函数,需要自己调用
HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t
Channel);
输入参数为定时器句柄和定时器通道
HAL_TIM_PWM_Stop()
HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t
Channel);
HAL_TIM_PWM_Start_IT()
HAL_TIM_PWM_Start_IT 函数⽤于启动指定定时器通道的PWM输出,并启⽤中断。
HAL_TIM_PWM_Stop_IT()
HAL_TIM_PWM_Stop_IT 函数⽤于停⽌指定定时器通道的PWM输出,并禁⽤中断.
输入捕获
基本原理
输⼊捕获是⼀种利⽤定时器外部输⼊信号触发定时器事件的功能。在STM32等微控制器中,定时器模块可以配置为在检测到输⼊信号的边沿(上升沿或下降沿)时,将当前定时器的计数值保存到捕获寄存器中,并触发中断或DMA请求。通过读取这些捕获值,可以计算输⼊信号的周期或脉宽
硬件框图

从硬件可以看出输入通道为PA15和PB4,那么就需要找到这两个端口对应的定时器比较通道
HAL库配置

Slave Mode设置为Reset Mode模式,Trigger Source 触发源设置为TI1FP1(这个就看那个端口对应的通道是哪个,就配置哪个通道就行了),Clock Source配置为内部时钟即可,在设置预分频系数和捕获的边沿
添加DMA进行读取
选择DMA通道
设置模式为循环读取模式
字宽设置为一个字宽
底层函数编写
首先需要初始化
HAL_TIM_IC_Start_DMA(&htim3,TIM_CHANNEL_1,tim_ic_buffer,64);
uint32_t tim_ic_buffer[64];// 定义存储输入捕获值的缓冲区
然后是读取和计算频率的部分代码
/**
* @brief 处理输入捕获数据
*
* 此函数用于处理输入捕获数据。它计算tim_ic_buffer中所有捕获值的平均值,
* 然后将其转换为对应的频率值(单位为Hz),并存储在tim_ic_val中。
* 最后,调用limit_value函数对tim_ic_val进行限制,确保其在1到20000之间。
*/
void ic_proc(void)
{
tim_ic_temp = 0;
// 对缓冲区中的捕获值求和
for (int i = 0; i < 64; i++)
{
tim_ic_temp += tim_ic_buffer[i];
}
// 计算平均值
tim_ic_temp /= 64;
// 计算频率值,单位为Hz
tim_ic_val = (int)((float)(1000.0f * 1000.0f) / (float)tim_ic_temp);
// 将计算得到的频率值限制在1到20000之间
limit_value(&tim_ic_val, 1, 500, 20000);
}
完成!
openvela 操作系统专为 AIoT 领域量身定制,以轻量化、标准兼容、安全性和高度可扩展性为核心特点。openvela 以其卓越的技术优势,已成为众多物联网设备和 AI 硬件的技术首选,涵盖了智能手表、运动手环、智能音箱、耳机、智能家居设备以及机器人等多个领域。
更多推荐


所有评论(0)