【STM32+HAL库】---- 通用定时器输入捕获PWM信号

硬件开发板:STM32G0B1RET6
软件平台:cubemax+keil+VScode

1 新建cubemax工程

1.1 配置系统时钟RCC

image

1.2 配置定时器

1.2.1 配置输入捕获

选择通用定时器TIM2-Channel 1为输入捕获引脚,对应IO口是PA0,时钟源选择内部时钟源Internal clock,工作模式选择直接输入捕获Input Capture direct mode,预分频系数选择63,定时器向上计数,重装载值选择最大值,减少溢出次数;输入捕获选择上升沿直接触发。
image

使能中断
image

1.2.2 配置PWM输出

选择通用定时器TIM3-Channel 1为PWM输出引脚,对应IO口是PA6,时钟源选择内部时钟源Internal clock,工作模式选择PWM输出PWM Generation CH1,预分频系数选择63,定时器向上计数,重装载值选择999,此时对应产生的PWM信号周期是 T = 64 ∗ 1000 64 M = 1 m s ; 频率为 1 K H z T=\frac{64*1000}{64M}=1ms;频率为1KHz T=64M641000=1ms;频率为1KHz,占空比设置为100,即高电平所占总周期的10%
image

1.3 配置串口

image

2 代码

2.1 printf重定向

usart.h中添加头文件和函数声明

# include "stdio.h"int fgetc(FILE *f);
int fputc(int ch,FILE *f);

usart.c中重定向

//重定向scanf
int fgetc(FILE *f)
{uint8_t ch=0;HAL_UART_Receive(&huart2,&ch,1,0xffff);return ch;
}//重定向printf
int fputc(int ch,FILE *f)
{uint8_t temp[1]={ch};HAL_UART_Transmit(&huart2,temp,1,2);return ch;
}

由于该实验并未使用到scanf函数,可不必重定向scanf

2.2 定义变量

uint32_t capture_value[3];    /*定义数组变量,存放捕获到的值*/
uint32_t diff_value1;    /*计数差值*/
uint32_t diff_value2;    /*计数差值*/uint8_t capture_state=0;    /*捕获状态:0表示未开始捕获;1表示完成一次捕获;2表示完成两次捕获*/
uint8_t capture_flag=0;    /*捕获标志位:0表示未完成,1表示已完成*/

2.3 中断回调函数

/* USER CODE BEGIN 4 */
//回调函数
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{if (htim==&htim2){switch (capture_state){case 0:{capture_value[0]=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);    /*读取捕获开始时间*/__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_FALLING);    /*切换为下降沿捕获*/capture_state=1;    /*标志完成第一次捕获*/}break;case 1:{capture_value[1]=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);    /*读取第二次捕获时间*/__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING);    /*切换为上升沿捕获*/capture_state=2;    /*标志完成第二次捕获*/}break;case 2:{capture_value[2]=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);    /*读取捕获结束时间*/HAL_TIM_IC_Stop_IT(htim,TIM_CHANNEL_1);    /*停止捕获*/capture_state=0;    /*标志完成第三次捕获,重新置0,准备下一轮捕获*/capture_flag=1;    /*标志捕获完成*/}break;default:printf("running error!\n");break;}}}
/* USER CODE END 4 */

2.4 main函数

int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_TIM2_Init();MX_TIM3_Init();MX_USART2_UART_Init();/* USER CODE BEGIN 2 */HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);    /*开启PWM输出*/HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);    /*开启输入捕获*//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){if (capture_flag==1)    /* 捕获完成 */{printf("\n******capture start******\n");if (capture_value[2] >= capture_value[0])    /* 计时没有溢出 */{diff_value1=capture_value[2]-capture_value[0];    /* 取差值 */}else    /* 计时有溢出 */{diff_value1=(0xffffffff+1)+capture_value[2]-capture_value[0];    /* 取差值 */}printf("周期:%.2fms\n",diff_value1/1000.0);    /*周期=差值*单次计数时间*/printf("频率:%.2fKHz\n",1000.0/diff_value1);if (capture_value[1] >= capture_value[0])    /* 计时没有溢出 */{diff_value2=capture_value[1]-capture_value[0];    /* 取差值 */}else    /* 计时有溢出 */{diff_value2=(0xffffffff+1)+capture_value[1]-capture_value[0];    /* 取差值 */}printf("高电平:%.2fms\n",diff_value2/1000.0);    /*高电平时间=差值*单次计数时间*/printf("占空比:%d%%\n",diff_value2*100/diff_value1);printf("******capture over******\n");capture_flag=0;    /*清除标志位,准备下一轮捕获*/HAL_Delay(1000);HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1);    /*开启下一轮捕获*/}/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

