单片机 PWM输入捕获【学习记录】

前言

学习是永无止境的,就算之前学过的东西再次学习一遍也能狗学习到很多东西,输入捕获很早之前就用过了,但是仅仅是照搬例程没有去进行理解。温故而知新!

定时器

定时器简介

定时器的分类

高级定时器 通用定时器 基本定时器,针对不同情况可以选择自己所需要的定时器,以下是这几种定时器的主要功能

高级定时器:

  1. 计数器单元
  2. 输入捕获
  3. 重复计数器
  4. PWM模式
  5. 互补输出和死区插入
  6. 支持针对定位的增量(正交)编码器和霍尔传感器电路
  7. 刹车功能
  8. DMA功能

通用定时器:

  1. 计数器单元
  2. 输入捕获
  3. PWM模式
  4. 支持针对定位的增量(正交)编码器和霍尔传感器电路
  5. DMA功能

基本定时器:

  1. 计数器单元
  2. 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 \frac{APBCLK}{ARR *Prescaler}。 

这里来解析一下为什么要使用 TIM_CLOCK_FREQ这个参数:

TIM_CLOCK_FREQ 代表的是定时器经过分频之后能够达到的极限频率,我们可以来推导一下,timer_clock(也就是主时钟APBCLK)分频之后 就是 \frac{timer_clock}{((timer_clock/TIM_CLOCK_FREQ))}

简单约去公约数,得到的就是TIM_CLOCK_FREQ,所以当重装载值为1的时候TIM_CLOCK_FREQ就是最高频率。再来解释一下周期是怎么得出的,由于1s之内计数器计数了TIM_CLOCK_FREQ次,所以一次需要的时间是1/TIM_CLOCK_FREQ,所以周期和重装载值之间的关系就是T= \frac{ARR*1}{TIM_CLOCK_FREQ},这里除以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输出,如果再讲下去就有点多了,这部分内容网上也有很多。

总结

输入捕获是高级定时器和通用定时器才有的功能,主要通过设置触发边沿和设置捕获频率来对脉宽进行一个测量,得出脉宽之后我们就可以很容易地计算出频率和周期。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Facebook与地方文化:数字平台的多元表达

在当今数字化时代,社交媒体不仅仅是人们交流的工具,更是促进地方文化传播和表达的重要平台。作为全球最大的社交网络之一,Facebook在连接世界各地用户的同时,也成为了地方文化多元表达的重要舞台。本文将深入探讨Facebook如何通过…

LabVIEW的热门应用

LabVIEW是一种图形化编程语言,因其易用性和强大的功能,在多个行业和领域中广泛应用。介绍LabVIEW在以下五个热门应用领域中的使用情况,:工业自动化、医疗设备与生物医学工程、科学研究与实验室自动化、能源管理与智能电网、航空航…

streamlit markdown里支持latex公式显示

参考: https://docs.streamlit.io/develop/api-reference/write-magic/st.write https://discuss.streamlit.io/t/streamlit-markdown-a-streaming-markdown-component-with-latex-mermaid-table-code-support/72187 也有独立支持的st.latex 接口单独显示公司&…

LeetCode347:前K个高频元素

题目描述 给你一个整数数组 nums 和一个整数 k &#xff0c;请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 解题思想 使用优先队列 priority_queue<Type, Container, Functional> Type 就是数据类型&#xff0c;Container 就是容器类型&#xff08;C…

Next14的appRouter模式中使用状态管理React-Redux

安装依赖 npm install reduxjs/toolkit react-redux创建store模块 创建 app/store/counterSlice.js文件 "use client"// redux需要作为客户端渲染的模块import { createSlice } from "reduxjs/toolkit"export const counterSlice createSlice({name: &…

解读自然语言处理:技术、应用与未来展望

引言 自然语言处理&#xff08;Natural Language Processing&#xff0c;简称NLP&#xff09;是计算机科学、人工智能和语言学的一个跨学科领域&#xff0c;致力于实现人与计算机之间通过自然语言进行有效沟通的能力。NLP 的核心任务是理解、解释和生成人类语言&#xff0c;使计…

AI早班2024.6.18

先一步知道AI未来&#xff01; 全球AI新闻速递 1.绿米 AI 智能存在传感器 FP1E开售。 2.摩尔线程 师者AI&#xff1a;完成70亿参数教育AI大模型训练测试。 3.Google 在 AI 功能推出新功能&#xff0c;需要明确说明可能出错的地方。 4.北大、快手攻克复杂视频生成难题&#…

生成式人工智能如何改变客户服务

生成式人工智能不仅重新定义了品牌与客户的互动方式&#xff0c;还重新定义了品牌如何优化内部资源&#xff0c;以提供更加个性化和高效的服务。 了解在就业和效率方面的挑战和机遇&#xff0c;使用生成式人工智能工具进行客户服务和支持任务。 生成式人工智能不仅重新定义了品…

