【蓝桥杯嵌入式】定时器的PWM输出与输入捕获(测量频率与占空比)

news2024/11/24 19:14:55

【蓝桥杯嵌入式】定时器的PWM输出与脉冲输 入捕获(测量频率与占空比)

  • PWM输出
    • cubemx配置
    • 程序设计
  • 输入捕获
    • cubemx配置
    • 程序设计
  • 真题典例分析

PWM输出

cubemx配置

  PWM输出引脚配置,这里使用PA6和PA7引脚输出两路PWM信号,分别对应的是由TIM16和TIM17的通道1产生的PWM信号,同时配置定时器的预分频系数PSC和自动重装载值CCR,PWM信号频率即为:
frq = 80000000 / (PSC+1)/ (ARR+1)
这里预分频系数为800-1,自动重装载值为100,则频率 frq = 80000000 / 800 / 100 = 1K Hz,占空比预设置为20%

同理 对TIM17通道1进行相关配置,使得输出频率为2KHz,占空比初始化为20%的PWM信号

程序设计

通过cubemx配置后,初始化信号的参数如下所示

//PA6 1KHz 20%
TIM16->PSC = 800-1;
TIM16->ARR = 100-1;
TIM16->CCR1 = 20;

//PA7 2KHz 20%
TIM17->PSC = 400-1;
TIM17->ARR = 100-1;
TIM17->CCR1 = 20;

启动PWM输出: 启动TIM16与TIM17的通道1输出PWM信号

HAL_TIM_PWM_Start(&htim16,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim17,TIM_CHANNEL_1);

修改PWM信号占空比: 通过改变TIM16与TIM17通道1的自动重装载值来改变PWM信号的占空比

TIM16->CCR1 = 50;
TIM17->CCR1 = 25;

修改PWM信号的频率:,可以通过改变预分频系数PSC,或者改变自动重装值,但通过修改自动重装载值修改频率的同时会修改占空比。

TIM16->PSC = 400-1;	//将PA6引脚的频率改为2000 Hz 占空比保持不变
TIM17->ARR = 50-1;	//将PA7的频率改为4000 Hz 但占空比变为原来的2倍

输入捕获

  • 输入捕获可以用来测量PWM波的频率与占空比
  • 输入捕获模式下,当通道输入引脚出现指定高电平跳变时,当前CNT的值将被锁存到CCR中

cubemx配置

  通过查看原理图发现,开发板自带2路555信号发生器,分别通过接口J9和J10接到开发板的PB4和PA15端口,这里取下跳线帽,通过杜邦线将PA6、PA7的PWM信号接入到PA15、PB4引脚,用于检测PWM信号的频率与占空比。

  通过配置PB4引脚为TIM3_CH1,开启定时器3,设置预分频系数,配置从模式、触发源及其时钟源,分别设置通道1和通道2为直接模式与间接模式,同时设置为上升沿触发和下降沿触发。

同理对TIM2进行同样的配置

程序设计

初始化开启定时器的通道捕获

HAL_TIM_IC_Start(&htim2,TIM_CHANNEL_1);
HAL_TIM_IC_Start(&htim3,TIM_CHANNEL_1);
HAL_TIM_IC_Start(&htim2,TIM_CHANNEL_2);
HAL_TIM_IC_Start(&htim3,TIM_CHANNEL_2);

频率和占空比的测量

void pwm_process(void)
{
	//测量频率
	frq1 = 1000000.0f / (HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1)+1);
	frq2 = 1000000.0f / (HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_1)+1);
	
	//测量占空比
	duty1 = (HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2)+1) * 100.0f / (HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1)+1);
	duty2 = (HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_2)+1) * 100.0f / (HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_1)+1);
}

真题典例分析

  • PA6输出信号占空比通过电位器R37进行调节如图调节
  • 通过B2按键切换高低频模式,并通过LCD进行实时显示

adc数据采集功能函数:

double getAdcVal(ADC_HandleTypeDef *pin)
{
	double dat;
	HAL_ADC_Start(pin);
	dat = HAL_ADC_GetValue(pin);
	return dat * 3.3 / 4096;	
}

adc业务逻辑程序进程函数: 首先确定adc数据采集周期为200ms采集一次,并进行数字滤波,最后通过电压与占空比的关系,来确定PA6引脚的占空比。

u32 adc_tick = 0;
double adc_sum = 0;
void adc_process(void)
{
	//adc采集周期 200ms
	if(uwTick - adc_tick < 200)
		return;
	adc_tick = uwTick;
	
	//adc数字滤波
	for(uchar i = 0; i < 10; i++)
		adc_sum += getAdcVal(&hadc2);
	vr37 = adc_sum / 10.0f;
	adc_sum = 0;
	
	//通过电压改变PWM占空比
	if(vr37 <= 1.0f)
		TIM16->CCR1 = 10;
	else if(vr37 >= 3.0f)
		TIM16->CCR1 = 85;
	else
		TIM16->CCR1 = (uchar)(37.5 * (vr37 - 1.0f) + 10);
}

