速通蓝桥杯嵌入式省一教程:(七)定时器输入捕获中断与PWM频率占空比测量

news2024/9/25 23:19:42

前文已经讲述过定时器的两个用法:基本定时中断与PWM输出。本节接着介绍第三种用法:定时器输入捕获中断。

在此之前,需要解释一下前文一直出现过的与定时器有关的概念。

定时器(TIMER):所谓定时器,其基本功能就是定时,我们可以通过设置定时器的频率也就是周期,来帮助我们完成定时功能。

预分配系数(Prescaler):将时钟源的频率进行不同的分频,用于作为定时器的频率。若时钟源的频率为80MHz,预分频系数为80-1,那么得到的定时器频率就是80,000,000/80=1MHz,周期是1us。

计数周期(Counter Period):当定时器计数若干个周期以后,重置定时器的计数。假设计数周期设置为1000-1,那么当定时器完成1000个周期的计数后(按如上设置,也就是1ms后),定时器的计数值从999重置为0,重新开始计数。定时器中断的原理就是当计数值到达设定的计数周期后产生中断。计数周期又叫重装载值(AutoReload)。

比较值(Compare):在正脉冲输出模式下,若设置比较值为100,那么当计数值处于0~99时,端口输出高电平;当计数值处于100~999时,端口输出低电平,得到的效果就是前100us输出高电平,后900us输出低电平,产生一个频率为1kHz,占空比为10%的PWM波。在Cube中,比较值又称为Pulse。

在掌握了这几个概念之后,大家在阅读前几节时对定时器的疑问应该就可以尽数消除。这也就是定时器频率计算公式与PWM频率、占空比计算公式的由来。

所谓定时器输入捕获中断,就是将定时器的某个通道设置为直接输入捕获模式以后,将外部信号接到该通道所在引脚上,当外部信号满足一定条件(如边沿跳变)时,就会触发中断。因此,若我们设置在外部信号发生上升沿跳变时触发中断,在中断程序中读取定时器的计数值后手动将其清零,那么通过所得计数值,结合预先设置好的时钟源频率与预分频系数,就能通过公式计算得到输入信号的频率了。

下面我们就来看看如何测量输入到PA7引脚的信号频率。首先用Cube进行定时器的配置。

cb37cb9a5e2b47e8b3ba682a9cad6378.png

 可见PA7引脚同时作为多个定时器的通道,在这里我们选择TIM3的CH2通道。

 1edefc2972f346e8aca50b6f322bef85.png

同样,为了提高测量频率的精度,我们将预分频系数设置得尽可能小,计数周期设置得尽可能大。随后,打开定时器中断开关。

680a47a14bff4e6b99eab2296a3a9935.png

这样,我们就完成了在Cube中的设置。

与定时器中断类似,在程序初始化时,需要先开启定时器输入捕获中断:

HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2);   //开启TIM3CH2的输入捕获(IC(Input Capture))中断

然后编写定时器输入捕获中断函数,同样要注意函数名和形参均不能改动!!!可参照下图查找:

cc1f8438ae3e4c5fbc2e8abe92a62cde.png24e2be45f3d141e3bab198c1f545f97b.png

uint16_t prescaler = 1-1;
uint32_t ccl_value;
uint32_t pa7_frq;

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)    //定时器输入捕获回调函数
{
    if (htim->Instance==TIM3 && htim->Channel==HAL_TIM_ACTIVE_CHANNEL_2) //TIM3CH2触发的中断
    {
        ccl_value = HAL_TIM_ReadCaptureValue(htim, TIM_CHANNEL_2);    //读取捕获值(计数值)
        __HAL_TIM_SetCounter(&htim3, 0);                              //重置计数值
        pa7_frq = 80000000/((prescaler+1)*ccl_value);                 //根据公式计算频率
        HAL_TIM_IC_Start(htim, TIM_CHANNEL_2);                        //重新开启输入捕获
    }
}

在这里,我们用到了HAL_TIM_ReadCaptrueValue来读取当前捕获的计数值,其定义如下:

/**
  * @brief  Read the captured value from Capture Compare unit
  * @param  htim TIM handle.
  * @param  Channel TIM Channels to be enabled
  *          This parameter can be one of the following values:
  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
  * @retval Captured value
  */
uint32_t HAL_TIM_ReadCapturedValue(TIM_HandleTypeDef *htim, uint32_t Channel)

若要测量占空比,则需要在测量频率的基础上,使用另一个通道作为间接输入,并设置为下降沿捕获。这样一来,每当上升沿捕获中断触发,定时器计数清零后,到达第一个下降沿处,间接输入捕获通道捕获从上升沿到下降沿之间的计数值ccl_value_1;到达第二个上升沿处,直接输入捕获通道捕获从上升沿到上升沿之间的计数值ccl_value_2,于是占空比就等于ccl_value_1/ccl_value_2。

