STM32TIM定时器(3)

文章目录

  • 前言
  • 一、介绍部分
    • 输入捕获简介
    • 频率测量
    • 捕获比较通道
    • 主从模式
    • 输入捕获基本结构
    • PWMI基本结构
  • 二、代码部分
    • 使用输入捕获捕获另一个端口的PWM输入
      • 线路连接
      • 代码内容
    • PWMI获取频率占空比
      • 线路连接与上个案例一致
      • 代码实现
  • 总结
    • 相关函数
    • PSC、ARR都有1的误差


前言

这部分主要介绍输入捕获,通过输入捕获捕获定时器的计数器的值,通过频率检测来获取波形频率。简单介绍主从模式,实现硬件自动化检测。


一、介绍部分

输入捕获简介

在这里插入图片描述
也就是定时器框图的这部分
在这里插入图片描述

频率测量

都是计次数越大误差越小,所以使用N相等时得到中界频率。

在这里插入图片描述

捕获比较通道

在这里插入图片描述

主从模式

通过触发触发源自动运行从模式的内容
在这里插入图片描述

输入捕获基本结构

在这里插入图片描述

PWMI基本结构

在这里插入图片描述

二、代码部分

使用输入捕获捕获另一个端口的PWM输入

使用TIM2、PA0端口用于输出PWM波形,使用TIM3、PA6端口来接收这段波形频率。使用的是测周法

线路连接

在这里插入图片描述

代码内容

PWM.c

#include "stm32f10x.h"                  // Device headervoid PWM_Init(void){// 初始化时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;		// 复用推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		// 50Hz翻转速度GPIO_Init(GPIOA, &GPIO_InitStructure);// 使用内部时钟(默认)TIM_InternalClockConfig(TIM2);// 配置事间基础(时基单元)TIM_TimeBaseInitTypeDef TIM_InitStructure;// 时钟分频TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;// 计算模式TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;// 重载值(有1的偏差)<计数值> ARRTIM_InitStructure.TIM_Period = 100-1;// 预分频(有1的偏差)<频率> PSCTIM_InitStructure.TIM_Prescaler = 720-1;// 重复计数器(不使用)TIM_InitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2,&TIM_InitStructure);//初始化输出比较TIM_OCInitTypeDef TIM_OCInitStruct;// 初始这个结构体,以免因为没有配置高级定时器相关的值而产生问题TIM_OCStructInit(&TIM_OCInitStruct);// PWM1模式TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;// PWM高电平时有效TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;// 输出使能TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;// CCR,用于控制占空比的值TIM_OCInitStruct.TIM_Pulse = 0;TIM_OC1Init(TIM2,&TIM_OCInitStruct);// 启动定时器TIM_Cmd(TIM2,ENABLE);}// 设置CCR
void PWM_SetCCR(uint16_t Compare){TIM_SetCompare1(TIM2,Compare);}// 设置PSC
void PWM_SetPSC(uint16_t Prescaler){// 单独修改TIM2的预分频,立即生效,不使用影子寄存器TIM_PrescalerConfig(TIM2,Prescaler,TIM_PSCReloadMode_Immediate);
}

封装输入捕获,IC.c内容:

#include "stm32f10x.h"                  // Device headervoid IC_Init(void){// 开启时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;		// 上拉输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		// 50Hz翻转速度GPIO_Init(GPIOA, &GPIO_InitStructure);// 使用内部时钟(默认)TIM_InternalClockConfig(TIM3);// 配置事间基础(时基单元)TIM_TimeBaseInitTypeDef TIM_InitStructure;// 时钟分频TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;// 计算模式TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;// 重载值(有1的偏差)<计数值> ARRTIM_InitStructure.TIM_Period = 65536-1;// 预分频(有1的偏差)<频率> PSCTIM_InitStructure.TIM_Prescaler = 72-1;// 重复计数器(不使用)TIM_InitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM3,&TIM_InitStructure);//初始化输入捕获TIM_ICInitTypeDef TIM_ICInitStructure;// 选择CH1通道TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;// 滤波频率,设置高点过使人耳听不见噪音,不会影响频率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);		// 四个通道一个函数// 设置输入触发源TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);// 选择从模式,重置TIM3的计数器TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);// 启动定时器TIM_Cmd(TIM3,ENABLE);
}uint32_t IC_GetFreq(void){// 72000000/73/获取的ARRreturn 1000000 / (TIM_GetCapture1(TIM3)+1);
}

