STM32 TIM输入捕获 测量频率
输入捕获简介:
IC(Input Capture)输入捕获
输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数
每个高级定时器和通用定时器都拥有4个输入捕获通道
可配置为PWMI模式,同时测量频率和占空比
可配合主从触发模式,实现硬件全自动测量
频率测量:


输入捕获基本结构

主从触发模式:

接线图:

代码配置:
实现功能在屏幕上显示频率,频率通过ARR与PSC共同控制,而ARR也涉及到占空比的改变,所以我们选择更改PSC,在初始化后单独写一个函数更改PSC
需要调用到这个函数,单独用来写入PSC的函数
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);
void pWM_SetPrescaler(uint16_t Prescaler)
{TIM_PrescalerConfig(TIM2, Prescaler, TIM_PSCReloadMode_Immediate);}

函数介绍:
用结构体配置输入捕获单元的函数
注意:输入捕获与输出比较都有4个通道,OCInit,4个通道每个通道各占一个函数,而ICInit,4个通道是共用一个函数的,在结构体里会有一个参数,来配置具体哪个通道,因为可能有交叉通道的配置,所以函数合在一起比较方便
void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
这个函数与上一个函数类似,都是用于初始化输入捕获单元的,但是上一个函数只是单一的配置一个通道,这个函数可以快速配置两个通道
void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
这个函数可以给输入捕获结构体赋一个初始值
void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct);
下面三个对应主从触发模式:
选择输入触发源TRGI
void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
选择输出触发源TRGO
void TIM_SelectOutputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_TRGOSource);
选择从模式
void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);
下面四个函数,分别单独配置通道1、2、3、4的分频器
void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC);
分别读取4个通道的CCR,这4个函数和SetCompare1、2、3、4是对应的,输出比较模式下,CCR是只写的,要用SetCompare写入,输入捕获模式下,CCR是只读的,要用GetCapture读出
uint16_t TIM_GetCapture1(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture2(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture3(TIM_TypeDef* TIMx);
uint16_t TIM_GetCapture4(TIM_TypeDef* TIMx);
输入捕获代码配置
根据结构图配置
1.定义结构体变量
定义GPIO、TimeBase时基单元、IC输入捕获单元结构体变量
//定义结构体变量
GPIO_InitTypeDef GPIO_InitStructure;//定义GPIO结构体变量
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//定义时基单元结构体变量
TIM_ICInitTypeDef TIM_ICInitStructure; //定义IC结构体变量
2.RCC开启时钟
把GPIO和TIM的时钟打开
//RCC开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启GPIO A族时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//开启TIM3时钟
3.GPIO初始化
把GPIO配置成输入模式,一般选择上拉输入或者浮空输入模式,这里选择TIM3_CH1通道,根据引脚图为PA6,所以这次配置这个引脚,模式选择上拉输入
//配置GPIOGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//配置引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);
4.配置时基单元
让CNT计数器在内部时钟的驱动下自增运行,这里的周期给到最大,PSC的值给72 - 1,这样标准频率就是72M / 72 = 1MHz 方便计算。
//配置时基单元TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//选择向上计数
TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1; //ARR周期的值
TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1; //预分频器PSC的值
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器的值TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
5.配置输入捕获单元
包括滤波器、极性、直连通道还是交叉通道、分频器这些参数
//配置输入捕获单元TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;//选择通道 我们这里选择的是TIM3的CH1
TIM_ICInitStructure.TIM_ICFilter = 0xF;//选择输入捕获的滤波器
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;//边沿检测极性选择 选择上升沿触发
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;//分频器
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//选择触发信号从那个引脚输入TIM_ICInit(TIM3, &TIM_ICInitStructure);
6.选择从模式的触发源
触发源选择为TI1FP1,这里调用一个库函数,给一个参数就行
//配置主从模式触发源
TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//配置TRIG的触发源
7.选择触发之后执行的操作
执行Reset操作,这里也是调用一个库函数就行了
TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//配置从模式为Reset
最后调用TIM_CMD函数开启定时器,当我们需要读取最新一个周期的频率时,直接读取CCR寄存器,然后按照fc/N,计算一下就行了。
//启动定时器
TIM_Cmd(TIM3,ENABLE);
整体代码:
void IC_Init(void)
{//定义结构体变量GPIO_InitTypeDef GPIO_InitStructure;//定义GPIO结构体变量TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//定义时基单元结构体变量TIM_ICInitTypeDef TIM_ICInitStructure; //定义IC结构体变量//RCC开启时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启GPIO A族时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//开启TIM3时钟//配置GPIOGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//配置引脚GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);//配置时基单元TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//选择向上计数TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1; //ARR周期的值TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1; //预分频器PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器的值TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);//配置输入捕获单元TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;//选择通道 我们这里选择的是TIM3的CH1TIM_ICInitStructure.TIM_ICFilter = 0xF;//选择输入捕获的滤波器TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;//边沿检测极性选择 选择上升沿触发TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;//分频器TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;//选择触发信号从那个引脚输入TIM_ICInit(TIM3, &TIM_ICInitStructure);//配置主从模式触发源TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//配置TRIG的触发源TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//配置从模式为Reset//启动定时器TIM_Cmd(TIM3,ENABLE);}
功能代码:
测量频率,在频幕上显示
uint32_t IC_GetFreg(void)
{return 1000000 / (TIM_GetCapture1(TIM3) + 1);}
主函数:
#include "IC.h"
int main(void)
{LED_Init();OLED_Init();PWM_Init();IC_Init();pWM_SetPrescaler(720 - 1); //Freg = 72M / (PSC + 1) / 100PWM_SetComPer(50); //Duty = CCR / 100OLED_ShowString(1, 1, "Freg:00000Hz");while(1){OLED_ShowNum(1, 6, IC_GetFreg(), 5);}}

相关文章:
STM32 TIM输入捕获 测量频率
输入捕获简介: IC(Input Capture)输入捕获 输入捕获模式下,当通道输入引脚出现指定电平跳变时,当前CNT的值将被锁存到CCR中,可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数 每个高级定时器…...
Autosar-以太网是怎么运行的?(Davinci配置部分)
写在前面: 入行一段时间了,基于个人理解整理一些东西,如有错误,欢迎各位大佬评论区指正!!! 目录 1.Autosar ETH通讯软件架构 2.Ethernet MCAL配置 2.1配置对应Pin属性 2.2配置TXD引脚 2.3配…...
16.[前端开发]Day16-HTML+CSS阶段练习(网易云音乐五)
完整代码 网易云-main-left-rank(排行榜) <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name&q…...
langchain 实现多智能体多轮对话
这里写目录标题 工具定义模型选择graph节点函数定义graph 运行 工具定义 import random from typing import Annotated, Literalfrom langchain_core.tools import tool from langchain_core.tools.base import InjectedToolCallId from langgraph.prebuilt import InjectedSt…...
Java-数据结构-优先级队列(堆)
一、优先级队列 ① 什么是优先级队列? 在此之前,我们已经学习过了"队列"的相关知识,我们知道"队列"是一种"先进先出"的数据结构,我们还学习过"栈",是"后进先出"的…...
C++实现状态模式
首先上代码: #include <iostream> #include <memory>class Context;class State { public:virtual void Handle(Context * context) 0; //纯虚函数virtual ~State() default; //虚析构函数 };//创建状态A class ConcreateStateA : public State{…...
FreeRTOS学习笔记2:FreeRTOS的基础知识
1.FreeRTOS介绍 FreeRTOS是一个免费的嵌入式实时操作系统,同时它在市面上也是一款主流的操作系统,是工作上必不可少的技能。它具有以下六种特点: 1.免费开源:在商业产品中使用,无潜在商业风险,无需担心。 2…...
计算机网络之计算机网络的分类
计算机网络可以根据不同的角度进行分类,以下是几种常见的分类方式: 1. 按照规模和范围: 局域网(LAN,Local Area Network):覆盖较小范围(例如一个建筑物或校园)…...
从理论到实践:Linux 进程替换与 exec 系列函数
个人主页:chian-ocean 文章专栏-Linux 前言: 在Linux中,进程替换(Process Substitution)是一个非常强大的特性,它允许将一个进程的输出直接当作一个文件来处理。这种技术通常用于Shell脚本和命令行操作中…...
Flutter常用Widget小部件
小部件Widget是一个类,按照继承方式,分为无状态的StatelessWidget和有状态的StatefulWidget。 这里先创建一个简单的无状态的Text小部件。 Text文本Widget 文件:lib/app/app.dart。 import package:flutter/material.dart;class App exte…...
微信小程序实战0 设置
1.调节模拟器到右侧位置 2.设置编辑页面的字体和行距。...
2025开源DouyinLiveRecorder全平台直播间录制工具整合包,多直播同时录制、教学直播录制、教学视频推送、简单易用不占内存
一、DouyinLiveRecorder软件介绍(文末提供下载) 官方地址:GitHub - ihmily/DouyinLiveRecorder 本文信息来源于作者GitHub地址 一款简易的可循环值守的直播录制工具,基于FFmpeg实现多平台直播源录制,支持自定义配置录制…...
使用 postman 测试思源笔记接口
思源笔记 API 权鉴 官方文档-中文:https://github.com/siyuan-note/siyuan/blob/master/API_zh_CN.md 权鉴相关介绍截图: 对应的xxx,在软件中查看 如上图:在每次发送 API 请求时,需要在 Header 中添加 以下键值对&a…...
当WebGIS遇到智慧文旅-以长沙市不绕路旅游攻略为例
目录 前言 一、旅游数据组织 1、旅游景点信息 2、路线时间推荐 二、WebGIS可视化实现 1、态势标绘实现 2、相关位置展示 三、成果展示 1、第一天旅游路线 2、第二天旅游路线 3、第三天旅游路线 4、交通、订票、住宿指南 四、总结 前言 随着信息技术的飞速发展&…...
阿里最新普通x231 逆向分析
声明: 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 逆向前言 12月份的时候更新了过一次…...
php的使用及storm环境部署
php语法 环境搭建:在小皮中新建网站,注意先填写域名再点击选择根目录。 成功创建网站后,打开发现forbidden,因为新建的网站里是空的,需要新建index.php文件----> 在Phpstorm中左上角打开文件,打开那个文…...
高可用 Keepalived 服务部署流程
一、配置文件 vim /etc/keepalived/keepalived.confGLOBAL CONFIGURATION --- 全局配置部分VRRPD CONFIGURATION --- VRRP协议配置部分LVS CONFIGURATION --- LVS服务管理配置部分[rootlb01 ~]# cat /etc/keepalived/keepalived.…...
【新春特辑】2025年1月科技浪潮中的AI最新时事与科技趋势
2025年1月科技浪潮中的AI最新时事与科技趋势 一、AI科技时事 人工智能代理(AI Agent)的发展 最新进展:人工智能代理正逐步成为科技领域的新热点。这些代理能够自主执行特定任务,如管理日程、回复邮件等。然而,它们仍…...
解决Django非ORM模型提示初始化request问题
提问 Django在DRF时候自定义显示一些非model的字段提示TypeError: Field.__init__() got an unexpected keyword argument request 解答1 错误提示 TypeError: Field.__init__() got an unexpected keyword argument request 显示在创建序列化器实例时,传递了一个…...
G. XOUR
题目链接:Problem - G - Codeforces 题目大意:给你一个n长的序列, 其中你可以将a[i] XOR a[j] 的值 严格小于4的数对进行交换。 你可以操作任何几次, 让最后的数列最小。如果在 x 和 y 不同的第一个位置, xi<yi &…...
CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
