【江科大】STM32:TIM输入捕获(理论部分)

文章目录

    • IC(Input Capture)输入捕获
    • PWM频率
  • 知识点补充
    • 1. 滤波器的工作原理:
    • 2. 边沿检测器:
    • 自动化清零CNT
    • 输入捕获的基本结构
    • PWMI基本结构
      • 滤波器和分频器的区别
      • 误差分析
      • pwm.c
      • main.c
      • IC.c
    • PWM模式测频率和占空比

IC(Input Capture)输入捕获

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

(输入捕获,接收到输入信号,执行CNT锁存到CCR的动作)
(输出比较,是根据CNT和CCR的比较关系执行输出动作)
在这里插入图片描述
测频法:在闸门时间T内,对上升沿计次,得到N,则频率 (适合测量高频信号
f x = N / T f_x=N / T fx=N/T N越大,误差和越小 ,因为容易计数遗漏 (记录的次数多了,一次记错也影响不大)
测周法:两个上升沿内,以标准频率fc计次,得到N ,则频率 f = 1/t (通过计时器记录一个上升加一个下降沿的时间)(适合测量低频信号
f x = f c / N f_x=f_c / N fx=fc/N N越大,误差和越小 多计算一些数
在这里插入图片描述
那多高算高频率,多低算低频率。就涉及到中界频率:
中界频率:测频法与测周法误差相等的频率点
f m = √ f c / T f_m=√f_c / T fm=fc/T
测量的是数字信号。

  • 因此测频法适用于频率大于中界频率,测周法适合小于中界频率。
  • 红外射频,上升沿计次+1,结合定时器,在中断里每隔1S取一下计次值,同时清零,为下一次做准备。
  • CNT计数器是由内部的标准时钟驱动的,所以CNT的数值,可以用来计算两个上升沿之间的时间间隔,这就是一个周期,取个倒数 就是测周法测量的频率
  • 每来一个上升沿,取CNT的值自动存到CCR里面,CCR捕获到的值就是就是计数值N,CNT的驱动时钟就是fc ,fc/N就得到了待测信号的频率。
  • 计数器计时频率:提高标准频率fc,频率就会越大
    fc = CK_CNT =CK_PSC/(PSC+1) CK_PSC = 72MHZ
    捕获后清零的操作,用的是主从触发模式。

PWM频率

Freq = CK_PSC / (PSC + 1) / (ARR + 1)
在这里插入图片描述

知识点补充

1. 滤波器的工作原理:

以采样频率对输入信号进行采样,当连续N个值都为高电平,输出才为高电平,反之亦然,如果信号出现高频抖动,导致连续 采样N个值不全都一样。那输出不会变化。达到滤波的效果。
特点
采样频率越低,采样个数N越大,滤波器效果就越好。
如果噪声比较大,就将采样频率从的值调大一点,就可以过滤噪声

2. 边沿检测器:

用来捕获上升沿或者下降沿。

  1. CC1P:用来选择极性
    最终到达Tl1FP1触发信号,选择数据选择器。
    通过数据选择器进入捕获电路
    到达Tl1FP2触发信号,连接到通道2的后续电路,
    同样通道2还有Tl2FP1,连接通道1的后续电路
    还有TI2FP2,连接通道2的后续电路。共有4种连接方式
  2. CC1S:配置数据选择器
  3. ICPS:配置分频器系数
  4. CC1E控制输出使能或失能,如果使能输出,输出的产生指定边沿信号,经过层层电路,到达捕获电路,就可以让CNT的值转运到CCR里面。
    每捕获一次CNT,都要将CNT清零,方便下一次捕获,硬件电路自动完成清零CNT,也就是图中Tl1FP1连接的从模式来处理(自动化)。

自动化清零CNT

在这里插入图片描述
在这里插入图片描述

输入捕获的基本结构

在这里插入图片描述
只有一个通道只能用来测频率。

PWMI基本结构

fx=fc/N N=CNT
因为CNT在清零后一直++
CCR1是一整个周期的计数值
CCR2是高电平期间的计数值
占空比:CCR2/CCR1
在这里插入图片描述

这里可以看出来 N = CCR1

uint32_t IC_GetFreq(void)
{                     // fx =fc/n   fc  = CK_PSC / (PSC + 1)  -> 72000000Hz/72 = 1MHZreturn 1000000/(TIM_GetCapture1(TIM3)+1); // 占空比= fc/N   N就是读取CCR的值
}
uint32_t IC_GetDuty(void)   //获得PWM的占空比
{return TIM_GetCapture2(TIM3)/TIM_GetCapture1(TIM3);  //CRR2/CRR1
}

滤波器和分频器的区别

滤波器不会改变信号的原有频率,只会滤除高频噪音。
分频器是对信号进行分频。改变了原有的频率

误差分析

除了由±1误差,还有晶振误差

通过直接在PWM.c文件中修改 PSC和ARR不方便,因此创建一个函数

  1. 据PWM频率:
    Freq = CK_PSC / (PSC + 1) / (ARR + 1) :
    72MHZ/(PSC+1)/(ARR+1) = 1000 PSC+1 =72000000/1000000=720HZ
  2. PWM占空比:
    Duty = CCR / (ARR + 1)
    因此修改ARR会同时影响 频率和占空比,所以修改PSC调节频率最合适
    固定ARR = 100-1;
    CCR的值 直接就是占空比
    在这里插入图片描述

#include “stm32f10x.h” // Device header
//1.配置GPIO
//2.选择内部时钟
//3.配置时基单元
//4.配置输入捕获单元
//5.选择从模式触发源
//6.选择触发之后执行的操作
//7.开启定时器

pwm.c

在这里插入图片描述

main.c

在这里插入图片描述

IC.c

void IC_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//给TIM2使能RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//给GPIO使能GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Mode =  GPIO_Mode_IPU;  //上拉输入,GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;   //根据引脚表的出CH_1所在引脚时PA0GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStruct);TIM_InternalClockConfig(TIM3); //选择内部时钟                           //时基单元TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;  //每一个时钟后面都会加一个滤波器,作用就是为是信号更加稳定,使用的采样的方式,在输入的脉冲中采样,按照n/f,因此采样系数越大,延迟越大TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInitStruct.TIM_Period = 65536-1;  //ARR =100TIM_TimeBaseInitStruct.TIM_Prescaler = 72-1;  // psc = 720//预分频器,72MHZ进行7200分频 ,72000/7200 = 10KHZ  1ms = 1KHZ  10KHZ下记10000个数 10000/10 =1000kHZ = 1STIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);//初始化输入捕获单元TIM_ICInitTypeDef TIM_ICInitStruct;TIM_ICInitStruct.TIM_Channel =  TIM_Channel_1 ;TIM_ICInitStruct.TIM_ICFilter = 0xF;  //数值越大,采样效果越好(以采样频率对输入信号进行采样,当连续N个值都为高电平,输出才为高电平,反之亦然,如果信号出现高频抖动,导致连续 采样N个值不全都一样。那输出不会变化。达到滤波的效果。)TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising; //极性选择    上升沿,下降沿 双沿TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;//设置分频值TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; ///通道选择 。直连,交叉TIM_ICInit(TIM3,&TIM_ICInitStruct);//配置触发源TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);//选择从模式 自动清理CNTTIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//启动时基单元TIM_Cmd(TIM3,ENABLE);
}
uint32_t IC_GetFreq(void)
{                     // fx =fc/n   fc  = CK_PSC / (PSC + 1)  -> 72000000Hz/72 = 1MHZreturn 1000000/(TIM_GetCapture1(TIM3)+1); // freq= fc/N   N就是读取CCR的值
}

在这里插入图片描述

PWM模式测频率和占空比

uint32_t IC_GetFreq(void)
{                     // fx =fc/n   fc  = CK_PSC / (PSC + 1)  -> 72000000Hz/72 = 1MHZreturn 1000000/(TIM_GetCapture1(TIM3)+1); // 占空比= fc/N   N就是读取CCR的值
}
uint32_t IC_GetDuty(void)
{return (TIM_GetCapture2(TIM3)+1)*100/(TIM_GetCapture1(TIM3)+1);  //*100可以变为整数
}

在这里插入图片描述

//配置成两个通道同时捕获一个引脚
//初始化输入捕获单元
TIM_ICInitTypeDef TIM_ICInitStruct;
TIM_ICInitStruct.TIM_Channel =  TIM_Channel_1 ;
TIM_ICInitStruct.TIM_ICFilter = 0xF;  //数值越大,采样效果越好(以采样频率对输入信号进行采样,当连续N个值都为高电平,输出才为高电平,反之亦然,如果信号出现高频抖动,导致连续 采样N个值不全都一样。那输出不会变化。达到滤波的效果。)
TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising; //极性选择    上升沿,下降沿 双沿
TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;//设置分频值
TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI; ///通道选择 。直连,交叉
TIM_ICInit(TIM3,&TIM_ICInitStruct);//如何配置成两个通道同时捕获一个引脚,采用下面的函数
//只支持通道1和通道2
TIM_PWMIConfig(TIM3,&TIM_ICInitStruct);  //这个函数会自动将配置呈相反的,上升沿变下降沿,直连变交叉//配置触发源
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1);//选择从模式 自动清理CNTTIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);

