单片机 PWM输入捕获【学习记录】
前言
学习是永无止境的,就算之前学过的东西再次学习一遍也能狗学习到很多东西,输入捕获很早之前就用过了,但是仅仅是照搬例程没有去进行理解。温故而知新!
定时器
定时器简介
定时器的分类
高级定时器 通用定时器 基本定时器,针对不同情况可以选择自己所需要的定时器,以下是这几种定时器的主要功能。
高级定时器:
- 计数器单元
- 输入捕获
- 重复计数器
- PWM模式
- 互补输出和死区插入
- 支持针对定位的增量(正交)编码器和霍尔传感器电路
- 刹车功能
- DMA功能
通用定时器:
- 计数器单元
- 输入捕获
- PWM模式
- 支持针对定位的增量(正交)编码器和霍尔传感器电路
- DMA功能
基本定时器:
- 计数器单元
- DMA功能
定时器的功能
我们使用定时器很多时候使用都是用做于计数作用,同样也可以作为PWM输出,输入捕获(脉宽测量,频率检测)等等,有的时候我们还会使用DMA+PWM输出这样的功能,总之定时器对于我们进行产品开发是必不可少的。
定时器的配置
主要寄存器
这里我使用的是航芯ACM32FP0X系列的单片机,不过其他单片机用法也是一样的。

这里我们主要关注以上六个寄存器,中断使能寄存器、状态寄存器、事件产生寄存器、预分频寄存器、自动加载寄存器、捕获/比较寄存器。其他的寄存器不是说不重要,只是在本次实验中主要理解这几个寄存器就好。
PWM配置
因为本次实验没有使用外置的脉冲发生器,所以使用单片机上另一个通用定时器来配置PWM,然后使用高级定时器去进行输入捕获。
TIM_Handler_PWM.Instance = TIM15;TIM_Handler_PWM.Init.ARRPreLoadEn = TIM_ARR_PRELOAD_ENABLE; TIM_Handler_PWM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; TIM_Handler_PWM.Init.CounterMode = TIM_COUNTERMODE_UP; TIM_Handler_PWM.Init.RepetitionCounter = 0; TIM_Handler_PWM.Init.Prescaler = (timer_clock/TIM_CLOCK_FREQ)*1 - 1; if (timer_clock%TIM_CLOCK_FREQ > TIM_CLOCK_FREQ/2) {TIM_Handler_PWM.Init.Prescaler = TIM_Handler_PWM.Init.Prescaler + 1; }TIM_Handler_PWM.Init.Period = (TIM_CLOCK_FREQ/100000)*20 - 1; // period = 1ms
首先是常规的配置,这里我选择的是定时器15作为PWM口进行输出,然后不分频所以APB的时钟就是定时器的时钟。然后就是自动重装载值ARR,和预分配系数Prescaler的配置;这两个参数共同决定了配置的PWM输出极限频率是多少。
PWM输出频率 Fre = 。
这里来解析一下为什么要使用 TIM_CLOCK_FREQ这个参数:
TIM_CLOCK_FREQ 代表的是定时器经过分频之后能够达到的极限频率,我们可以来推导一下,timer_clock(也就是主时钟APBCLK)分频之后 就是 ,
简单约去公约数,得到的就是TIM_CLOCK_FREQ,所以当重装载值为1的时候TIM_CLOCK_FREQ就是最高频率。再来解释一下周期是怎么得出的,由于1s之内计数器计数了TIM_CLOCK_FREQ次,所以一次需要的时间是1/TIM_CLOCK_FREQ,所以周期和重装载值之间的关系就是T= ,这里除以1000的原因是将秒的单位换算成毫秒。OK,也不知道讲清楚了没有,之前也搞不懂这个关系式,后来推导出来的时候还感觉蛮巧妙的。
配置完这些再配置一下模式和占空比(CCR)和引脚就行了
输入捕获的配置
TIM_IC_InitTypeDef Tim_IC_Init_Para; TIM_Handler.Instance = TIM1;TIM_Handler.Init.ARRPreLoadEn = TIM_ARR_PRELOAD_ENABLE; TIM_Handler.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; TIM_Handler.Init.CounterMode = TIM_COUNTERMODE_UP; TIM_Handler.Init.RepetitionCounter = 0; TIM_Handler.Init.Prescaler = 0; TIM_Handler.Init.Period = 0xFFFF; // max period TIM1_MSP_Pre_Init(&TIM_Handler); HAL_TIMER_Base_Init(&TIM_Handler); Tim_IC_Init_Para.TIFilter = TIM_TI1_FILTER_LVL(0); // no filter Tim_IC_Init_Para.ICPolarity = TIM_SLAVE_CAPTURE_ACTIVE_RISING_FALLING; Tim_IC_Init_Para.ICPrescaler = TIM_IC1_PRESCALER_1; Tim_IC_Init_Para.ICSelection = TIM_ICSELECTION_DIRECTTI; // TI1FP1 HAL_TIMER_Capture_Config(TIM_Handler.Instance, &Tim_IC_Init_Para, TIM_CHANNEL_1); TIM1_MSP_Post_Init();
上面也是一些很常规的配置,配置了分频系数(为1意味着定时器的频率和APB时钟一致),重装载值为0xFFFF,这些数据传达了一个怎样的信息呢?说明了使用输入捕获的频率可高达64MHz(APB时钟为64MHz),说明捕获精度可以达到1/64000000 s,也就是15ns,最长捕获时间间隔为1023us(15ns * 0xFFFF)。然后下一个就是设置捕获触发模式,可能不同的单片机的库设置起来会有细微差别,但是大致意思是相同的。由于我们需要收集这些鞋数据然后在串口上打印出来所以我这里使用了中断触发,在中断里面收集数据。
HAL_TIMER_Clear_Capture_Flag(&TIM_Handler, TIM_CHANNEL_1);NVIC_ClearPendingIRQ(TIM1_CC_IRQn); NVIC_ClearPendingIRQ(TIM1_BRK_UP_TRG_COM_IRQn);NVIC_EnableIRQ(TIM1_CC_IRQn); NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn); HAL_TIMER_Base_Init(&TIM_Handler); HAL_TIM_ENABLE_IT(&TIM_Handler, TIM_IT_CC1);HAL_TIM_ENABLE_IT(&TIM_Handler, TIMER_INT_EN_UPD); //计数器向上溢出/向下溢出 用于记录更新次数HAL_TIM_Capture_Start(TIM_Handler.Instance, TIM_CHANNEL_1);
当然这里还加了个溢出中断,用于辅助捕获计算超出最大捕获长度的电平时间,具体思路就是当计数器溢出的时候在事件更新中断里面设置一个变量进行加加。
可以大致看一下捕获中断里面的函数,主要是获取触发了捕获中断之后将数据写入事先定义好的数组,然后在定义一个变量进行计数。
void TIM1_CC_IRQHandler(void)
{uint32_t status; status = TIM1->SR; if ( (status & TIMER_SR_CC1IF) && ((TIM1->CCMR1) & (BIT0|BIT1)) ) {if(flag1 == 1)flag2 = 1;flag1 = 1;Capture_data[0][capture_times] = TIM1->CCR1;}if ((status & TIMER_SR_CC2IF) && ((TIM1->CCMR1) & (BIT8|BIT9)) ) {Capture_data[1][capture_times] = TIM1->CCR2; }capture_times++; NVIC_ClearPendingIRQ(TIM1_CC_IRQn);
}
然后在主函数里面获取标志位之后打印显示就可以了

