STM32F407输入捕获应用--PWM 输入模式测量脉冲频率与宽度

news2024/9/25 9:30:53

STM32F407输入捕获应用--PWM 输入模式测量脉冲频率与宽度

    • 一、测量脉宽或者频率
    • 二、PWM 输入模式
    • 三、软件实现
      • 3.1、硬件准备
      • 3.2代码
      • 3.4 验证

输入捕获一般应用在两个方面,一个方面是脉冲跳变沿时间测量,另一方面
是 PWM 输入测量。

一、测量脉宽或者频率

在这里插入图片描述
1.测量频率

当捕获通道 TIx 上出现上升沿时,发生第一次捕获,计数器 CNT 的值会被锁存到捕获寄存器 CCR 中,而且还会进入捕获中断,在中断服务程序中记录一次捕获(可以用一个标志变量来记录),并把捕获寄存器中的值读取到 value1 中。当出现第二次上升沿时,发生第二次捕获,计数器 CNT 的值会再次被锁存到捕获寄存器 CCR 中,并再次进入捕获中断,在捕获中断中,把捕获寄存器的值读取到 value3 中,并清除捕获记录标志。利用 value3 和 value1 的差值我们就可以算出信号的周期(频率)。

2.测量脉宽

当捕获通道 TIx 上出现上升沿时,发生第一次捕获,计数器 CNT 的值会被锁存到捕获寄存器 CCR 中,而且还会进入捕获中断,在中断服务程序中记录一次捕获(可以用一个标志变量来记录),并把捕获寄存器中的值读取到 value1 中。然后把捕获边沿改变为下降沿捕获,目的是捕获后面的下降沿。当下降沿到来的时候,发生第二次捕获,计数器 CNT 的值会再次被锁存到捕获寄存器 CCR 中,并再次进入捕获中断,在捕获中断中,把捕获寄存器的值读取到 value3 中,并清除捕获记录标志。然后把捕获边沿设置为上升沿捕获。在测量脉宽过程中需要来回的切换捕获边沿的极性,如果测量的脉宽时间比较长,定时器就会发生溢出,溢出的时候会产生更新中断,我们可以在中断里面对溢出进行记录处理。

二、PWM 输入模式

测量脉宽和频率还有一个更简便的方法就是使用 PWM 输入模式。与上面那种只使用一个捕获寄存器测量脉宽和频率的方法相比,PWM 输入模式需要占用两个捕获寄存器。

在这里插入图片描述
当使用 PWM 输入模式的时候,因为一个输入通道(TIx)会占用两个捕获通道(ICx),所以一个定时器在使用 PWM 输入的时候最多只能使用两个输入通道(TIx)。我们以输入通道 TI1 工作在 PWM 输入模式为例来讲解下具体的工作原理,其他通道以此类推即可。

PWM 信号由输入通道 TI1 进入,因为是 PWM 输入模式的缘故,信号会被分为两路,一路是 TI1FP1,另外一路是 TI2FP2。其中一路是周期,另一路是占空比,具体哪一路信号对应周期还是占空比,得从程序上设置哪一路信号作为触发输入,作为触发输入的哪一路信号对应的就是周期,另一路就是对应占空比。作为触发输入的那一路信号还需要设置极性,是上升沿还是下降沿捕获,一旦设置好触发输入的极性,另外一路硬件就会自动配置为相反的极性捕获,无需软件配置。一句话概括就是:选定输入通道,确定触发信号,然后设置触发信号的极性即可,因为是 PWM 输入的缘故,另一路信号则由硬件配置,无需软件配置。当使用 PWM 输入模式的时候必须将从模式控制器配置为复位模式(配置寄存器 SMCR 的位 SMS[2:0]来实现),即当我们启动触发信号开始进行捕获的时候,同时把计数器 CNT 复位清零。

下面我们以一个更加具体的时序图来分析下 PWM 输入模式。

在这里插入图片描述

PWM 信号由输入通道 TI1 进入,配置 TI1FP1 为触发信号,上升沿捕获。当上升沿的时候 IC1 和 IC2 同时捕获,计数器 CNT 清零,到了下降沿的时候,IC2捕获,此时计数器 CNT 的值被锁存到捕获寄存器 CCR2 中,到了下一个上升沿的时候,IC1 捕获,计数器 CNT 的值被锁存到捕获寄存器 CCR1 中。其中 CCR2 测量的是脉宽,CCR1 测量的是周期。

