嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记14:PWM捕获

news2024/11/16 18:06:52

系列文章目录

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记01:赛事介绍与硬件平台

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记02:开发环境安装

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记03:G4时钟结构

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记04:从零开始创建工程模板并开始点灯

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记05:Systick滴答定时器

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记06:按键输入

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记07:ADC模数转换

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记08:LCD液晶屏

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记09:EEPROM

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记10:USART串口通讯

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记11:数字电位器MCP4017

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记12:DAC数模转换

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记13:RTC实时时钟

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记14:PWM捕获

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记15:PWM输出

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记16:蓝桥杯编程手册

嵌入式|蓝桥杯STM32G431(HAL库开发)——CT117E学习笔记17:第十四届省赛真题



前言

这节讲解一下PWM捕获的基础知识。PWM捕获是指我们的单片机可以测量输入到它管脚上的方波的频率或者占空比,捕获就是说我们可以捕捉外部方波的信息。这就是我们这节要学习的内容。

一、基础知识

首先我们看一下电路图,这里有两个555芯片构成了一个方波发生器。

我们可以通过R40和R39两个电位器,就可以在555芯片的3号管脚输出一个方波,方波的频率就是通过R40和R39进行调节。3号管脚通过跳帽J9、J10接入PA15和PB4两个管脚。PA15和PB4分别可以配置成TIM2_CH1和TIM3_CH1,也就是定时器2的1通道和定时器3的1通道,用他们来捕获外部方波的频率和占空比。

捕获频率的作用有很多,比如说无人机上很多接收机的信号都是方波信号,也可以用来测量霍尔传感器的输出等等。但是我们这里只需要测量555的输出就行了。我们不需要知道555的具体接法是什么,只需要知道他可以通过调节这两个电阻就能产生不同频率的方波就行了,而我们的任务就是要用单片机测量他们的频率。另外还要注意好每个管脚分别对应着定时器的哪个通道。

此外呢,我们还要知道如何用示波器来观察方波的频率和占空比,只需要把示波器接在J9、J10两个跳线上就行了,我们调节R39、R40就可以看到方波的频率是在变化的。大致范围是在1-23kHz,并且频率太快(20k以上)的话波形是会失真的,波形正常时的频率范围应该在5k左右。占空比大概就是在50%。

二、测量单路频率

我们先研究U8芯片,通过R40可以产生频率可变的方波,然后通过跳帽J10接到了PA15管脚,对应TIM2_CH1通道来捕获。

首先看一下编程思路:每次上升沿中断,获取CNT值(定时器的计数值),并重新清零CNT值,重新计时。CNT的值就是一个PWM的周期,通过周期可以获得其频率(周期的倒数)。

我们可以把定时器配置成每us加1,那么如果CNT=1000,就相当于周期就是1ms,对应的频率就是1kHz。

程序设计步骤:

1.用“模板”生成代码

2.配置TIM2的PA15作为TIM2_CH1的输入捕获,注意要配置输入捕获模式,并勾选中断NVIC(一定不能忘)

3.根据需求配置TIM2_CH1的分频值,推荐配置成1us计数一次(因为系统时钟80MHz,我们想要1us就要1MHz,也就是分频80,因为从0开始算所以设置成79。up是上升计数模式,默认,不用更改。Counter Period是计时周期,它是32位的,也就是0—0xffffffff,如果超过这个这个周期就会溢出,所以我们把它设置成最大。)

4.移植文件到编程工程

  • main.c包含tim.h头文件
  • 添加tim.c的源文件和TIM相关的HAL库驱动函到工程中
  • 在stm32g4xx_hal_conf.h中启动TIM模块
  • 在stm32g4xx_it.c中移植TIM2_IRQHandler中断服务函数
  • 在主函数中调用MX_TIM2_Init()定时器初始化函数和HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1)启动定时器2捕获功能
  • HAL_TIM_IC_CaptureCallback回调函数里,获取CNT值,计算PWM的频率

前四步都是常规的移植步骤,我们前面已经做过很多次,下面重点讲解一下后面两步:定时器捕获启动函数和中断回调函数。

