STM32基础篇(五)------TIM定时器比较输出

简介

在这里插入图片描述

定时器的类型

在《STM32F10xxx参考手册(中文).pdf》中可以看到下面三个章节
在这里插入图片描述

因此可以得到
在这里插入图片描述

高级定时器含有通用定时器的所有功能,通用定时器含有基本定时器的所有功能!!!!!!

在下图中可以看到这款芯片确实只有TIM1高级定时器和TIM2~TIM4通用定时器这四个定时器(无基本定时器)

在这里插入图片描述

定时中断基本结构

在这里插入图片描述

定时器计数方式

类型计数方式
基本定时器向上计数
通用定时器向上/向下计数、中央计数
高级定时器向上/向下计数、中央计数

基本定时器结构

在这里插入图片描述

● 计数器寄存器(TIMx_CNT)
● 预分频寄存器(TIMx_PSC)
● 自动重装载寄存器(TIMx_ARR)

基本定时器是TIM定时器中最简单的,以此为例解释其工作原理。通过上图易知基本定时器的工作流程就是:计数器寄存器(TIMx_CNT)一直在自增,当增加到自动重装载寄存器(TIMx_ARR)规定的数值的时候,则触发中断或者事件。

设 TIMxCLK = 72MHz即 每秒中有72,000,000(7200万)个时钟脉冲。1s=1000ms,1ms = 1000us,则1s = 1000000。则1us会有72个时钟脉冲。则1us会有72个时钟脉冲。现在我们假设上图中没有PSC预分频器,那么我想延时1s的话,TIMx_ARR的数值是不是需要设置为7200万。我们看一下TIMx_ARR的寄存器
在这里插入图片描述
只有16位欸,最大不过是0xFFFF=65535,这可完犊子了。。。。所以引入了预分频寄存器(TIMx_PSC)。这个东西通俗点解释可以这么理解。TIMxCLK 给过来的是72MHz的信号,相当于1s有72,000,000(7200万)个抖动,我嫌弃这抖的太快了,我想要一秒钟只抖动72,000次,那我就给TIMx_PSC设置为1000分频,这不每秒就只抖动72,000次就行了。OK了家人们,我们就给TIMx_PSC设置为1000,然后我想实现延迟1S,那TIMx_ARR是不是得设置为72,000,我i嘞个去啊这不又完犊子了,TIMx_ARR最大才65535啊。没关系家人们,我们看一下TIMx_PSC这逼崽子。
在这里插入图片描述
芜湖!!!!起飞。也是16位,那不就是说TIMx_PSC支持0~65535嘛,那我给它设置为10000,这下TIMx_ARR给个7200不就OK了嘛。

TIMx_PSC = 65535,TIMx_ARR = 65535
TIMx_PSC  *  TIMx_ARR  = 4,294,836,225
4,294,836,225 / 72,000,000 = 59.650503125

那么也就是说单个定时器最多可以延时 59.650503125秒。

在这里插入图片描述

看没错吧,手册上面给的也是59.6.

● 预分频寄存器(TIMx_PSC)
● 自动重装载寄存器(TIMx_ARR)
注意这俩寄存器中的这两句话:1(TIMx_PSC) 计数器的时钟频率CK_CNT等于fCK_PSC/(PSC[15:0]+1)。
也就是说我们在设置TIMx_PSC的时候要手动-1,如果TIMx_PSC想要设置为10000,则实际需要设置为10000 - 12、TIMx_ARR这个和TIMx_PSC一样也是实际使用中需要-1,具体原因我没想明白也没找到。但是教程里面都是这样使用的。有知道的可以评论区交流。

因为stm32f103中没有基本定时器,我们使用通用定时器来实现一个 1s的延时。