从软件上来说,用 PWM 输入模式测量脉宽和周期更容易,付出的代价是需要占用两个捕获寄存器

三、软件实现

3.1、硬件准备

1、粤嵌开发板一套
在这里插入图片描述

2、迷你示波器一个

在这里插入图片描述

3.2代码

初始化代码

/*****************************************
引脚说明:
PB6

TIM4_CH1(TIM4 -- APB1 16位  84MHZ)

*****************************************/


void Pwm_PB6_InputInit(void)
{
	GPIO_InitTypeDef 			GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  	TIM_TimeBaseStructure;
	NVIC_InitTypeDef 			NVIC_InitStructure;
	TIM_ICInitTypeDef			TIM4_ICInitStructure;
	
	
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//时钟使能
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);//使能GPIOB时钟
	
	
	GPIO_InitStructure.GPIO_Pin 	= GPIO_Pin_6; 			//GPIOB6
	GPIO_InitStructure.GPIO_Mode 	= GPIO_Mode_AF;			//复用功能
	GPIO_InitStructure.GPIO_Speed 	= GPIO_Speed_100MHz;	//速度100MHz
	GPIO_InitStructure.GPIO_OType 	= GPIO_OType_PP; 		//推挽复用输出
	GPIO_InitStructure.GPIO_PuPd 	= GPIO_PuPd_NOPULL; 		//下拉
	GPIO_Init(GPIOB,&GPIO_InitStructure); 					//初始化
	
	// 定时器复用引脚
	GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_TIM4);

	TIM_TimeBaseStructure.TIM_Prescaler		= 83;  					//定时器分频
	TIM_TimeBaseStructure.TIM_CounterMode	= TIM_CounterMode_Up; 	//向上计数模式
	TIM_TimeBaseStructure.TIM_Period		= 49999;   				//自动重装载值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 		//分频因子 配置死区时会用到
	
	TIM_TimeBaseInit(TIM4,&TIM_TimeBaseStructure);


	//初始化TIM2输入捕获参数
	TIM4_ICInitStructure.TIM_Channel 	= TIM_Channel_1;   			//通道1
	TIM4_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;	//上升沿捕获
	TIM4_ICInitStructure.TIM_ICSelection= TIM_ICSelection_DirectTI; //映射到TI1上
	TIM4_ICInitStructure.TIM_ICPrescaler= TIM_ICPSC_DIV1;	 		//配置输入分频,不分频 
	TIM4_ICInitStructure.TIM_ICFilter   = 0x05;						//IC3F=0000 配置输入滤波器 不滤波
	// 初始化 PWM 输入模式
	TIM_PWMIConfig(TIM4, &TIM4_ICInitStructure);
		
	

	// 当工作做 PWM 输入模式时,只需要设置触发信号的那一路即可(用于测量周期)
	// 另外一路(用于测量占空比)会由硬件自带设置,不需要再配置
	
	// 选择输入捕获的触发信号
	TIM_SelectInputTrigger(TIM4, TIM_TS_TI1FP1);

	// 选择从模式: 复位模式
	// PWM 输入模式时,从模式必须工作在复位模式,当捕获开始时,计数器 CNT 会被复位
	TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);
	TIM_SelectMasterSlaveMode(TIM4,TIM_MasterSlaveMode_Enable);

	// 使能捕获中断,这个中断针对的是主捕获通道(测量周期那个)
	TIM_ITConfig(TIM4, TIM_IT_CC1, ENABLE);
	TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级2
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;		//子优先级0
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器、
	
	//TIM_ITConfig(TIM4,TIM_IT_Update|TIM_IT_CC2,ENABLE);				//允许更新中断 ,允许CC2IE捕获中断	
	
	TIM_Cmd(TIM4,ENABLE ); 	//使能定时器4
	
}


主函数代码

u32 IC1Value, IC2Value;
float DutyCycle,Frequency;


//定时器4中断服务程序	 
void TIM4_IRQHandler(void)
{ 		    

	/* 清除定时器捕获/比较 1 中断 */
	TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);

	/* 获取输入捕获值 */
	IC1Value = TIM_GetCapture1(TIM4);
	IC2Value = TIM_GetCapture2(TIM4);
	//printf("IC1Value = %d IC2Value = %d ",IC1Value,IC2Value);
	// 注意:捕获寄存器 CCR1 和 CCR2 的值在计算占空比和频率的时候必须加 1
	if (IC1Value != 0) 
	{
		flag = 1;
	} 

}