在这里插入图片描述
定时器输入捕获库函数

//也有四个通道,初始化输入捕获单元
void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
//给初始化PWMI
void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
//给结构体初始化值
void TIM_ICStructInit(TIM_ICInitTypeDef* TIM_ICInitStruct);//选择输入触发源 (从模式) 
void TIM_SelectInputTrigger(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
//选择输出触发源
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);
void TIM_SetClockDivision(TIM_TypeDef* TIMx, uint16_t TIM_CKD);//分别读取4个通道的CCR
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);

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

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

相关文章

手机备忘录设置提醒后不通知怎么办 解决方法来了

在这个快节奏的时代,我们每个人都像是旋转的陀螺,总有无数的事项需要记录。手机备忘录,无疑成为了我们的得力助手。它轻便、简单,随时随地都能捕捉那些一闪而过的灵感和任务。 然而,有时我们会遇到这样的困扰&#xf…

部署开源的团队协作工具

简介 Zulip 是一个开源的团队协作工具,拥有独特的基于主题的线程功能,结合了电子邮件和聊天的优点,使远程工作更加高效和愉快。它是唯一设计用于实时和异步对话的现代团队聊天应用程序。其核心优势包括: 适用于大型企业、领先的开…

CSS的浮动(float)布局效果

<!DOCTYPE html> <html> <head> <meta charset"UTF-8" /> <title>浮动(float)布局效果</title> <style> *{ margin: 0; padding: 0; box-sizing: border-box; } /*.box1{ width: 300px; height: 300px; background-colo…

react后端开发:如何根据特定ID创建新的用户信息?

以音乐app开发为例&#xff0c;我们想要在想要创建新的唱片库&#xff0c;就需要使用Post连接服务器端新建唱片ID&#xff0c;并在该ID处插入唱片信息。怎么做呢&#xff1f; 使用create同时创建id和唱片信息 existingAlbum await Album.create({ _id: albumId, ...albumDat…

Django入门,十分钟学会登录网页

我们假定你已经阅读了 安装 Django。你能知道 Django 已被安装&#xff0c;且安装的是哪个版本&#xff0c;通过在命令提示行输入命令 cmd黑窗口运行&#xff0c;不懂cmd百度一下 python -m django --version 如果没出现版本&#xff0c;就是没安装&#xff0c;那么用pip安装…

《WebKit 技术内幕》学习之十(2): 插件与JavaScript扩展

2 Chromium PPAPI插件 2.1 原理 插件其实是一种统称&#xff0c;表示一些动态库&#xff0c;这些动态库根据定义的一些标准接口可以跟浏览器进行交互&#xff0c;至于这个标准接口是什么都可以&#xff0c;重要的是大家都遵循它们&#xff0c;NPAPI接口标准只是其中的一种&a…

C语言第六弹---分支语句(下)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 分支语句 1、 逻辑操作符&#xff1a;&& , || , &#xff01;4.1、 逻辑取反运算符 &#xff01;4.2、 与运算符4.3、 或运算符4.4、 练习&#xff1a;闰…

vue3.0规范学习记录

组合式函数使用usename进行命名&#xff0c;例如useMouse&#xff1b; 自定义指令使用v name进行命名&#xff0c;例如vFocus&#xff1b; 在组件使用v-model实现“双向绑定”时&#xff0c;子组件默认通过emits(‘update:modelValue’, params)触发更新&#xff1b; setup…

灵眸边缘计算产品学习

EASY EAI灵眸科技 | 让边缘AI落地更简单 (easy-eai.com) 产品简介 支持4路1080P30fps视频流采集&#xff0c;四核CPU1.5GHz与2Tops AI边缘算力能力。集成有以太网、Wi-Fi、4G等网络通信外设&#xff1b;RS232、RS485、UART等本地通信接口。HDMI显示屏接口、音频输入输出等交互…

[计算机网络]基本概念

目录 1.ip地址和端口号 1.1IP地址 1.2端口号 2.认识协议 2.1概念&#xff1a; 2.2知名协议的默认端口 3.五元组 4.协议分层 4.1分层的作用 4.2OSI七层模型 4.3TCP/IP五层&#xff08;四层&#xff09;模型 ​编辑4.4网络设备对应的分层&#xff1a; ​编辑以下为跨…

TestNG中的@AfterSuite注释

目录 什么是AfterSuite annotation&#xff1f; 代码示例 是时候来点头脑风暴了 我们可以在一个类中使用多个AfterSuite注释方法吗&#xff1f; AfterSuite放在超类上时如何工作&#xff1f; TestNG是Java中广泛使用的测试框架&#xff0c;用于进行单元&#xff0c;功能和…

大数据开发之Spark(入门)

第 1 章&#xff1a;Spark概述 1.1 什么是spark 回顾&#xff1a;hadoop主要解决&#xff0c;海量数据的存储和海量数据的分析计算。 spark是一种基于内存的快速、通用、可扩展的大数据分析计算引擎。 1.2 hadoop与spark历史 hadoop的yarn框架比spark框架诞生的晚&#xff…

CSS实现文本和图片无限滚动动画

Demo图如下&#xff1a; <style>* {margin: 0;padding: 0;box-sizing: border-box;font-family: Poppins, sans-serif;}body {min-height: 100vh;background-color: rgb(11, 11, 11);color: #fff;display: flex;flex-direction: column;justify-content: center;align-i…

Python无人系统

Python无人系统全方位自动坦克在现代军事中具有重要性。以下是几个重要原因&#xff1a; 自动化作战能力&#xff1a;Python无人系统全方位自动坦克能够在没有人类干预的情况下进行作战。它可以通过计算机视觉、传感器和算法来自主地感知环境、分析情报&#xff0c;制定战术和执…

Vision Mamba:将Mamba应用于计算机视觉任务的新模型

Mamba是LLM的一种新架构&#xff0c;与Transformers等传统模型相比&#xff0c;它能够更有效地处理长序列。就像VIT一样现在已经有人将他应用到了计算机视觉领域&#xff0c;让我们来看看最近的这篇论文“Vision Mamba: Efficient Visual Representation Learning with Bidirec…

Kubernetes operator(一)client-go篇【更新中】

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 Kubernetes operator学习 系列第一篇&#xff0c;主要对client-go进行学习&#xff0c;从源码阅读角度&#xff0c;学习client-go各个组件的实现原理、如何协同工作等参考视频&#xff1a;Bilibili 2022年最新k…

程序员裁员潮:技术变革下的职业危机

程序员裁员潮&#xff1a;技术变革下的职业危机 一对来自中国的工程师夫妻在美身亡&#xff0c;疑因谷歌裁员致悲剧发生。在技术变革下&#xff0c;裁员对于程序员的影响到底有多大&#xff1f;快来和我们分享一下你的看法吧~ 哎&#xff0c;这是悲哀&#xff0c;让我又想起来…

pod的亲和性和反亲和性

pod的亲和性和反亲和性 调度策略&#xff1a; 匹配标签 操作符 拓扑域 调度目标 node的亲和性 主机标签 In Notin exists doesexists Gt Lt 不支持 指定主机 pod的亲和性 pod的标签 In Notin exists doesexists 支持 pod和指…

【无标题】JavaScript 高阶 Promise篇

1、什么是Promise Promise 是异步编程的一种解决方案&#xff0c;其实是一个构造函数&#xff0c;自己身上有all、reject、resolve这几个方法&#xff0c;原型上有then、catch等方法。&#xff08;ps:关于原型&#xff1a;JavaScript高级 构造函数与原型篇&#xff09; Promi…

什么是 Web3.0

什么是Web3.0 对于 Web3.0 的解释网上有很多&#xff0c;目前来说 Web3.0 是一个趋势&#xff0c;尚未有明确的定义。我们今天讨论下几个核心的点&#xff0c;就能很好的理解 Web3.0 要解决哪些问题 谁创造数据&#xff0c;这里的数据可以是一篇博客&#xff0c;一段视频&…