按键二: 启动5秒定时,并确定是从高频到低频,还是从低频到高频

if(key[1].single_flag == 1)
{
	//按键2短按业务逻辑程序
	//shake_flag = !shake_flag;
	up_flag = !up_flag;					//从低频到高频标志
	sec5_flag = !sec5_flag;			//5秒定时标志
	HAL_TIM_Base_Start_IT(&htim7);	//启动定时器 改变分频系数
	key[1].single_flag = 0;
}

定时器中断服务函数

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{	
	if(htim->Instance == TIM7)		//50ms
	{
		if(up_flag)
			psc--;
		else
			psc++;
	}
}

PWM进程函数: 频率、占空比的修改与测量

void pwm_process(void)
{
	//通过修改预分频系数修改频率
	TIM16->PSC = psc;
	
	//检测PWM信号频率
	frq1 = 1000000.0f / (HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1)+1);
	frq2 = 1000000.0f / (HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_1)+1);
	
	//检测PWM信号占空比
	duty1 = (HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2)+1) * 100.0f / (HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1)+1);
	duty2 = (HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_2)+1) * 100.0f / (HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_1)+1);
}

最后将实时的频率与占空比显示在LCD屏幕

void lcd_process(void)
{
	if(ui == 0)					//第一个界面显示的内容
	{
		sprintf(text,"     Title1 ");
		LCD_DisplayStringLine(Line1, (unsigned char *)text);	//LCD显示函数
		
		sprintf(text,"    frq1:%dHz  ",frq1);
		LCD_DisplayStringLine(Line3, (unsigned char *)text);	//LCD显示函数
		sprintf(text,"    duty1:%d%% ",duty1);
		LCD_DisplayStringLine(Line4, (unsigned char *)text);	//LCD显示函数
		sprintf(text,"    frq2:%dHz  ",frq2);
		LCD_DisplayStringLine(Line5, (unsigned char *)text);	//LCD显示函数
		sprintf(text,"    duty2:%d%% ",duty2);
		LCD_DisplayStringLine(Line6, (unsigned char *)text);	//LCD显示函数
	}
}

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

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

相关文章

计算机提示msvcp140.dll丢失的解决方法

在日常操作与深度应用计算机系统的过程中&#xff0c;我们难免会遭遇各类技术性问题。其中&#xff0c;一种颇为常见且可能导致应用程序无法正常启动或运行的情况便是“msvcp140.dll文件缺失”。这一现象&#xff0c;对于无论是经验丰富的IT专业人士&#xff0c;还是对计算机知…

Linux操作系统(六):文件系统组件

参考资料&#xff1a;阿秀的笔记 文件系统 1. 文件系统的基本组成2. 文件的使用3.文件如何存储3.1 目录怎么存储 4.Linux继承于Unix系统的Unix文件实现方式4.1 Linux Ext 2/3 文件系统4.2 Linux Ext 4 文件系统4.3 磁盘空闲空间的管理机制4.3.1 空闲表法4.3.2 空闲链表法4.3.3…

网易云歌曲评论抓取

网易云歌曲评论爬取 步骤1.找到一首歌曲2.按下F12键打开开发者模式,对其进行抓包3.查找获得评论数据的接口4.对获得评论数据接口进行分析5.构建加密函数方法一方法二运行结果全部代码使用Js文件只使用python新的代码小结与展望这次的任务是获取网易云音乐下面的评论,涉及的知…

安卓四大组件——Service篇

1.作用 长时间位于后台&#xff08;无界面&#xff09;完成用户指定操作 1.1两类状态 &#xff08;a&#xff09;started&#xff08;启动&#xff09;&#xff1a;当应用程序组件&#xff08;如activity&#xff09;调用startService()方法启动服务时&#xff0c;服务处于sta…

HJ1 字符串最后一个单词的长度(字符串,import java.util.HashSet;)