int main(void)
{
	
	unsigned int count = 0;
	
	
	//设置NVIC分组 第二分组 抢占优先级范围:0~3  响应优先级范围:0~3
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	Delay_Init();
	//对LED初始化
	Led_Init();

	Usart1_Init(115200);
	Pwm_PB6_InputInit();
	
	while(1)
	{

		//每隔500ms计算一次占空比与频率。
		if(flag == 1)
		{
			
			/* 占空比计算 */
			DutyCycle = (float)((IC2Value+1) * 100) / (IC1Value+1);

			/* 频率计算 */
			Frequency = 84000000/(83+1)/(float)(IC1Value+1);			
			
			
			printf("占空比:%0.2f%% 频率:%0.2fHz\r\n",DutyCycle,Frequency);
			
			DutyCycle = 0;
			Frequency = 0;
			flag = 0;
		}
			
		delay_ms(500);
			
	}
	return 0;
}

3.4 验证

在这里插入图片描述

最后发现有一定的误差,未知是不是这几百块的示波器产生的问题,还是软件的问题。还待验证,到时再找台高精度的脉冲发生器看看了。有了解的码农可以互相讨论下。

程序链接:https://download.csdn.net/download/wwwqqq2014/87148727

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/31926.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Dockerfile(容器与镜像 自定义nginx tomcat 镜像优化)

Dockerfile精讲一、容器与容器镜像之间的关系二、容器镜像分类三、容器镜像获取的方法四、容器镜像获取方法演示4.1 在DockerHub直接下载4.2 把操作系统中文件系统打包为容器镜像4.2.1 安装一个最化的操作系统4.2.2 把操作系统中文件系统进行打包4.2.3 把打包后文件加载至本地文…

连续信号与系统的频域分析之傅里叶级数

信号的傅里叶级数一、正交函数集二、三角形式傅里叶级数三、指数形式的傅里叶级数1. 定义2. 系数确定3. 典型信号的傅里叶级数4. 周期信号的功率谱在LTI系统的时域分析中,输入信号被分解成冲激信号或阶跃信号的叠加(积分),然后利用…

LeetCode刷题2:链表篇

提示:本篇共7道力扣题目供大家食用,时间自行把控~ 算法刷题系列笔记 LeetCode刷题1:数组篇 文章目录算法刷题系列笔记作者有话说一、链表知识1.1 什么是链表?1.2 链表的类型1.3 链表操作二、经典题目2.1 Leetcode203.移除链表元素2.2 Leet…

vue-jest vue3