主函数main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"int main(void)
{OLED_Init();PWM_Init();IC_Init();PWM_SetPSC(720-1);			// f = 72MHz/(Prescaler+1)/(ARR+1)PWM_SetCCR(50);					// 占空比 = CRR/(ARR+1)OLED_ShowString(1,1,"Freq:       Hz");while (1){OLED_ShowNum(1,8,IC_GetFreq(),5);}
}

PWMI获取频率占空比

和PWMI基本结构一样,在上面的基础上多加一条交叉通道,用这个通道检测下降沿,来获取占空比

线路连接与上个案例一致

代码实现

PWM.c不用修改,修改IC.c的内容

#include "stm32f10x.h"                  // Device headervoid IC_Init(void){// 开启时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;		// 上拉输入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		// 50Hz翻转速度GPIO_Init(GPIOA, &GPIO_InitStructure);// 使用内部时钟(默认)TIM_InternalClockConfig(TIM3);// 配置事间基础(时基单元)TIM_TimeBaseInitTypeDef TIM_InitStructure;// 时钟分频TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;// 计算模式TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;// 重载值(有1的偏差)<计数值> ARRTIM_InitStructure.TIM_Period = 65536-1;// 预分频(有1的偏差)<频率> PSCTIM_InitStructure.TIM_Prescaler = 72-1;// 重复计数器(不使用)TIM_InitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM3,&TIM_InitStructure);//初始化输入捕获TIM_ICInitTypeDef TIM_ICInitStructure;// 选择CH1通道TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;// 滤波频率,设置高点过使人耳听不见噪音,不会影响频率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);		// 四个通道一个函数// 自动配置另一条相反通道,下降沿触发,交叉通道TIM_PWMIConfig(TIM3,&TIM_ICInitStructure);// 设置输入触发源TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);// 选择从模式,重置TIM3的计数器TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);// 启动定时器TIM_Cmd(TIM3,ENABLE);
}uint32_t IC_GetFreq(void){// 72000000/73/获取的ARRreturn 1000000 / (TIM_GetCapture1(TIM3)+1);
}
// 获取占空比
uint32_t IC_GetDuty(void){return (TIM_GetCapture2(TIM3)+1)*100/(TIM_GetCapture1(TIM3)+1);
}

主函数main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
#include "IC.h"int main(void)
{OLED_Init();PWM_Init();IC_Init();PWM_SetPSC(7200-1);			// f = 72MHz/(Prescaler+1)/(ARR+1)PWM_SetCCR(80);					// 占空比 = CRR/(ARR+1)OLED_ShowString(1,1,"Freq:       Hz");OLED_ShowString(2,1,"Duty:       %");while (1){// 显示频率OLED_ShowNum(1,8,IC_GetFreq(),5);// 显示占空比OLED_ShowNum(2,11,IC_GetDuty(),2);}
}

总结

相关函数

// 初始化输入捕获
void TIM_ICInit(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
// 自动配置没有配置的另一条输入捕获通道
void TIM_PWMIConfig(TIM_TypeDef* TIMx, TIM_ICInitTypeDef* TIM_ICInitStruct);
// 设置从模式
void TIM_SelectSlaveMode(TIM_TypeDef* TIMx, uint16_t TIM_SlaveMode);
// 设置不同定时器的比较值
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1);
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
void TIM_SetCompare3(TIM_TypeDef* TIMx, uint16_t Compare3);
void TIM_SetCompare4(TIM_TypeDef* TIMx, uint16_t Compare4);
// 设置不同定时器的预分频
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);
// 获取不同定时器的捕获计数器内容
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);