MX_TIM2_Init()初始化之后,我们在后面加上HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1)启动定时器2捕获。这样只要有up输入进到PA15,我们的定时器就会产生一个中断,然后就可以在中断处理函数中处理了。

下面我们就可以用HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)回调函数了,这个回调函数我们可以在stm32g4xx_it.c中找到HAL_TIM_IRQHandler(),即TIM的中断处理函数,然后在里面就能找到了。

这是一个弱定义的函数,我们把它复制到main.c中编辑它的功能。编程思路之前已经讲过了,中断后开始计时,每1us计时一次作为CNT,回调函数中先要__HAL_TIM_GetCounter(&htim2)获取之前计时的CNT,再__HAL_TIM_SetCounter(&htim2,0)设置重新计时,然后计算得到频率,最后重新使能中断启动函数(否则只会中断一次)。

//pwm capture
u32 tim2_cnt1=0;
u32 f1=0;
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	tim2_cnt1 = __HAL_TIM_GetCounter(&htim2); //获取CNT
	__HAL_TIM_SetCounter(&htim2,0);//CNT置0,重新计数
	f1=1000000/tim2_cnt1;//计算频率
	HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);//重新启动中断
}

这样我们就能得到R40输出的方波频率f1了。我们可以把它显示在LCD上,也可以接在示波器上看一下波形,频率对不对。接示波器的时候一头接地,一头接J10。

三、测量双路频率

除了PA15可以测量R40调节输出的PWM频率之外,PB4也可以测量R39调节输出的PWM频率。我们可以同时测量这两路的频率。

PB4可以配置为TIM3的CH1通道,经过上一节我们知道,PA15可以配置为TIM2的CH1通道,我们打开CubeMX查看如何初始化,这里我们就直接打开刚刚的工程即可,就不新建新的工程了。

如图,选择PB4和PA15引脚。

分别选择Channel1的输入捕获直连模式

然后使能TIM2和TIM3的中断。使能好后我们设置一下Configuration里面的参数。依然是预分频79,让定时器1us计数一次到CNT中。Counter Period继续选择最大值0xFFFF或者65535(因为这里是16位的,鼠标点击它会提示可以设置的最大数值)。其他的我们就保持默认。

然后生成代码,CubeMX会自动帮我们做好分频、周期的配置、使能中断。这里我们就不需要移植了。

我们可以在stm32g4xx_it.c文件中看到两个TIM的中断处理函数了。

查看它的定义,在里面也可以看到中断回调函数HAL_TIM_IC_CaptureCallback()了。

继续查看它的定义,可以看到HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)。

这样以后我们要编写TIM2的回调函数就可以直接定义它了(因为是弱定义的函数),但是有一个问题是,我们可以注意TIM2和TIM3的回调函数都是同一个,所以函数本身无法区分是哪个TIM。就需要我们人为地编写程序判断,要写一个if语句,判断这里的结构体htim是哪一个。比如if(htim == &htim2),就说明这里是TIM2,后面就写TIM2要做的工作。

不过我们这里还没有启动中断,同样,与上节一样,TIM2和TIM3的中断启动函数分别为:

HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1)

HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1)

这个函数名和格式是需要记忆的。我们直接把他们放在各自的TIM初始化函数后面即可开启中断。

启动中断之后我们继续编写中断回调函数,实现PWM捕获的功能,逻辑依然是:先获取CNT值,再清空CNT值,重新计数,再用CNT值计算此时的频率,再重新开启中断。注意不要忘记__HAL_TIM_GetCounter()__HAL_TIM_SetCounter()这两个函数的用法。

//PWM Capture
u32 tim2_cnt = 0;
u32 tim3_cnt = 0;
u32 f40 = 0;
u32 f39 = 0;
void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
{
	if(htim == &htim2)
	{
		tim2_cnt = __HAL_TIM_GetCounter(&htim2);
		__HAL_TIM_SetCounter(&htim2,0);
		f40 = 1000000/tim2_cnt;//得到频率
		HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);
	}
	else if(htim == &htim3)
	{
		tim3_cnt = __HAL_TIM_GetCounter(&htim3);
		__HAL_TIM_SetCounter(&htim3,0);
		f39 = 1000000/tim3_cnt;//得到频率
		HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
	}
}