#include "Tim.h"uint32_t TIM2_Count = 0;void TIM2_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//1、选择时钟源为内部时钟TIM_InternalClockConfig(TIM2);//2、初始化时基单元TIM_TimeBaseInitTypeDef TIM_Prama;TIM_Prama.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能TIM_Prama.TIM_CounterMode = TIM_CounterMode_Up;//向上计数TIM_Prama.TIM_Period = 7200 -1; //ARRTIM_Prama.TIM_Prescaler = 10000 - 1; //PCSTIM_Prama.TIM_RepetitionCounter = 0; //重复计数器,高级定时器才会用到TIM_TimeBaseInit(TIM2, &TIM_Prama);TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//TIM_TimeBaseInit 初始化时候触发了一次更新事件//3、选择中断触发方式TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//更新方式触发中断//4、配置中断优先级分组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//5、配置NVICNVIC_InitTypeDef NVIC_Prama;NVIC_Prama.NVIC_IRQChannel = TIM2_IRQn;NVIC_Prama.NVIC_IRQChannelCmd = ENABLE;NVIC_Prama.NVIC_IRQChannelSubPriority = 0;NVIC_Prama.NVIC_IRQChannelPreemptionPriority = 1;NVIC_Init(&NVIC_Prama);//使能定时器TIM_Cmd(TIM2,ENABLE);
}uint32_t GetTIM2Count(void)
{return TIM2_Count;
}void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){TIM2_Count++;TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}

通用定时器

在这里插入图片描述

通过此图可以发现上面我们使用的系统内部时钟实现了定时中断,下面我们使用外部时钟模式2,即外部每触发10次,TIM2进入一次中断

#include "Tim_ETR.h"uint16_t TIM2ETR_CNT = 0;
uint32_t TIM2ETR_Count = 0;void TIM2ETR_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//1、外部时钟2模式作为TIM2的时钟输入//TIM_ExtTRGPSC_OFF 不适使用分频//TIM_ExtTRGPolarity_NonInverted 高电平有效//以一个f采样频率采样N个点,如果N个点都一样才会有效输出TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x00);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//GPIO初始化 上拉输入GPIO_InitTypeDef GPIO_InitPram;GPIO_InitPram.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitPram.GPIO_Pin = GPIO_Pin_0;GPIO_Init(GPIOA,&GPIO_InitPram);//2、初始化时基单元TIM_TimeBaseInitTypeDef TIM_Prama;TIM_Prama.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能TIM_Prama.TIM_CounterMode = TIM_CounterMode_Up;//向上计数TIM_Prama.TIM_Period = 10 -1; //ARRTIM_Prama.TIM_Prescaler = 1 - 1; //PCSTIM_Prama.TIM_RepetitionCounter = 0; //重复计数器,高级定时器才会用到TIM_TimeBaseInit(TIM2, &TIM_Prama);TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//TIM_TimeBaseInit 初始化时候触发了一次更新事件//3、选择中断触发方式TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//更新方式触发中断//4、配置中断优先级分组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//5、配置NVICNVIC_InitTypeDef NVIC_Prama;NVIC_Prama.NVIC_IRQChannel = TIM2_IRQn;NVIC_Prama.NVIC_IRQChannelCmd = ENABLE;NVIC_Prama.NVIC_IRQChannelSubPriority = 3;NVIC_Prama.NVIC_IRQChannelPreemptionPriority = 1;NVIC_Init(&NVIC_Prama);//使能定时器TIM_Cmd(TIM2,ENABLE);
}uint32_t GetTIM2ETRCount(void)
{return TIM2ETR_Count;
}uint16_t GetTIM2ETRCNT(void)
{return TIM_GetCounter(TIM2);
}void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){TIM2ETR_Count++;TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}

高级定时器

在这里插入图片描述

通过上图可以发现高级定时器左上部分就是通用定时器,其余部分才是高级定时器独有的功能。

定时器的输出比较

基于上面的结构图可以发现,只有通用/高级定时器才有输出比较功能,基础定时器无此功能。

在这里插入图片描述

PWM

在这里插入图片描述
通过上图可以得到、

占空比越大,等效的模拟电压就越趋近于高电平
占空比越小,等效的模拟电压就越趋近于低电平

在这里插入图片描述
输出模式控制器见下表
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

PWM频率公式推导过程

