目的测量PWM的频率和占空比,通过串口调试助手打印出来
方法一:用定时器的PWM输入模式,采用一个定时器的两个通道(通道一和通道二),配置从模式为复位模式,没有进行溢出处理,所以需要考虑捕获的最低频率;
因为需要测量一个PWM信号,那么首先需要先产生一个PWM信号,这里我用TIM4_CH1(PD12)输出一个频率为50HZ,占空比为50%的PWM信号 然后参见定时器的内部框图可知,当从CH1输入一个PWM波,通过输入滤波后将会产生两路信号:tim_ti1fp1 & tim_ti1fp2,分别送至tim_ic1 & tim_ic2,也就是说一个TI信号将会被映射成两路的IC信号,所以可以通过进行边沿检测来测量PWM的频率以及占空比。
所以需要用到另外一个定时器的一个通道,此处选择TIM3_CH1(PA6) 1、设置定时器Slave Mode为Reset Mode,也就是当检测到上升沿时,定时器复位; 2、PWM由CH1进入,触发源设置为TI1FP1,并设置IC1为上升沿捕获; 3、当第一次捕获到上升沿时,定时器复位,计数寄存器CNT清零; 4、当IC2捕获到下降沿时,计数器CNT的值将会被存到捕获寄存器CCR2中; 5、当IC1再次捕获到上升沿时,计数器CNT的值将会被存到捕获寄存器CCR1中,同时将定时器复位; 6、开启TIM3的中断 因此,CCR1的值就是周期,CCR2的值就是占空比。
最终计算得到的频率值 = 分频后得到的时钟频率 / 上升沿个数 = ( 定时器时钟频率 / 预分频系数 )/ 上升沿个数 ; 最终计算的到的占空比 = 下降沿个数 / 上升沿个数; 值得注意的是:要明确输入PWM波的大致范围,因为需要根据PWM波范围来确定预分频系数;比如说输入一个频率大概为50Hz,占空比为10%的PWM波,需要将预分频系数稍微设置大一些;(这是因为:定时器所能测量到的最小频率 = 定时器频率 / ( 预分频系数 * 自动重载值 ),而因为ARR(Auto-Reload-Register)是一个十六位寄存器,其最大值为65536,所以当需要测量的频率值较小时,必须要将预分频系数设为较大值) 以本次使用定时器TIM3为例,其时钟频率已配置为84MHz,再配置PSC(Prescaler)为(8400-1),因此,最终频率 = ( 84000000 / 8400 )/ PWM_RisingCount;
由于需要用到串口,所以还需要配置USART1
三、编写代码 串口1重定义,在keil设置中勾选微库(use mircolib)
#include <stdio.h>
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);
return (ch);
}
TIM4_CH1输出频率50HZ,占空比50%PWM信号
HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);
TIM3_CH1输入捕获PWM信号的占空比和频率,需要用跳线将PA6和PD12连接在一起。 定义相关变量,以及使能相关定时器和计数处理代码
#define cnt_clk 72000000/(71+1)
#define arr 65535
uint32_t CCR1,CCR2,end_flag;
float duty_cycle,frequency;
HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_2);
while (1)
{
if(end_flag==1)
{
printf("\r\n频率=%.2fHZ,占空比=%.2f%%\r\n",frequency,duty_cycle);
end_flag=0;
}
HAL_Delay(1000);
}
输入捕获中断回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
CCR1=HAL_TIM_ReadCapturedValue(&htim8, TIM_CHANNEL_1);
if(CCR1!=0)
{
CCR2=HAL_TIM_ReadCapturedValue(&htim8, TIM_CHANNEL_2);
frequency=(float)cnt_clk/(CCR1+1);
duty_cycle=(float)(CCR2+1)*100/(CCR1+1);
end_flag=1;
}
else
{
frequency=0;
duty_cycle=0;
}
}
串口调试助手打印的结果基本正确 注意事项: 1、 PWM模式只能使用通道1和通道2 2、能捕获的最低频率f=(时钟频率/(分频系数PSC+1))/(重装载值ARR+1) f=(72000000/(71+1))/(65535+1)=15.2HZ
▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂ 二、普通输入捕获模式
|