1. 使用vite搭建测试项目: vue create test-vue-jest 选择单元测试:Unit Testing--->jest 2. 配置 jest.config.js module.exports {transform: {"^.\\.vue$": "vue-jest",},preset: vue/cli-plugin-unit-jest/presets/types…

【关于几个问题的思考】

项目如何部署在服务器上面的 此文章以springboot 项目为例: 1.需要申请一台服务器,安装Linux操作系统 2.在服务器安装jdk ,不需要安装Tomcat,springboot 项目内嵌 Tomcat;安装项目的依赖项:如mysql redis等 3.此处利用…

Oracle SQL执行计划操作(9)——位图相关操作

​​​​​​9. 位图相关操作 该类操作基于位图数据(例如:位图索引的位图数据)进行位操作,或将其他结构数据转成位图数据以利用位操作。根据不同的具体SQL语句及其他相关因素,如下各操作可能会出现于相关SQL语句的执行计划。 1)BITMAP AND 对两个位图索引进行“与”(…

【CLS数据淘金第四期】网络流日志-云联网日志分析

导语 云联网(Cloud Connect Network,CCN)云联网覆盖全球 20 地域,提供云上私有网络间(VPC)、VPC 与本地数据中心间(IDC)内网互联的服务,具备全网多点互联、路由自学习、…

Hypermesh三维网格划分技能,以汽车发动机连杆结构为例

作者:米条老师,仿真秀专栏作者 Hypermesh三维单元的划分功能还是非常的丰富和灵活的,通常掌握主要的几个命令基本就能够满足大部分的网格划分工作。首先我们先了解一下在hypermesh中实现三维网格划分的基本步骤: 几何部件分组及…

finereport开发者需要关注的问题

版本问题 如果使用高版本开发,则无法在低版本的设计使用与发布, 所以第一件事情就是要把设计器的版本弄好。 请使用v10.0.0(本地版本需要与当前的中台版本一致),目前官方已没有直接下载到v10.0.0完整包的地址了,例如:下图为当前的…

大佬指明方向!使用微服务的最佳实践以及如何避免采用微服务架构可能带来的复杂性陷阱

什么是微服务 微服务应用是与单体应用区分开来的. 当一个单体项目随着业务的发展会越来越膨胀,变得更加难维护,从一开始仅需一两个人到需要两三个团队,多个团队维护同一个项目无疑是一场灾难,沟通成本大大增加,技术协同也会十分困难. 举个例子,我在上一家公司维护过一个后台项…

IP地址虚拟网络与虚拟机网络配置

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起探讨和分享Linux C/C/Python/Shell编程、机器人技术、机器学习、机器视觉、嵌入式AI相关领域的知识和技术。 IP地址虚拟网络与虚拟机网络配置1. IP地址与子网划分☞IP地址☞特殊IP地址☞IP地址申请☞子网掩码☞子…

spider

大家好 我是Yhen 今天给大家分享一下 如何爬取卡塔尔世界杯球员榜 数据来源:百度体育 https://tiyu.baidu.com/match/%E4%B8%96%E7%95%8C%E6%9D%AF/tab/%E7%90%83%E5%91%98%E6%A6%9C/current/0 文章目录一.需求分析二.思路分析三.代码实战四.源码获取一.需求分析…

强强联合 加速科技“牵手”清华大学达成深度战略合作

近日,清华大学集成电路学院成功采购了加速科技ST2500系列高性能数模混合测试机(浙江省首台套装备)。加速科技“牵手”清华大学,共同推进集成电路自主技术的创新升级,就集成电路学科教学科研、人才培养展开深度合作。 清…

Java Spring后处理器

Java Spring后处理器 在Spring框架中,交给Spring管理的类信息都会被Spring底层自动加载被封装成对应的BeanDefinition对象存储在beanDefinitionMap的Map集合中去,那么除了直接将类信息配置的方式外,还有别的方式可以对想要交给Spring管理的类…

matlab在管理学中的应用简matlab基础【二】

1、MATLAB语言概述 1.1 MATLAB语言的发展 matlab语言是由美国的Clever Moler博士于1980年开发的 MATLAB Matrix Laboratory 它将一个优秀软件的易用性与可靠性、通用性与专业性 、一般目的的应用与高深的科学技术应用有机的结合 MATLAB是一种直译式的高级语言,比…

【安装Ubuntu18.04遇到的问题】未找到WIFI适配器

大家好,我是小政。好久没有更新文章,近期开始陆续分享一些研究生阶段正在学习的知识和遇到的一些问题。 联想拯救者Y9000P关于安装Ubuntu未找到WIFI适配器的解决方法1.Ubuntu18.042.网卡信息3.解决方法(1)用手机USB连接电脑提供网…

如何判断对象是否该被回收(引用计数法、可达性分析算法)

👨‍💻个人主页: 才疏学浅的木子 🙇‍♂️ 本人也在学习阶段如若发现问题,请告知非常感谢 🙇‍♂️ 📒 本文来自专栏: JVM 🌈 算法类型:Hot100题 &#x1f30…

计算机的应用领域

文章目录计算机的应用领域1、商业2、银行业3、保险行业4、教育行业5、市场营销6、卫生保健7、工程设计8、军事9、通讯10、政府计算机的应用领域 本节,我将带领您了解计算机在各个领域的应用。 1、商业 计算机的功能丰富,极高的计算能力,计…

sqli-labs/Less-56

这一关的欢迎界面提示我们还是以id作为注入点 我们仍然有14次尝试机会 首先我们还是先来判断一下是否属于数字型注入 输入如下 id1 and 12 回显如下 正确回显 属于字符型 接着输入1 查看回显 这个回显说明两件事情 一个是我们后面不能使用报错注入进行注入了 一个是我们这个…

Elasticsearch:使用反向地理编码在地图上显示自定义区域统计数据

在实际的许多应用中,我们可能并不一定按照行政区来进行划分区域,比如我们常说江浙一代,我们可以理解江苏和浙江这两个省合在一起,而不是把它们分开。我们有时也说长江三角区,它可能是跨几个省市的一个区域,…