PSC、ARR都有1的误差

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

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

相关文章

Spring Boot整合新版Spring Security:Lambda表达式配置优雅安全

文章目录 1. 引言2. 项目依赖配置3. 使用Lambda表达式配置Spring Security4. 自定义身份验证逻辑5. 认证与授权注解5.1 Secured注解5.2 PreAuthorize和PostAuthorize注解 6. 总结 &#x1f389;Spring Boot整合新版Spring Security&#xff1a;Lambda表达式配置优雅安全 ☆* o(…

spring cloud stream

背景 主要解决不同消息中间件切换问题。实现不同中间件的代码解耦。 链接: 支持的中间件 后文使用kafka测试。 引入依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-stream</artifactId></depende…

Spring Web Body 转化常见错误

在 Spring 中&#xff0c;对于 Body 的处理很多是借助第三方编解码器来完成的。例如常见的 JSON 解析&#xff0c;Spring 都是借助于 Jackson、Gson 等常见工具来完成。所以在 Body 处理中&#xff0c;我们遇到的很多错误都是第三方工具使用中的一些问题。 真正对于 Spring 而…

2024年 复习 HTML5+CSS3+移动web 笔记 之CSS遍 第5天

第 五 天 整个网站例 5.1 准备工作 项目目录与版心 base.css 5.2 网页制作思路 5.3 header 区域-整体布局 5.4 header区域-logo 5.5 header区域-导航 index.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8">&l…

网桥与网关

文章目录 概要网桥网关联系与区别参考文章 概要 网桥和网关的理解 网桥 几个名词的概念 网关 联系与区别 参考文章 如何通俗地解释什么是网桥&#xff1f; 网关到底是什么求通俗易懂讲解? 网桥&#xff1a;网桥也叫桥接器&#xff0c;是连接两个局域网的一种存储/转发…

C语言第十九弹---指针(三)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 指针 1、数组名的理解 2、使用指针访问数组 3、⼀维数组传参的本质 4、冒泡排序 5、二级指针 6、指针数组 7、指针数组模拟二维数组 总结 1、数组名的理解…

测试开发体系

软件测试 通过手工或者工具对 “被测对象”进行测试验证实际结果与预期结果之间是否存在差异 软件测试作用 通过测试工作可以发现并修复软件当中存在的缺陷&#xff0c;从而提高用户对产品的使用信心测试可以降低同类型产品开发遇到问题的风险 软件缺陷 软件缺陷被测试工程…

快速渲染效果图:设计师的高效工作流揭秘

渲染技能是每个建模设计师需求的一个重要技能&#xff0c;尽管在许多设计公司里&#xff0c;建模和渲染往往是分开由各自的专家来完成。不过&#xff0c;一个全能型的建模师还是应该精通渲染技术。对于那些接外包项目来制作渲染效果图的设计师来说&#xff0c;掌握如何提速渲染…

神经网络基本原理

神经网络是一门重要的机器学习技术。它是目前最为火热的研究方向–深度学习的基础。 神经网络是一种模拟人脑的神经网络以期能够实现类人工智能的机器学习技术。人脑中的神经网络是一个非常复杂的组织。成人的大脑中估计有1000亿个神经元之多。 1 介绍 下面是一个包含三个层…

使用webstorm调试vue 2 项目

学习目标&#xff1a; 使用webstorm调试vue 2 项目 笔者环境&#xff1a; npm 6.14.12 webstorm 2023.1 vue 2 学习内容&#xff1a; 例如&#xff1a; 正常启动npm 项目 配置javaScruot dubug 配置你的项目地址就好 使用dubug运行你配置的调式页 问题 如果进入了js页无…