在这里我们选择Channel1作为间接输入捕获通道,在Cube中的设置如下:

8690a3434cd745ec9e4d6d61c3c1b920.png

更改代码如下:

uint16_t prescaler = 1-1;
uint32_t ccl_value_1, ccl_value_2;
uint32_t pa7_frq;
float pa7_duty;

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)    //定时器输入捕获回调函数
{
    if (htim->Instance==TIM3 && htim->Channel==HAL_TIM_ACTIVE_CHANNEL_2) //TIM3CH2触发的中断
    {
        ccl_value_1 = HAL_TIM_ReadCaptureValue(htim, TIM_CHANNEL_1);  //间接
        ccl_value_2 = HAL_TIM_ReadCaptureValue(htim, TIM_CHANNEL_2);  //直接
        __HAL_TIM_SetCounter(&htim3, 0);                              //重置计数值
        pa7_frq = 80000000/((prescaler+1)*ccl_value);                 //根据公式计算频率
        pa7_duty = float(ccl_value_1/ccl_value_2);                    //计算占空比
        HAL_TIM_IC_Start(htim, TIM_CHANNEL_1);                        //重新开启间接输入捕获
        HAL_TIM_IC_Start(htim, TIM_CHANNEL_2);                        //重新开启直接输入捕获
    }
}

下面我们通过第十四届省赛题来总结本节所讲内容:

8ab43d9037144ecba881781035f92d09.png

/* 以下代码添加到task.c中 */

#define PI 3.14

uint16_t prescaler = 1-1;
uint32_t ccl_value;
uint32_t pa7_frq;

/* 测量频率 */
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance==TIM3 && htim->Channel==HAL_TIM_ACTIVE_CHANNEL_2)
    {
        ccl_value = HAL_TIM_ReadCaptureValue(htim, TIM_CHANNEL_2);
        __HAL_TIM_SetCounter(&htim3, 0);
        pa7_frq = 80000000/((prescaler+1)*ccl_value);
        V = (pa7_frq*2*PI*R)/(100*K);
        HAL_TIM_IC_Start(htim, TIM_CHANNEL_2);
    }
}

 

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

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

相关文章

strstr的学习与使用及实现/查找字符串中的字符

在字符串中查找字符或字符串 strstr函数传入两个字符串&#xff0c;并返回查找后的首地址&#xff0c;找不到返回NULL 模拟实现 char* my_strstr( char* str1, const char* str2) {int i, j;assert(str1 && str2);//断言判断一下for ( i 0; i < strlen(str1); i){f…

【G-LAB】网络工程师常用排错命令详细版

网络工程师在日常配置中难免出现各种配置错误&#xff0c;比如接口地址配错、掩码位数配错、接口忘记no shutdown。除去这些基础错误&#xff0c;在配置各种路由选择协议时也会因为网络类型、邻居类型、区域和路由器层级等各种问题使邻居无法建立、路由无法传递进而导致网络不通…

Apipost中自定义接口字段如何配置

Apipost项目设置中可以配置接口文档中的自定义接口字段&#xff0c;创建状态码字典。分享分档时会展示到文档页面 状态码字典 在状态码字典中可以自定义状态码即其含义 自定义的状态码会在分享的API文档中展示 接口属性 接口属性中可以自定义接口和接口文档展示字段&#xf…

使用Python批量将飞书文档转为MD

说明&#xff1a;飞书是在线文档平台&#xff0c;本文介绍如何使用Python程序批量将飞书文档转为MD文档&#xff0c;并下载到本地&#xff1b; 复制地址 首先&#xff0c;把文档的URL都复制下来&#xff0c;这个需要一个一个点&#xff0c;并复制拷贝&#xff0c;但却是工作量…

【HCIP】10.路由策略

&#x1f4ce;13 路由策略与路由控制.pptx 通过修改路由的属性&#xff0c;影响了路由的生成及选路&#xff0c;最终影响了转发流量的路径&#xff1b;控制平面。 ACL IP prefix Filter-Policy Router-Policy 笔记

巴适得很!影驰2023“势在必燃”线下新品体验会成都站精彩回顾

全新一代的RTX 40系显卡早已和大家见面&#xff0c;其全新带来的核心架构、性能动力以及DLSS 3等技术黑科技&#xff0c;都为大家带来了不一样的惊喜。影驰 RTX 40 系显卡如今已经上线了诸多新品&#xff0c;更有DDR5系列的高频内存以及全新技术加持的PCI-E 5.0 SSD强势来袭&am…

Hadoop分布式计算与资源调度:打开专业江湖的魔幻之门

文章目录 版权声明一 分布式计算概述1.1 分布式计算1.2 分布式&#xff08;数据&#xff09;计算模式1.3 小结 二 MapReduce概述2.1 分布式计算框架 - MapReduce2.2 MapReduce执行原理2.3 小结 三 YARN概述3.1 YARN & MapReduce3.2 资源调度3.3 程序的资源调度3.4 YARN的资…