import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别int num sc.nextInt();boolean[] in new boolean[…

设计模式学习笔记 - 设计模式与范式 -行为型:8.状态模式:游戏、工作流引擎中常用的状态机是如何实现的?

概述 本章学习状态模式。在实际的开发中&#xff0c;状态模式并不是很常用&#xff0c;但是在能够用到的场景里&#xff0c;它可以发挥很大的作用。从这一点上看&#xff0c;它有点像我们之前讲到的组合模式。 状态模式一般用来实现状态机&#xff0c;而状态机常用在游戏、工…

✌2024/4/3—力扣—整数反转

代码实现&#xff1a; int reverse(int x) {long num 0;while (x ! 0) {num num * 10 x % 10;x x / 10;}if ((int)num ! num) {return 0;}return (int)num; }

使用手动连接,将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中,在自定义的槽函数中调用关闭函数

使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#xff0c;密码是否为…

Houdini笔记操作技巧_集锦

个人记录下&#xff0c;谨防遗忘。同时丰富下Hou的中文搜素环境。 1、自定义启动界面 ① 设置完界面后&#xff0c;保存自定义界面&#xff08;Save Current Desktop As...&#xff09; ② Edit-->Preferences-->General UIInterface-->Startup in Desktop&#xff1…

qt打包程序打包之跨平台

本文讲的是linux系统中的程序打包&#xff0c;首先我们创建一个简单的程序&#xff0c;我的程序叫做debtest 然后设置qmake来源&#xff0c;这个直接决定了程序依赖的qt库的位置&#xff0c;如果我们需要指定qt标准库的位置&#xff0c;那么qt环境就需要在那个位置。 修改前&am…

C# 如何修改项目名称

目录 背景具体步骤1、Visual Studio中修改项目名和程序集名称以及命名空间2、修改项目文件夹名3、修改解决方案里项目的路径4、再次打开解决方案&#xff0c;问题解决步骤总结 名词解释解决方案&#xff08;Solution&#xff09;项目&#xff08;Project&#xff09;程序集&…

【操作系统】CentOS7入门级安装

下载镜像 CentOS镜像下载Download (centos.org) 我们选择第一个 X86_64 CentOS Mirrors List 版本描述X86_X64带64位的32位扩展版(一般安装这个)ARM64 (aarch64)嵌入式。适用于微端(树莓派、机械臂、机械中控)IBM Power (ppc64le)专用于IBM POWER服务器 选择一个合适的链接 …

DSL - Wire 实现-ApiHug101

&#x1f917; ApiHug {Postman|Swagger|Api...} 快↑ 准√ 省↓ GitHub - apihug/apihug.com: All abou the Apihug apihug.com: 有爱&#xff0c;有温度&#xff0c;有质量&#xff0c;有信任ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace docs/ha…

javaScript手写专题——防抖/节流/闭包/Promise/深浅拷贝

目录 目录 一、 防抖/节流/闭包/定时器 编写一个组件&#xff0c;在input中输入文本&#xff0c;在给定的数据中查找相关的项目&#xff0c;并渲染搜索结果列表 1.新增InputSearch.vue组件 key的作用 2.新增 InputView.vue 3.添加路由 4.效果演示 follow up加上防抖怎么处理 1.…

如何从头开始编写LoRA代码,这有一份教程

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 作者表示&#xff1a;在各种有效的 LLM 微调方法中&#xff0c;LoRA 仍然是他的首选。 LoRA&…

机器学习-随机森林算法预测温度

文章目录 算法简介解决问题获取数据集探索性数据分析查看数据集字段信息查看数据集综合统计结果查看特征值随时间变化趋势 数据预处理处理缺失数据字符列编码数据集分割训练集、验证集、测试集数据集分割 构建模型并训练结果分析与评估进一步优化实际使用经验总结 算法简介 随…

基于遗传优化的SVD水印嵌入提取算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于遗传优化的的SVD水印嵌入提取算法。对比遗传优化前后SVD水印提取性能&#xff0c;并分析不同干扰情况下水印提取效果。 2.测试软件版本以及运行结果展示 MA…

深度学习实践(一)基于Transformer英译汉模型

本文目录 前述一、环境依赖二、数据准备1. 数据加载2. 构建单词表程序解析&#xff08;1&#xff09;将列表里每个子列表的所有单词合并到一个新列表&#xff08;没有子列表&#xff09;中。&#xff08;2&#xff09;Counter&#xff08;&#xff09;-- 统计迭代对象各元素出现…

【Spring AOP】@Aspect结合案例详解(一): @Pointcut使用@annotation + 五种通知Advice注解(已附源码)

文章目录 前言AOP与Spring AOPAspect简单案例快速入门 一、Pointcutannotation 二、五种通知Advice1. Before前置通知2. After后置通知3. AfterRunning返回通知4. AfterThrowing异常通知5. Around环绕通知 总结 前言 在微服务流行的当下&#xff0c;在使用SpringCloud/Springb…

Mogdb双网卡同步最佳实践

大家都知道Oracle数据库无论是单机还是RAC集群在进行生产部署实施时&#xff0c;我们都会对网卡做冗余考虑&#xff0c;比如使用双网卡&#xff0c;比如public、心跳网络。这样的目的主要是为了安全&#xff0c;避免淡点故障。当然也网卡Bond不仅是可以做主备还可以支持负载均衡…