周期计算公式: T = 计数差值 ∗ 单次计数时间 = 计数差值 ∗ 1 计数频率 = 计数差值 ∗ 1 时钟频率 / 预分频系数 = 计数差值 ∗ 预分频系数 时钟频率 T=计数差值*单次计数时间=计数差值*\frac{1}{计数频率}=计数差值*\frac{1}{时钟频率/预分频系数}=计数差值*\frac{预分频系数}{时钟频率} T=计数差值单次计数时间=计数差值计数频率1=计数差值时钟频率/预分频系数1=计数差值时钟频率预分频系数
比如该实验中,时钟频率为64MHz,预分频系数为63(64分频),得到的计数频率为1MHz,即单次计数时间为1us

3 实验现象

用杜邦线连接PA0PA6引脚,打开串口,观察打印情况
image

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

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

相关文章

Unity实战案例 2D小游戏HappyGlass(模拟水珠)

本案例素材和教程都来自Siki学院,十分感谢教程中的老师 本文仅作学习笔记分享交流,不作任何商业用途 预制体 在这个小案例中,水可以做成圆形但是带碰撞体,碰撞体比图形小一圈,顺便加上Trail renderer组件 材质 将碰撞…

Win11 / Win10 系统极化工具,降低游戏延迟效果明显

Win11 / Win10 系统优化工具,降低游戏延迟效果明显 Windows 系统优化就是精简系统一些功能组件、对一些系统功能进行设置等,这样可以减少不必要的硬件资源占用。 全面的系统优化功能外,据不少网友表示通过优化后 CS GO 游戏降低输入延迟效果明显。 免费…

沃飞长空联合极氪亮相2024世界动力电池大会

9月1日至2日,2024世界动力电池大会在四川宜宾举办,沃飞长空与同属吉利控股集团旗下的新时代豪华科技品牌极氪汽车一同亮相。 现场,双方携手展出了AE200电动垂直起降航空器、极氪009光辉版、极氪001,以及极氪能源、金砖电池、威睿…

开源 AI 智能名片 O2O 商城小程序在营销中的应用

摘要:本文探讨了开源 AI 智能名片 O2O 商城小程序在营销中的应用,重点分析了喜好原则、互惠互利和高度认可三个方面对小程序推广和用户忠诚度提升的重要性。通过融入这些原则,开源 AI 智能名片 O2O 商城小程序能够更好地满足用户需求&#xf…

HTML静态网页成品作业(HTML+CSS)——动漫大耳朵图图网页(4个页面)

🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有4个页面。 二、作品演示 三、代…

VUE2.0 elementUI el-input-number 数据更新,视图不更新——基础积累

今天遇到一个问题,是关于el-input-number组件的,发现数据明明已经更改了,但是页面上组件输入框中还是之前的值。 比如上方输入框中,我输入120.5,就会出现下面的诡异现象 回显此值是120.779,但是页面上输入…

协同开发工具Git

网上对于Git的使用方法介绍的很多,在日常工作中,Git是团队开发必不可少的工具之一,我想为一些刚使用Git的小伙伴们介绍一下常遇到的小问题。 1:拼写错误。这应该是每个初学者都会犯得错误,当出现这种错误还是比较好排…

供应链管理平台开发指南:从食堂采购系统源码开始

本篇文章,小编将围绕如何从食堂采购系统源码出发,构建一个完整的供应链管理平台进行详细解读,帮助开发人员掌握实现技术要点,并为企业打造高效的供应链系统提供技术参考。 一、供应链管理平台的核心功能概述 供应链管理平台的核心…

RK3568 Android 11 蓝牙BluetoothA2dpSink 获取用于生成频谱的PCM