我们可以在LCD上显示R39和R40的频率,这里就不演示了。

四、测量单路占空比

测完频率,我们接下来看一下如何测量频率和占空比。我们知道,测量频率本质就是测量PWM输入的周期,用CNT计数器来实现,那么同样,占空比的本质就是高电平占整个周期的比值。所以测量占空比除了要测量周期之外,还要再测量一下高电平时间。

那么大概的编程思路就是:

  • 第一次上升沿中断,开始计时(清零计数器),并改成下降沿中断。
  • 下降沿中断,获取计数器的CNT值T1,并改成上升沿中断。
  • 第二次上升沿中断,获取计数器的CNT值T2。通过T2可以获得PWM的频率,T1/T2可以获得PWM的占空比。

其实这里面大部分的操作,比如如何开启中断,如何获取计数器的CNT的值等等,我们都是已经掌握的,唯一没有掌握的就是如何改变上升沿下降沿的极性。所以我们初始化的时候要怎么改变极性呢?我们只需要操作一个寄存器:CCER,就可以改变极性了

五、测量双路占空比

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

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

相关文章

SQLite的架构(十一)

返回:SQLite—系列文章目录 上一篇:SQLite下一代查询规划器(十) 下一篇:SQLite—系列文章目录 介绍 本文档介绍SQLite库的架构。 这里的信息对那些想要了解或 修改SQLite的内部工作原理。 接口SQL 命令处理器虚拟机B-树…

深入理解npm常用命令

npm(Node Package Manager)是 Node.js 的包管理工具,用于管理 Node.js 应用程序的依赖包。除了安装、更新和卸载依赖包外,npm 还提供了许多其他功能,如初始化项目、运行脚本、查看依赖树等。本文将详细介绍一些常用的 …

阿里云弹性计算通用算力型u1实例性能评测,性价比高

阿里云服务器u1是通用算力型云服务器,CPU采用2.5 GHz主频的Intel(R) Xeon(R) Platinum处理器,ECS通用算力型u1云服务器不适用于游戏和高频交易等需要极致性能的应用场景及对业务性能一致性有强诉求的应用场景(比如业务HA场景主备机需要性能一致)&#xf…

续二叉搜索树递归玩法

文章目录 一、插入递归二、寻找递归&#xff08;非常简单&#xff0c;走流程就行&#xff09;三、插入递归&#xff08;理解起来比较麻烦&#xff09; 先赞后看&#xff0c;养成习惯&#xff01;&#xff01;&#xff01;^ _ ^<3 ❤️ ❤️ ❤️ 码字不易&#xff0c;大家的…

将 Elasticsearch 向量数据库引入到数据上的 Azure OpenAI 服务(预览)

作者&#xff1a;来自 Elastic Aditya Tripathi Microsoft 和 Elastic 很高兴地宣布&#xff0c;全球下载次数最多的向量数据库 Elasticsearch 是公共预览版中 Azure OpenAI Service On Your Data 官方支持的向量存储和检索增强搜索技术。 这项突破性的功能使你能够利用 GPT-4 …

Android MediaRecorder

AndroidManifest.xml中添加权限标记 <uses-permission android:name"android.permission.RECORD_AUDIO"/> 动态添加权限MainActivity requestPermissions(new String[]{Manifest.permission.CAMERA,Manifest.permission.RECORD_AUDIO},100); 创建MediaReco…

阿里云服务器ECS经济型e实例优惠价格99元一年

阿里云服务器99元一年配置为云服务器ECS经济型e实例&#xff0c;2核2G配置、3M固定带宽和40G ESSD Entry系统盘&#xff0c;新用户和老用户均可买&#xff0c;续费不涨价依旧是99元一年&#xff0c;阿里云服务器网aliyunfuwuqi.com来详细说下阿里云99元服务器性能测评&#xff…

ST表---算法

相当于二分的思想&#xff0c;一直比较最值 ST的创建 现在创建成功&#xff0c;是应该如何查询的问题 ST表的查询 虽然这两区间有重叠&#xff0c;但是可以一个往前数&#xff0c;一个往后数&#xff0c;互不影响 时间复杂度 创建st表的复杂度为n*logn 使用时的复杂度为O(…