微信怎么添加更多的好友?通过后还能自动打招呼?

近期好多客户来问想把抖音、淘宝等平台的客户引流到自己的微信号里&#xff0c;打造自己的私域流量池&#xff0c;有什么办法能快捷地批量自动添加客户好友的微信呢&#xff1f;怎么规避加太多频繁的问题呢&#xff1f; 今天&#xff0c;我们来一一解决&#xff0c;都知道加好…

Python连接DB2数据库

安装Python DB2驱动 pip install ibm_db待更新

展会动态 | 迪捷软件邀您参加第五届中国嵌入式技术大会

大会简介 第五届中国嵌入式技术大会将于2023年8月23-25日在深圳会展中心&#xff08;福田&#xff09;1号会议室4/5/6举办&#xff0c;本届大会将以“智能、创新、开源”为主题&#xff0c;聚焦智能系统、汽车电子、开源芯片和基础软件四大板块&#xff0c;汇聚优质企业及知名…

批量修改文件名怎么操作?

批量修改文件名怎么操作&#xff1f;不管你使用电脑处理工作还是进行学习&#xff0c;都会在电脑中产生很多的文件&#xff0c;时间一久电脑里的文件更加杂乱无章&#xff0c;这时候如果不对电脑中的文件进行及时的管理&#xff0c;那么很可能出现文件丢失而你自己还发现不了的…

最新出炉!2023年NPS和CSAT行业基准分数一览

根据Forrester的最新调研&#xff0c;美国品牌在2023年难以提供出色的客户体验&#xff0c;导致其客户体验指数得分史无前例地连续第二年下降&#xff0c;大多数行业都在客户体验之旅中“碰壁”。无独有偶&#xff0c;加拿大品牌的整体客户体验水平也刷新了自2016年调研以来的“…

【报错】yarn --version Unrecognized option: --version Error...

文章目录 问题分析解决问题 在使用 npm install -g yarn 全局安装 yarn 后,查看yarn 的版本号,报错如下 PS D:\global-data-display> yarn --version Unrecognized option: --version Error: Could

这所“984.5”保护一志愿!集成学硕爆冷,300分以上全要!考数二英一!

一、学校及专业介绍 南京航空航天大学&#xff08;Nanjing University of Aeronautics and Astronautics&#xff09;&#xff0c;简称南航&#xff08;NUAA&#xff09;。位于江苏省南京市&#xff0c;是一所具有航空航天民航特色、以理工类为主的综合性全国重点大学。国家“…

Redis常用数据类型及常用命令

文章目录 简介下载与安装运行访问服务端运行连接数据库设置数据库密码带端口密码地址连接数据库利用可视化工具连接redis 5种常用数据类型Redis常用命令字符串操作命令哈希操作命令列表操作命令集合操作命令有序集合操作命令通用命令 简介 下载与安装 https://github.com/micro…

idea提示无法访问某个类

一、问题 maven引入某个包后无法访问这个包里面的类 二、原因 这个类用java11编写&#xff0c;而我的项目代码是用java8编译的所以无法访问此类&#xff0c;idea报错。 将项目的Java版本号改为11&#xff0c;重新编译&#xff0c;问题解决 参考文章&#xff1a; https://www…

maven打出jar中动态替换占位符

使用场景&#xff1a; maven打出的jar中pom.xml动态替换占位符 有些时候某些公共工具jar包被项目引用后发现公共jar的pom.xml中的version依然还是占位符&#xff0c;例如下面 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok<…

Python基础教程——实现登录和注册、2048游戏开发(完整版,附源码)

一、登录和注册 1. 案例介绍 本例设计一个用户登录和注册模块&#xff0c;使用 Tkinter 框架构建界面&#xff0c;主要用到画布、文本框、按钮等组件。涉及知识点&#xff1a;Python Tkinter 界面编程、pickle 数据存储。本例实现了基本的用户登录和注册互动界面&#xff0c;…

【Go】Goland项目配置运行教程

Golang项目配置运行教程 1.安装Golang下载安装包安装 2.Goland配置 注意&#xff0c;本项目描述的是git clone下来的Golang项目配置运行教程&#xff0c;并不是从头创建一个Golang项目并运行 作者是在win11系统上使用goland进行的实践&#xff0c;其他操作系统和比编辑器请谨慎…

linux设备驱动模型:xbus、platform

xbus&#xff1a;打造自属的驱动总线 软件和硬件的代码分离&#xff0c;提高程序的复用性。 device&#xff1a;关联硬件代码 driver_devices&#xff1a;关联软件代码 bus_type&#xff1a;统一管理、设置match匹配规则&#xff08;struct device和struct device_driver&…