• 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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

    HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);  //启动TIM4_CH1 PWM输出
    
    • 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)
      {
        //每1秒输出一次
    		if(end_flag==1)
    		{
    			printf("\r\n频率=%.2fHZ,占空比=%.2f%%\r\n",frequency,duty_cycle);
    			end_flag=0;
    		}
    		HAL_Delay(1000);
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    输入捕获中断回调函数

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这里插入图片描述

    串口调试助手打印的结果基本正确
    注意事项
    1、 PWM模式只能使用通道1和通道2
    2、能捕获的最低频率f=(时钟频率/(分频系数PSC+1))/(重装载值ARR+1)
    f=(72000000/(71+1))/(65535+1)=15.2HZ

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

  • 相关阅读:
    什么是 SSL?SSL/TLS是如何工作的?HTTP和HTTPS有什么区别?
    FITC-PEG-FA,Folic acid-PEG-Fluorescein,叶酸PEG荧光素
    基于SSM实现前后端分离在线考试管理系统
    Linux 环境Skywalking部署Elasticsearch
    【HAL库】STM32CubeMX开发----STM32F407----CAN通信实验
    java计算机毕业设计高校多媒体设备运维管理系统服务端MyBatis+系统+LW文档+源码+调试部署
    JS中字符串与ASCII码相互转换,前端如何解决秘钥非明文存储
    线性代数学习笔记4-3:求解齐次线性方程组Ax=0、消元法、行最简阶梯型矩阵RRFE
    模拟量信号干扰的主要原因及解决方案
    DM_SQL
  • 原文地址:https://blog.csdn.net/wsq_666/article/details/126557396