CK_PSC 输入时钟
PSC 分频系数
ARR 重新转载值T = ((PSC + 1)*(ARR + 1)) / CK_PSC   T是定时周期
f = 1/T
=> f = CK_PSC / ((PSC + 1)*(ARR + 1)) 
=> f = CK_PSC / (PSC + 1) / (ARR + 1)

下面是个使用PWM驱动舵机示例(舵机型号:G90),使用旋转编码器控制舵机旋转角度

#include "Servo.h"//通用定时器TIM2 CH3通道 ----PA2
//PA2输出PWM波
//舵机需要的PWM时钟周期为20ms  舵机转角范围0~180度
//0.5ms ------ 0度
//1.0ms ------ 45度
//1.5ms ------ 90度
//2.0ms ------ 135度
//2.5ms ------ 180度void Servo_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);TIM_InternalClockConfig(TIM2);//GPIO初始化 上拉输入GPIO_InitTypeDef GPIO_InitPram;GPIO_InitPram.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitPram.GPIO_Pin = GPIO_Pin_2;GPIO_InitPram.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitPram);//2、初始化时基单元  20ms的周期TIM_TimeBaseInitTypeDef TIM_Prama;TIM_Prama.TIM_ClockDivision = TIM_CKD_DIV1;//时钟分频,选择不分频,此参数用于配置滤波器时钟,不影响时基单元功能TIM_Prama.TIM_CounterMode = TIM_CounterMode_Up;//向上计数TIM_Prama.TIM_Period = 20000 -1; //ARR 20msTIM_Prama.TIM_Prescaler = 72 - 1; //PCSTIM_Prama.TIM_RepetitionCounter = 0; //重复计数器,高级定时器才会用到TIM_TimeBaseInit(TIM2, &TIM_Prama);TIM_OCInitTypeDef TIM_OCParam;TIM_OCStructInit(&TIM_OCParam);//TIM_OCInitTypeDef 结构体中部分是高级定时器才使用的功能,因此需要一个默认值,所以使用TIM_OCStructInit初始化一个默认值//假设TIM_OCInitTypeDef中的A_Pram变量取值范围是(1,2)。如果不使用TIM_OCStructInit初始化可能A_Pram = 0.可能会影响系统。TIM_OCParam.TIM_OCMode = TIM_OCMode_PWM1; //PWM模式选择模式1 向上计数:CNT<CCR时,REF置有效电平(+),CNT≥CCR时,REF置无效电平(-)TIM_OCParam.TIM_OutputState = TIM_OutputState_Enable;//输出使能TIM_OCParam.TIM_Pulse = 0; //CRR初始值TIM_OCParam.TIM_OCPolarity = TIM_OCPolarity_High;//指定输出级性TIM_OC3Init(TIM2, &TIM_OCParam);//使能定时器TIM_Cmd(TIM2,ENABLE);
}/*TIM_Prama.TIM_Period = 20000 -1; //ARR 20ms
TIM_Prama.TIM_Prescaler = 72 - 1; //PCS((PCS + 1) * (ARR + 1)) / 定时器输入时钟 = 定时周期0.5ms ------ 0度
1.0ms ------ 45度
1.5ms ------ 90度
2.0ms ------ 135度
2.5ms ------ 180度将周期转换成计数的数值也就是500  ------ 0度
1000 ------ 45度
1500 ------ 90度
2000 ------ 135度
2500 ------ 180度可得到方程 计数值CRR = k * 2000 + 500;其中K是 n/180 (n是设置的度数)*/void SetCRRValue(uint16_t val)
{uint16_t Kval = (val *1.0f / 180.0f) * 2000 + 500;TIM_SetCompare3(TIM2, Kval);
}

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

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

相关文章

基于STM32的两路电压测量仿真设计Proteus仿真+程序设计+设计报告+讲解视频