一键复制备份轻松守护数据安全;安全删除目标文件夹里的原文件,释放存储空间

在这个信息爆炸的时代&#xff0c;我们的生活中充满了各种各样的数据和信息。从工作文档到家庭照片&#xff0c;从学习资料到个人收藏&#xff0c;这些资料都是我们的宝贵财富。然而&#xff0c;如何高效、安全地管理这些资料&#xff0c;却成为了许多人头疼的问题。今天&#…

关于在word中使用Axmath的报错的解决

介绍 Axmath是数学公式编辑器软件。官网如下。 AxMath/AxGlyph/AxCells (amyxun.com) 支持正版。 在word中使用Axmath 点击word中的“文件”→“选项”。 选择“加载项” 选择“word加载项” 在Axmath默认的安装目录如下&#xff1a; C:\Program Files (x86)\AxMathhao&am…

CSS-0_2 CSS和继承(inherit initial)

文章目录 CSS的层叠和继承inheritinitial很多你以为的样式初始值&#xff0c;其实是用户代理样式 碎碎念 CSS的层叠和继承 在上一篇 CSS和层叠、样式优先级 里已经讲过了层叠和优先级之间的关系&#xff0c;但是在CSS中的层叠除了体现在争抢露脸机会的优先级之外&#xff0c;还…

Pyqt QCustomPlot 简介、安装与实用代码示例(三)

目录 前言实用代码示例Line Style DemoDate Axis DemoParametric Curves DemoBar Chart DemoStatistical Box Demo 所有文章除特别声明外&#xff0c;均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 nixgnauhcuy’s blog&#xff01; 如需转载&#xff0c;请标明出处&#x…

【一文开启StableDiffusion】最火AIGC绘画工具SD阿里云部署指南(含踩坑经验)

Midjonery使用简单&#xff0c;效果出色&#xff0c;不过需要付费。本文将介绍完全开源的另一款产品StableDiffusion&#xff0c;它的社区目前非常活跃&#xff0c;各种插件和微调模型都非常多&#xff0c;而且它无需付费注册&#xff0c;没有速度、网络限制&#xff0c;非常推…

广州巨控科技GRM230系列无线模块:环保监控的新利器*

​近日&#xff0c;广州巨控科技推出了一款功能强大的无线模块——GRM230系列&#xff0c;其独特的IO输入输出与485通讯功能&#xff0c;在环保、河道水质检测、流量液位无线4G传输等方面展现出显著的应用优势&#xff0c;尤其在远程泵站启停与监控领域取得了显著成效。 一、G…

有趣且重要的JS知识合集(22)树相关的算法

0、举例&#xff1a;树形结构原始数据 1、序列化树形结构 /*** 平铺序列化树形结构* param tree 树形结构* param result 转化后一维数组* returns Array<TreeNode>*/ export function flattenTree(tree, result []) {if (tree.length 0) {return result}for (const …

分数计算 中级题目

分数计算 中级题目&#xff1a;多个数参与的计算 参考答案&#xff1a;【仅供参考】CBBCCBCCCC

【语义分割系列】基于camvid数据集的Deeplabv3+分割算法(二)

基于camvid数据集的Deeplabv3+分割算法 前言 在前面的内容中,对比了Camvid数据集在基于不同backbone的Deeplabv3+算法上的效果。在这节内容中,本文将介绍在ghostnet的基础上,进一步优化效果,使得Miou提升。通过引入CFAC和CARAFE结构,有效地提升了模型的miou。 1.代码部…

国际期货投机交易的常见操作方法:

一、在开仓阶段&#xff0c;入市时机的选择&#xff1a; &#xff08;1&#xff09;通过基本分析法&#xff0c;判断市场处于牛市还是熊市 开仓阶段&#xff0c;入市时机的选择&#xff1a;当需求增加、供给减少&#xff0c;此时价格上升&#xff0c;买入期货合约&#xff1b…

Element-ui中Table表格无法显示

Element-ui中Table表格无法显示 在使用过程中发现样式正常显示但是table就是不显示&#xff0c;研究了一段时间后&#xff0c;发现问题是项目结构的问题 当你创建vue和安装el的时候&#xff0c;一定要注意进入到正确的项目文件夹&#xff0c;如果在外面也出现一个package.jso…

ARDUINO NRF24L01

连线 5v 3.3皆可 gnd Optimized high speed nRF24L01 driver class documentation: Optimized High Speed Driver for nRF24L01() 2.4GHz Wireless Transceiver 同时下载同一个程序 案例默认引脚ce ces &#xff0c;7&#xff0c;8 可以 修改为 9,10 安装库 第一个示例 两…