这样在主函数当中我们就可以是去使用到这些数据然后打印到串口。这里要注意一点我使用的是双边沿触发所以打印出来的不是一个周期,而是两段占空比的数值。
当然这里我还使用了DMA+PWM进行PWM输出,如果再讲下去就有点多了,这部分内容网上也有很多。

总结
输入捕获是高级定时器和通用定时器才有的功能,主要通过设置触发边沿和设置捕获频率来对脉宽进行一个测量,得出脉宽之后我们就可以很容易地计算出频率和周期。
相关文章:
单片机 PWM输入捕获【学习记录】
前言 学习是永无止境的,就算之前学过的东西再次学习一遍也能狗学习到很多东西,输入捕获很早之前就用过了,但是仅仅是照搬例程没有去进行理解。温故而知新! 定时器 定时器简介 定时器的分类 高级定时器 通用定时器 基本定时器…...
3.1、前端异步编程(超详细手写实现Promise;实现all、race、allSettled、any;async/await的使用)
前端异步编程规范 Promise介绍手写Promise(resolve,reject)手写Promise(then)Promise相关 API实现allraceallSettledany async/await和Promise的关系async/await的使用 Promise介绍 Promise是一个类,可以翻…...
3.1. 马氏链-马氏链的定义和示例
马氏链的定义和示例 马氏链的定义和示例1. 马氏链的定义2. 马氏链的示例2.1. 随机游走2.2. 分支过程2.3. Ehrenfest chain2.4. 遗传模型2.5. M/G/1 队列 马氏链的定义和示例 1. 马氏链的定义 对于可数状态空间的马氏链, 马氏性指的是给定当前状态, 其他过去的状态与未来的预测…...
红利之外的A股底仓选择:A50
内容提要 华泰证券指出,当前指数层面下行风险不大,市场再入震荡期下,可关注三条配置线索:1)A50为代表的产业巨头;2)以家电/食饮/物流/出版为代表的稳健消费龙头,3)消费电…...
wondershaper 一款限制 linux 服务器网卡级别的带宽工具
文章目录 一、关于wondershaper二、文档链接三、源码下载四、限流测试五、常见报错1. /usr/local/sbin/wondershaper: line 145: tc: command not found2. Failed to download metadata for repo ‘appstream‘: Cannot prepare internal mirrorlist: No URLs.. 一、关于wonder…...
独孤思维:盲目进群,根本赚不到钱
01 我看有些伙伴,对标同行找写作素材和灵感的时候。 喜欢把对标文章发给ai提炼总结。 这个方法好是好,但是,有一个问题。 即,无法感受全文的细节。 更无法感受作者的情感和温度。 就好像电影《记忆大师》一样。 我提取了记…...
针对indexedDB的简易封装
连接数据库 我们首先创建一个DBManager类,通过这个类new出来的对象管理一个数据库 具体关于indexedDB的相关内容可以看我的这篇博客 indexedDB class DBManager{}我们首先需要打开数据库,打开数据库需要数据库名和该数据库的版本 constructor(dbName,…...
网络编程--网络理论基础(二)
这里写目录标题 网络通信流程mac地址、ip地址arp协议交换机路由器简介子网划分网关 路由总结 为什么ip相同的主机在与同一个互联网服务通信时不冲突公网ip对于同一个路由器下的不同设备,虽然ip不冲突,但是因为都是由路由器的公网ip转发通信,接…...
Python MongoDB 基本操作
本文内容主要为使用Python 对Mongodb数据库的一些基本操作整理。 目录 安装类库 操作实例 引用类库 连接服务器 连接数据库 添加文档 添加单条 批量添加 查询文档 查询所有文档 查询部分文档 使用id查询 统计查询 排序 分页查询 更新文档 update_one方法 upd…...
Node.js 入门:
Node.js 是一个开源、跨平台的 JavaScript 运行时环境,它允许开发者在浏览器之外编写命令行工具和服务器端脚本。以下是一些关于 Node.js 的基础教程: 1. **Node.js 入门**: - 了解 Node.js 的基本概念,包括它是一个基于 Chro…...
java8 List的Stream流操作 (实用篇 三)
目录 java8 List的Stream流操作 (实用篇 三) 初始数据 1、Stream过滤: 过滤-常用方法 1.1 筛选单元素--年龄等于18 1.2 筛选单元素--年龄大于18 1.3 筛选范围--年龄大于18 and 年龄小于40 1.4 多条件筛选--年龄大于18 or 年龄小于40 and sex男 1.5 多条件筛…...
机器学习python实践——数据“相关性“的一些补充性个人思考
在上一篇“数据白化”的文章中,说到了数据“相关性”的概念,但是在统计学中,不仅存在“相关性”还存在“独立性”等等,所以,本文主要对数据“相关性”进行一些补充。当然,如果这篇文章还能入得了各位“看官…...
MySQL——触发器(trigger)基本结构
1、修改分隔符符号 delimiter $$ $$可以修改 2、创建触发器函数名称 create trigger 函数名 3、什么样在操作触发,操作哪个表 after :……之后触发 before :……之后触发 insert :……之后触发 update :……之后触…...
数字孪生定义及应用介绍
数字孪生定义及应用介绍 1 数字孪生(Digital Twin, DT)概述1.1 定义1.2 功能1.3 使用场景1.4 数字孪生三步走1.4.1 数字模型1.4.2 数字影子1.4.3 数字孪生 数字孪生地球平台Earth-2 参考 1 数字孪生(Digital Twin, DT)概述 数字孪…...
数据赋能(122)——体系:数据清洗——技术方法、主要工具
技术方法 数据清洗标准模型是将数据输入到数据清洗处理器,通过一系列步骤“清理”数据,然后以期望的格式输出清理过的数据。数据清洗从数据的准确性、完整性、一致性、惟一性、适时性、有效性几个方面来处理数据的丢失值、越界值、不一致代码、重复数据…...
【SCAU数据挖掘】数据挖掘期末总复习题库简答题及解析——中
1. 某学校对入学的新生进行性格问卷调查(没有心理学家的参与),根据学生对问题的回答,把学生的性格分成了8个类别。请说明该数据挖掘任务是属于分类任务还是聚类任务?为什么?并利用该例说明聚类分析和分类分析的异同点。 解答: (a)该数据…...
2024年注册安全工程师报名常见问题汇总!
注册安全工程师报名 24年注册安全工程师报名已正式拉开序幕,报名时间为6月18日—7月10日,考试时间为10月26日—10月27日。 目前经有12个地区公布了2024年注册安全工程师报名时间: 注册安全工程师报名信息完善 根据注安报名系统提示&am…...
JRebel-JVMTI [FATAL] Couldn‘t write to C:\Users\中文用户名-完美解决
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 热部署下载参考博客解决第一步第二步第三步:第四步: 热部署下载 下载后启动报错:JRebel-JVMTI [FATAL] Couldn’t write to C:\…...
STM32基于DMA数据转运和AD多通道
文章目录 1. DMA数据转运 1.1 初始化DMA步骤 1.2 DMA的库函数 1.3 设置当前数据寄存器 1.4 DMA获取当前数据寄存器 2. DMA数据转运 2.1 DMA.C 2.2 DMA.H 2.3 MAIN.C 3. DMAAD多通道 3.1 AD.C 3.2 AD.H 3.3 MAIN.C 1. DMA数据转运 对于DMA的详细解析可以看下面这篇…...
安卓应用开发——Android Studio中通过id进行约束布局
在Android开发中,布局通常使用XML文件来描述,而约束(如相对位置、大小等)可以通过多种方式实现,但直接使用ID进行约束并不直接对应于Android的传统布局系统(如LinearLayout、RelativeLayout等)。…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...
Linux中《基础IO》详细介绍
目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...