使用pandas将excel转成json格式

1.Excel数据 2.我们想要的JSON格式 {"0": {"raw_data1": "Sam","raw_data2": "Wong","raw_data3": "Good","layer": "12v1"},"1": {"raw_data1": "Lucy…

算法效率的度量-时间空间复杂度

常对幂指阶 1.时间复杂度 事前预估 算法 时间开销 T(n) 与 问题规模 n 的关系&#xff08; T 表示 “ time ”&#xff09; 一般默认问题规模为n。 1.单循环 2.嵌套两层循环都为n 3.单层循环指数递增型 4.搜索型 链接 &#xff1a;第七章查找算法&#xff01;&#xff01…

【力扣】整数反转,判断是否溢出的数学解法

整数反转原题地址 方法一&#xff1a;数学 反转整数 如何反转一个整数呢&#xff1f;考虑整数操作的3个技巧&#xff1a; xmod10可以取出x的最低位&#xff0c;如x123&#xff0c;xmod103。x/10可以去掉x的最低位&#xff0c;如x123&#xff0c;x/10&#xff0c;x12。xx*10…

IntelliJ IDE 插件开发 | (六)内部模式的使用

系列文章 IntelliJ IDE 插件开发 |&#xff08;一&#xff09;快速入门IntelliJ IDE 插件开发 |&#xff08;二&#xff09;UI 界面与数据持久化IntelliJ IDE 插件开发 |&#xff08;三&#xff09;消息通知与事件监听IntelliJ IDE 插件开发 |&#xff08;四&#xff09;来查收…

PCB正片和负片的区别与使用

PCB正片和负片的区别与使用 简单解释详细解释 简单解释 简单的来说&#xff0c;正片在电路板的表面&#xff08;指定是顶层和底层&#xff09;上保留我们绘图工具所画的线&#xff08;图案&#xff09;。 而负片则是将我们绘制的线&#xff08;图案&#xff09;进行腐蚀掉&am…

leetcode1079:游戏玩法分析——求留存率

求留存率 题目描述题解 题目描述 表&#xff1a;Activity --------------------- | Column Name | Type | --------------------- | player_id | int | | device_id | int | | event_date | date | | games_played | int | --------------------- &#xff08;player_id&…

JIT逆优化引发的Java服务瞬时抖动 问题排查解决方案

目录 一、背景 二、前期排查&#xff08;失败&#xff09; 三、使用神器JFR 四、学习JIT&思考解决方案 五、最终的解决方案 五、总结 一、背景 我们有一个QPS较高、机器数较多的Java服务&#xff1b;该服务的TP9999一般为几十ms&#xff0c;但偶尔会突然飙升至数秒&a…

OnlyOffice:释放无限创意,打造高效协作新体验

Onlyoffice &#x1f496;前言一、&#x1f4ab;开发者版本介绍二、&#x1f4ab;开发者版本特点三、&#x1f4ab;最新版重磅来袭&#xff0c;8.0版本介绍1.显示协作者头像2.插件 UI 界面更新 四、✨Windows部署ONLYOFFICE1.安装Erlang2.安装RabbitMQ3.安装Redis4.安装Postgre…

CSS:两列布局

两列布局是指一列宽度固定&#xff0c;另一列自适应。效果如下&#xff1a; HTML: <div class"container clearfix"><div class"left"></div><div class"right"></div> </div>公共 CSS&#xff1a; .con…

Elasticsearch:BM25 及 使用 Elasticsearch 和 LangChain 的自查询检索器

本工作簿演示了 Elasticsearch 的自查询检索器将非结构化查询转换为结构化查询的示例&#xff0c;我们将其用于 BM25 示例。 在这个例子中&#xff1a; 我们将摄取 LangChain 之外的电影样本数据集自定义 ElasticsearchStore 中的检索策略以仅使用 BM25使用自查询检索将问题转…