基于STM32两路电压测量仿真设计(Proteus仿真程序设计设计报告讲解视频&#xff09; 仿真图Proteus 8.9 程序编译器&#xff1a;keil 5 编程语言&#xff1a;C语言 设计编号&#xff1a;C0106 1.主要功能 基于STM32单片机设计一个双路电压检测器 1.系统可以测量两路输入电…

210、【图论】课程表(Python)

题目 思路 这道题本质上是一个拓扑排序。每次先统计每个点的入度个数、然后再统计点与点之间的邻接关系&#xff0c;找到入度为0的点作为起始遍历点。之后每遍历到这个点之后&#xff0c;就把这个点后续的邻接关系边的点入度减去一。当某个点入度为0时&#xff0c;继续被加入其…

react 杂记2 优化hook

useEffect 每个Fiber节点都会为该组件的所有effec对象​维护一个链表, 场景​类组件方法函数组件等效写法差异说明挂载时执行componentDidMount()useEffect(fn, [])useEffect 副作用在浏览器绘制后异步执行&#xff1b;componentDidMount 是同步的。更新时执行componentDidUp…

Java内存泄漏、CPU飙升排查

在Java应用开发中&#xff0c;内存泄漏和CPU飙升是两类高频出现的生产问题&#xff0c;也是常见的面试问题。这里通过一些demo进行实践。 内存泄漏 private static List<byte[]> leakList new ArrayList<>();GetMapping("/memory/leak") public void …

【搜索】dfs(回溯、剪枝、记忆化)

个人主页&#xff1a;Guiat 归属专栏&#xff1a;我讲你听 文章目录 1. dfs 回溯1.1 回溯介绍1.2 回溯模板1.3 回溯经典题目 2. dfs 剪枝2.1 剪枝介绍2. 2 剪枝模板2.3 经典题目 3. dfs 记忆化3.1 记忆化介绍3.2 记忆化示例 正文 1. dfs 回溯 1.1 回溯介绍 核心思想&#xff…

emWin自定义键盘布局

emWin V6.46提供了自带的键盘控件&#xff0c;用起来功能还是比较齐全的。但是有些时候自带的布局不能满足要求&#xff0c;此时可用键盘的结构体来自定义布局。 KEYDEF_KEYBOARD MyNumPad;static KEYDEF_AREA NumPadKeyArea[4] {{10, 0, 720, 250}, //每行按钮的坐标和占用…

人工智能之数学基础:瑞利商与特征值的关系

本文重点 瑞利商是线性代数中的一个重要概念,具有丰富的性质和广泛的应用。通过求解瑞利商的最大值或最小值,可以找到矩阵的特征值和特征向量,进而解决降维、聚类、优化和计算机视觉等领域的问题。广义瑞利商作为瑞利商的推广形式,在机器学习和数据分析中也发挥着重要作用…

Mysql配套测试之更新篇

&#x1f3dd;️专栏&#xff1a;Mysql_猫咪-9527的博客-CSDN博客 &#x1f305;主页&#xff1a;猫咪-9527-CSDN博客 “欲穷千里目&#xff0c;更上一层楼。会当凌绝顶&#xff0c;一览众山小。” 目录 测试准备&#xff1a; 更新测试 &#xff1a; 1.将孙悟空同学的数学成…

2025年如何避免使用验证码求解器时被IP封禁

引言 2025年&#xff0c;验证码求解器已成为自动化网络抓取和其他在线流程的关键工具。然而&#xff0c;自动化用户面临的一个常见挑战是IP封禁。当网站检测到自动化活动时&#xff0c;通常会阻止发出请求的IP地址&#xff0c;导致验证码挑战无法解决。本文将探讨使用验证码求…

ElasticSearch 可观测性最佳实践

ElasticSearch 概述 ElasticSearch 是一个开源的高扩展的分布式全文检索引擎&#xff0c;它可以近乎实时的存储、检索数据&#xff1b;本身扩展性很好&#xff0c;可以扩展到上百台服务器&#xff0c;处理 PB 级别&#xff08;大数据时代&#xff09;的数据。ES 也使用 Java 开…

操作系统的特征

并发 指两个或多个事件在同一时间间隔内发生。这些时间宏观上是同时发生的&#xff0c;但微观上是交替发生的。 并行 指两个或多个事件在同一时刻同时发生 操作系统的并发性 指计算机系统重“同时”运行着多个程序&#xff0c;这些程序宏观上看是同时运行的&#xff0c;而…

数据结构——B树、B+树、哈夫曼树

目录 一、B树概念1.B树的构造2 .B树的特点 二、B树概念1.B树构造2.B树的特点 三、B树和B树的区别四、哈夫曼树1.哈夫曼树的基本概念2.哈夫曼树的构建 一、B树概念 B树的出现是为了弥合不同的存储级别之间的访问速度上的巨大差异&#xff0c;实现高效的 I/O。平衡二叉树的查找效…

电子签的法律效力、业务合规与监管难点

撰稿 | 区长 来源 | 贝多财经 据2025年央视“3.15”晚会报道&#xff0c;借贷宝、人人信等平台上存在高利贷的情形。放贷人与借款人在平台签署借款合同&#xff0c;但是实际借款金额低于合同金额&#xff0c;从而绕开平台对利率的限制。这引发了人们对电子签法律效力、业务合…

资金管理策略思路

详细描述了完整交易策略的实现细节&#xff0c;主要包括输入参数、变量定义、趋势判断、入场与出场条件、止损与止盈设置等多个方面。 输入参数&#xff08;Input&#xff09;&#xff1a; EntryFrL (.6)&#xff1a;多头入场的前一日波动范围的倍数。 EntryFrS (.3)&#xff1…

体育直播视频源格式解析:M3U8 vs FLV

在体育直播领域&#xff0c;视频源的格式选择直接影响着直播的流畅度、画质以及兼容性。目前&#xff0c;M3U8 和 FLV 是两种最为常见的视频流格式&#xff0c;它们各有优劣&#xff0c;适用于不同的场景。本文将从技术原理、优缺点以及应用场景等方面对 M3U8 和 FLV 进行详细解…

【动态规划】下降路径最小和

跟之前不同由于可能取到最右上角值&#xff0c;则左右各加一列&#xff0c;并且由于求最小值&#xff0c;则加的列须设置为正无穷大&#xff1b; class Solution { public:int minFallingPathSum(vector<vector<int>>& matrix) {int nmatrix.size();vector<…

07_GRU模型

GRU模型 双向GRU笔记:https://blog.csdn.net/weixin_44579176/article/details/146459952 概念 GRU&#xff08;Gated Recurrent Unit&#xff09;也称为门控循环单元&#xff0c;是一种改进版的RNN。与LSTM一样能够有效捕捉长序列之间的语义关联&#xff0c;通过引入两个&qu…

VScode

由于centos停止了维护 ,后面使用ubuntu 在Ubuntu中用vscode 充当记事本的作用 替代了centos中vim的作用 后面使用vscode编辑 vscode中继续使用makefile , xshell中的cgdb进行debug (半图形写 ,半命令行debug&&运行) 官网下载地址&#xff1a;https://code.visuals…

【行驶证识别】批量咕嘎OCR识别行驶证照片复印件图片里的文字信息保存表格或改名字,基于QT和腾讯云api_ocr的实现方式

项目背景 在许多业务场景中,如物流管理、车辆租赁、保险理赔等,常常需要处理大量的行驶证照片复印件。手动录入行驶证上的文字信息,像车主姓名、车辆型号、车牌号码等,不仅效率低下,还容易出现人为错误。借助 OCR(光学字符识别)技术,能够自动识别行驶证图片中的文字信…

异步编程与流水线架构:从理论到高并发

目录 一、异步编程核心机制解析 1.1 同步与异步的本质区别 1.1.1 控制流模型 1.1.2 资源利用对比 1.2 阻塞与非阻塞的技术实现 1.2.1 阻塞I/O模型 1.2.2 非阻塞I/O模型 1.3 异步编程关键技术 1.3.1 事件循环机制 1.3.2 Future/Promise模式 1.3.3 协程&#xff08;Cor…