STM32F103ZET6【HAL开发】STM32CUBEMX------3.3测量PWM的频率和占空比

目的测量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)
{
	/* 发送一个字节数据到串口DEBUG_USART */
	HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);	
	
	return (ch);
}

TIM4_CH1输出频率50HZ,占空比50%PWM信号

HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);  //启动TIM4_CH1 PWM输出

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)
  {
    //每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)
{
	  /*PWM 信号的第一个上升沿时,定时器产生中断,计数器,CCR寄存器被复位。
    当下降沿到来时,IC2 会捕获,对应的是脉冲宽度测量,但不会产生中断。当第
	  二个上升沿时,IC1会捕获,对应的是周期宽度测量,而且会再次进入中断*/
				//printf("0");
				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

▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂
二、普通输入捕获模式

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值