IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32F103ZET6【HAL开发】STM32CUBEMX------3.3测量PWM的频率和占空比 -> 正文阅读

[嵌入式]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

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

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-09-04 01:27:45  更:2022-09-04 01:30:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 16:53:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计