Vol.34 Good Men Project:一个博客网站,每月90万访问量,通过付费订阅和广告变现

今天给大家分享的案例网站是&#xff1a;Good Men Project&#xff0c;这是一个专门针对男性成长的博客网站&#xff0c;内容包括人际关系、家庭、职业发展等话题。 它的网址是&#xff1a;The Good Men Project - The Conversation No One Else Is Having 流量情况 我们先看…

【c/c++】深入探秘:C++内存管理的机制

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 朋友们大家好&#xff0c;本篇文章我们详细讲解c中的动态内存管理 目录 1.C/C内存分布2.C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free3.c内存管理方式3.1new/delete对内…

二叉树层序遍历 及相关题目

1&#xff0c;力扣102 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9,20],[15,7]]示例…

常见滤波算法(PythonC版本)

简介 受限于MCU自身的ADC外设缺陷&#xff0c;精度和稳定性通常较差&#xff0c;很多场景下需要用滤波算法进行补偿。滤波的主要目的是减少噪声与干扰对数据的影响&#xff0c;让数据更加接近真实值。 一阶低通滤波 一阶低通滤波是一种信号处理技术&#xff0c;用于去除信号中…

【C++入门】初识C++

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

【Linux】寿司线程池{单例模式之懒汉模式下的线程池}

文章目录 回顾单例模式0.多线程下的单例模式的意义1.什么是单例模式1.0设计模式1.1C单例模式的介绍及原理1.2拷贝构造和赋值重载的处理1.3if (nullptr ptr)&#xff0c;nullptr放在比较运算符的前面?1.4实现单例模式的方式 2.实现懒汉方式的单例模式2.1单线程的单例模式2.2多…

StarRocks实战——携程火车票指标平台建设

目录 前言 一、早期OLAP架构与痛点 二、指标平台重构整体设计 2.1 指标查询过程 2.1.1 明细类子查询 2.1.2 汇总类子查询 2.1.3 “缓存” 2.2 数据同步 三、Starrocks使用经验分享 3.1 建表经验 3.2 数据查询 3.3 函数问题 四、查询性能大幅提升 五、 后续优化方…

算法——分治(快速排序)

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 小比特 大梦想 此篇文章与大家分享分治算法关于排序排序的专题 对于快速排序在我个人主页专栏 <排序> 有详细的介绍,此专题对快排进行了优化操作,并介绍了优化后的快排的几种运用 如果有不足的或者错误的请…

利用Lora调整和部署 LLM

使用 NVIDIA TensorRT-LLM 调整和部署 LoRA LLM 大型语言模型 (LLM) 能够从大量文本中学习并为各种任务和领域生成流畅且连贯的文本&#xff0c;从而彻底改变了自然语言处理 (NLP)。 然而&#xff0c;定制LLM是一项具有挑战性的任务&#xff0c;通常需要完整的培训过程&#xf…

C++ 2024-4-1 作业

#include <iostream> using namespace std;class A { public:int a;A(int a):a(a){cout<<"A的有参构造"<<endl;} }; class B:virtual public A { public:int b;B(int a,int b):A(a),b(b){cout<<"B的有参构造"<<endl;} }; cl…

反截屏控制技术如何防止信息通过手机拍照泄漏?

反截屏控制技术为企业数据安全提供了重要的防护措施。通过以下几点&#xff0c;有效阻止了信息通过拍照等方式的泄漏&#xff1a; 反截屏控制开启&#xff0c;用户启动截屏操作时&#xff0c;允许非涉密内容截屏操作&#xff0c;但所有涉密内容窗口会自动隐藏&#xff0c;防止涉…

openstack云计算(一)————openstack安装教程,创建空白虚拟机,虚拟机的环境准备

1、创建空白虚拟机 需要注意的步骤会截图一下&#xff0c;其它的基本都是下一步&#xff0c;默认的即可 ----------------------------------------------------------- 2、在所建的空白虚拟机上安装CentOS 7操作系统 &#xff08;1&#xff09;、在安装CentOS 7的启动界面中…