Android 中的 A2DP Sink A2DP Sink 在 Android 系统中主要用于 接收 其他蓝牙设备(如手机、平板、电脑等)发送过来的 高质量的立体声音频。简单来说,它让你的 Android 设备可以充当一个 蓝牙音箱 或 耳机 的角色。 核心功能: 接…

中国农村政策与改革统计年报(2015-2022年)

中国农村经营管理统计年报、政策与改革统计年报(2015-2022年) 数据年限:2015-2022年,目前最新 数据格式:pdf 数据范围:全国各省市自治区(不含港澳台) 数据内容:《中国农村…

win系统安装mysql,使用mysqldump,pycharm使用mysqldump,避坑

文章目录 下载mysql的win客户端设置系统环境变量验证是否可用pycharm使用mysqldump异常问题排查 下载mysql的win客户端 官网下载地址如果下载旧版本,需自行到Archives里面找 本人使用的是mysql5.7,找到相应版本后,点击Download下载 设置系统…

多模态大模型中,融合后如何知道最终结果受哪种模态影响更大?

本篇介绍多模态大模型中如何基于最终结果分析各模态的影响。 具身智能被众多大佬看好,通往AGI的路最终肯定需要多个模态的大模型互相融合。多个模态配合好也是有可能去构建一个模拟现实的世界模型的。 最近一直在研究和尝试多模态大模型在一些VQA领域的前瞻研究和…

9、Django Admin优化查询

如果你的Admin后台中有很多计算字段,那么你需要对每个对象运行多个查询,这会使你的Admin后台变得非常慢。要解决此问题,你可以重写管理模型中的get_queryset方法使用annotate聚合函数来计算相关的字段。 以下示例为Origin模型的中ModelAdmin…

CSS总结——瀑布流布局

瀑布流布局 瀑布流布局是一种新型的布局方式,可以将大小不一的图片完整的显示在页面上,并且在杂乱的布局中保持着一定的美感,今天学习了一下如何使用瀑布流布局,总结了有以下三种方式。(瀑布流还可以使用grid布局实现…

Nginx 部署前端 Vue 项目实战指南

一、环境准备 1. 安装 Nginx 首先,需要在服务器上安装 Nginx。Nginx 是一款轻量级、高性能的 HTTP 和反向代理服务器。安装方式因操作系统而异。 Linux 系统(以 Ubuntu 为例): sudo apt-get update sudo apt-get install nginxWi…

【Android】Material Design编写更好的UI

Toolbar 对于控件ActionBar我们非常熟悉,就是我们常见的标题栏,但ActionBar只能位于活动的顶部,因此我们更建议使用Toolbar。在新建一个项目的时候都是默认显示ActionBar,我们要使用Toolbar就需要先将标题栏改为不显示 先来看看…

HMI触屏网关-VISION如何与Node-red通信

上文:HMI触屏网关-VISION如何与Modbus TCP从机通信-CSDN博客 1. Node-red启用HTTP监听 HTTP监听,用于模拟WebAPI服务端,接收WebAPI客户端GET请求。 启用HTTP监听服务,选择请求方式GET;URL自定义,本示例设…

LavaDome:一款基于ShadowDOM的DOM树安全隔离与封装工具

关于LavaDome LavaDome是一款针对HTML代码安全和Web安全的强大工具,该工具基于ShadowDOM实现其功能,可以帮助广大研究人员实现安全的DOM节点/树隔离和封装。 在当今的Web标准下,尚无既定方法可以安全地选择性地隔离DOM子树。换句话说&#x…

【ceph学习】rgw网关进程如何启动

rgw 网关进程启动 主要在rgw_main.cc的main函数中,主要涉及一些关键线程启动、前端服务器(beast等)启动、后端存储模块启动(rados)、perf和log启动等。 流程图关键节点如下: 1、beast的启动 2、rados的启…

Android Camera系列(一):SurfaceView+Camera

心行慈善,何需努力看经—《西游记》 本系列主要讲述Android开发中Camera的相关操作、预览方式、视频录制等,项目结构代码耦合性低,旨在帮助大家能从中有所收获(方便copy :) ),对于个人来说也是一…