STM32--TIM定时器(1)
文章目录
- TIM简介
- 定时器类型
- 通用定时器
- 预分频器时序
- 计数器时序
- 定时中断基本结构
- TIM内部中断工程
- TIM外部中断工程
TIM简介
STM32的TIM(定时器)是一种非常常用的外设,用于实现各种定时和计数功能。它是基于时钟信号进行计数,并在计数值达到设定值时触发中断,执行相应的操作。
定时器类型
一般来说,STM32中有三类定时器:
在我们这款STM32F03C9T6有4种定时器资源:TIM1,TIM2,TIM3,TIM4;
对于定时器,类型越高级,拥有的功能越多,且向下兼容;
我们将以通用定时器进行讲解。
通用定时器
通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成。
它适用于多种场合,包括测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和PWM)。
使用定时器预分频器和RCC时钟控制器预分频器,脉冲信号长度和波形周期可以在几个微妙到几个毫秒间调整。
每个定时器都是完全独立的,没有互相共享任何资源。它们可以同步操作。
这是通用定时器的总框图,我将会分为几部分进行讲解。
这是定时器最基本的结构,通过RCC内部时钟产生的脉冲频率通向预分频器,频率分频后到计数器,当达到自动重装载寄存器的值,将会发出信号,或者触发中断。
RCC的TIMxCLK会产生一个72MHz的脉冲频率;
这一部分称为时基单元,是TIM计时器最主要的计数计时结构。
PSC预分频器会将72MHZ进行分频,可以按1到65536之间的任意值分频;将输入频率除以预分频器值就得到分频结果;
通过频率会在计数器中计数,通过传输的频率的上升沿,计数器将加一,
计数器取值范围为0到65535;所以计数的快慢由输入频率决定;
对于通用计数器来说,计数器是有多种模式进行计数的。
向上计数模式:计数器从0计数到自动加载值(TIMx_ARR计数器的内容),然后重新从0开始计数并且产生一个计数器溢出事件。
向下计数模式:计数器从自动装入的值(TIMx_ARR计数器的值)开始向下计数到0,然后从自动装入的值重新开始并且产生一个计数器向下溢出事件。
中央对齐模式:计数器从0开始计数到自动加载的值(TIMx_ARR寄存器)−1,产生一个计数器
溢出事件,然后向下计数到1并且产生一个计数器下溢事件;然后再从0开始重新计数。
自动重装载寄存器相当就是给计数器一个周期值,当计数器达到这个值就会产生中断,并清零计数器;计数器溢出中断后,会产生更新中断,传到NVIC中,最后传到CPU,那么定时器就能产生中断了。也会产生更新事件,它会触发内部其他电路的工作。
这部分,是定时器时钟频率的来源,在通用定时器中,不止有内部时钟,还有外部时钟。
第一个外部时钟TIMx_ETR,如果在引脚上默认有该功能,就能直接使用,作为外部时钟的连接引脚;
传输进来的方波信号会通过极性选择,边沿检测,滤波等进行整形,处理掉一些毛刺;滤波后的信号兵分两路,第一路是走到ETRF,通过触发控制器走到复位使能,这种走法称为“外部时钟模式2”。(TRIGO是映射功能,能够从主模式触发DAC)。第二路是TRGI,主要用作触发使用的,可以走到从模式;当然也可以走复位,使能那里,那么这样的外部时钟称为“外部时钟模式1”。
第二个的来源就是ITR,TRIGO可以通向其他定时器,其他定时器就是通过ITR引脚来连接的。
这是内部定时器连接的方式。可以允许4种定时器进行连接到定时器上,但是只允许一个定时器连接着一个定时器。
第三个一个是TIIF_ED,这里连接着输入捕获单元的CH1,ED为Edge,边沿的意思,触发方式上升沿和下降沿都有效。
最后一个是TI1FP1和TI2FP2
后续将会讲解。
下边的,左半部分为输入捕获电路,右半部分为输出比较部分,每部分都有4个通道可以进入,且输入和输出共用一个寄存器,意味着不能边输入边输出,具体功能将会后续讲解。
预分频器时序
这是一个预分频器从1变到2的时序图。
CK_PSC是时钟频率,一般都为72MHZ;
CNT_EN是计时器使能,只有在使能高电平状态下,才能运行。
CK_CNT是计时器时钟,它既是预分频器的时钟输出,也是计数器的时钟输入;当使能为高电平时,CNT开始运行,前半段频率跟时钟一样,后半段预分频器从1变到2,CNT让定时器上升沿减半,即一个周期有效,一个周期无效(保持低电平)。
在计时器时钟的驱动下,计时器寄存器也不断增加,当达到FC时(与自动重转载寄存器的值一样)将会从0开始;
更新事件UEV,当计数器寄存器到FC时,更新事件将会触发。
下面三个时序将一起看,这是预分频控制寄存器的缓冲机制,我们写入的值会到预分频控制寄存器上,当在计数器未归零之前写入时,为了保持完整性,将会在更新事件后才会进行分频。所以到预分频缓冲器上才是所读的正确结果,而预分频计数器会在1时保持定时器时钟为低电平,为0时保持原先状态。
计数器计数频率:CK_CNT = CK_PSC / (PSC + 1)
PSC相对我们输入者来说,就是0开始的,当对于PSC来说,是从1开始的。就像一块蛋糕,不切时它就是1份完整的,切一刀时,就会被分成两份。
计数器时序
大体来说与预分频器一致,当计数器寄存器满时,将会使计数器溢出,更新事件发生,更新中断标志。
计数器溢出频率:CK_CNT_OV = CK_CNT / (ARR + 1)
= CK_PSC / (PSC + 1) / (ARR + 1)
定时中断基本结构
对于我们来说,由于有库函数的提供,不需要管哪些寄存器,我们需要了解一些代码逻辑结构。
通过外部引脚GPIO就可连接外部时钟,然后选择时钟模式,接着对时基单元初始化,接上NVIC即可。
TIM内部中断工程
连接方式:
OLED函数可以点击连接
该工程将会实现走秒的例子。
Timer.h
#ifndef __TIMER_H__
#define __TIMER_H__void Timer_Init();#endif
Timer.c
#include "stm32f10x.h" // Device headervoid Timer_Init()
{//开启APB1外设开关RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//配置TIM2为内部时钟TIM_InternalClockConfig(TIM2);//时钟结构体初始化TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; //划分TIM2TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //计时器模式,上升沿计时TIM_TimeBaseInitStructure.TIM_Period=10000-1; //自动加载寄存器周期值TIM_TimeBaseInitStructure.TIM_Prescaler=7200-1; //预分频值TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0; //指定重复计时器的值,这里不用到TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//清除标志位TIM_ClearFlag(TIM2, TIM_FLAG_Update);//启用TIM2中断TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//配置优先级分组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC初始化NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;NVIC_Init(&NVIC_InitStructure);//启用TIM2外设控制TIM_Cmd(TIM2,ENABLE);
}
对于内部时钟,没有外部引脚的使用,记住TIM所在总线是APB1,先开启外设开关,接着配置TIM2的内部时钟,然后对时基单元结构体成员进行初始化,对于预分频器值,通过公式可知需要-1才能达到我们想要的数字,重复计时器是高级计时器的操作,这里不需要用到。
在初始化完将会生成一个更新事件,立即重新加载预分频和计时器的计算。在更新一个事件后,同时也会产生中断标志,为了让计时时从0开始,就采用了清除标志的函数。
最后记得启用TIM2的外设,否则无效。
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "Buzzer.h"
#include "LightSensor.h"
#include "OLED.h"
#include "Timer.h"uint16_t Count;
int main()
{OLED_Init();Timer_Init();while(1){OLED_ShowNum(1,1,Count,4);}
}//中断函数
void TIM2_IRQHandler()
{
//表示已经触发中断了if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET){Count++;//中断挂起位,中断结束后需要将中断位挂起,让下一个能进入中断TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}
}
TIM外部中断工程
接线方式:
通过对射式红外传感器的电平变化作为CNT的触发条件,然后通过10次的电平变化,让计时器溢出进1;
Timer.h
#ifndef __TIMER_H__
#define __TIMER_H__void Timer_Init();#endif
Timer.c
#include "stm32f10x.h" // Device headervoid Timer_Init()
{//开启APB1外设开关RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//配置TIM2为外部时钟模式2TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x0F);//时钟结构体初始化TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; //表示不分频TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //计时器模式TIM_TimeBaseInitStructure.TIM_Period=10-1; //自动加载寄存器周期值TIM_TimeBaseInitStructure.TIM_Prescaler=1-1; //预分频值TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0; //指定重复计时器的值,这里不用到TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//TIM_ClearFlag(TIM2, TIM_FLAG_Update);//启用TIM2中断TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//配置优先级分组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC初始化NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;NVIC_Init(&NVIC_InitStructure);//启用TIM2外设控制TIM_Cmd(TIM2,ENABLE);
}
外部时钟模式2:
TIM_ExtTRGPrescaler:外部触发预分频器
TIM_ExtTRGPolarity_NonInverted:触发极性为上升沿或高电平;
ExtTRGFilter:最后一个参数,表示滤波频率高低,可选范围0x00 and 0x0F;一般来说,滤波频率越高,毛刺与不规则信号处理的越干净。
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "Buzzer.h"
#include "LightSensor.h"
#include "OLED.h"
#include "Timer.h"uint16_t Count;
int main()
{OLED_Init();Timer_Init();while(1){OLED_ShowNum(1,1,Count,4);OLED_ShowNum(2,1,TIM_GetCounter(TIM2),5);}
}void TIM2_IRQHandler()
{if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET){Count++;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}
}
相关文章:

STM32--TIM定时器(1)
文章目录 TIM简介定时器类型 通用定时器预分频器时序计数器时序定时中断基本结构TIM内部中断工程TIM外部中断工程 TIM简介 STM32的TIM(定时器)是一种非常常用的外设,用于实现各种定时和计数功能。它是基于时钟信号进行计数,并在计…...

Android取证——基础知识
目录 一、安卓系统版本 二、安装操作系统UI 三、鉴权码 1.IMEI(手机序列号) 2.ICCID...

【学习心得】安装cuda/cudann和pytorch
一、查看驱动信息 # 进入CMD输入命令 nvidia-smi 也可以右下角图标打开NVIDIA 设置进行查看 二、下载安装CUDA 1、下载 下载地址 https://developer.nvidia.com/ 2、安装 推荐自定义安装。建议只勾选Cuda,只安装这一个就好,以免报错安装失败。 3、验证…...

中电金信通过KCSP认证 云原生能力获权威认可
中电金信通过KCSP(Kubernetes Certified Service Provider)认证,正式成为CNCF(云原生计算基金会)官方认证的 Kubernetes 服务提供商。 Kubernetes是容器管理编排引擎,底层实现为容器技术,是云原…...

【Spring】Bean的实例化
1、简介 在容器中的Bean要实例化为对象有三种方式 1、构造方法 2、静态工厂 3、实例工厂 4、实现工厂接口 2、构造方法 构造方法实例化Bean即是直接通过构造方法创建对象 <bean id"bookDao" class"com.wn.spring.dao.impl.BookDaoImpl"/> 当不存在…...

2023牛客暑期多校训练营8-C Clamped Sequence II
2023牛客暑期多校训练营8-C Clamped Sequence II https://ac.nowcoder.com/acm/contest/57362/C 文章目录 2023牛客暑期多校训练营8-C Clamped Sequence II题意解题思路代码 题意 解题思路 先考虑不加紧密度的情况,要支持单点修改,整体查询࿰…...

【GitLab私有仓库】如何在Linux上用Gitlab搭建自己的私有库并配置cpolar内网穿透?
文章目录 前言1. 下载Gitlab2. 安装Gitlab3. 启动Gitlab4. 安装cpolar5. 创建隧道配置访问地址6. 固定GitLab访问地址6.1 保留二级子域名6.2 配置二级子域名 7. 测试访问二级子域名 前言 GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具…...

企业计算机服务器遭到了locked勒索病毒攻击如何解决,勒索病毒解密
网络技术的不断发展,也为网络安全埋下了隐患,近期,我们收到很多企业的求助,企业的计算机服务器遭到了locked勒索病毒的攻击,导致企业的财务系统内的所有数据被加密无法读取,严重影响了企业的正常运行。最近…...

Redis哨兵模式搭建
Redis主从复制搭建 Redis虽然拥有非常高的性能,但是在实际的生产环境中,使用单机模式还是会产生不少问题的,比如说容易出现 单机故障,容量瓶颈,以及QPS瓶颈等问题。通常环境下,主从复制、哨兵模式、Redis…...

大语言模型控制生成的过程Trick:自定义LogitsProcessor实践
前言 在大模型的生成过程中,部分原生的大语言模型未经过特殊的对齐训练,往往会“胡说八道”的生成一些敏感词语等用户不想生成的词语,最简单粗暴的方式就是在大模型生成的文本之后,添加敏感词库等规则手段进行敏感词过滤…...

Docker容器:docker的资源控制及docker数据管理
文章目录 一.docker的资源控制1.CPU 资源控制1.1 资源控制工具1.2 cgroups有四大功能1.3 设置CPU使用率上限1.4 进行CPU压力测试1.5 设置50%的比例分配CPU使用时间上限1.6 设置CPU资源占用比(设置多个容器时才有效)1.6.1 两个容器测试cpu1.6.2 设置容器绑…...

从零开始打造家装预约咨询小程序
在如今互联网高度发达的时代,家装行业也逐渐意识到了线上渠道的重要性。为了更好地服务客户,提高用户体验,越来越多的家装公司开始寻找合适的小程序制作平台。本文将向大家介绍如何使用第三方制作平台,如乔拓云网,打造…...

es线上处理命令记录
常用命令 搜索 GET _search {"query": {"match_all": {}} }获取全部模版 GET _index_template GET _index_template/yst_crawler_template获取全部索引 GET /_cat/indices?v 获取当前mapping GET /yst_crawler/_mapping创建一个mapping PUT /yst_c…...

mysql 在nodejs中的简单使用(增删改查)
一 、封装SQL查询请求链接 const mysql require(mysql) //创建开发工具数据库链接池 const pool mysql.createPool({host: 192.168.1.133,user: user_name, password: 123456,database: database_name,port: 3306,connectionLimit: 50 // 限制连接数 });// sql:查…...

1.MySQL数据库的基本操作
数据库操作过程: 1.用户在客户端输入 SQL 2.客户端会把 SQL 通过网络发送给服务器 3.服务器执行这个 SQL,把结果返回给客户端 4.客户端收到结果,显示到界面上 数据库的操作 这里的数据库不是代表一个软件,而是代表一个数据集合。 显示当前的数据库 …...

Zabbix-6.4.4 邮箱告警SMS告警配置
目录 ------------------------- # 邮箱告警 ---------------------------------- 1.安装mailx与postfix软件包 2.修改mailx配置文件 3. 创建文件夹 4. 编写mail-send.sh脚本 5. 将该脚本赋予执行权限 6. 进入web界面进行设置—> Alerts —> Media Types 7. 添…...

网络安全 Day30-运维安全项目-容器架构上
容器架构上 1. 什么是容器2. 容器 vs 虚拟机(化) :star::star:3. Docker极速上手指南1)使用rpm包安装docker2) docker下载镜像加速的配置3) 载入镜像大礼包(老师资料包中有) 4. Docker使用案例1) 案例01::star::star::…...

深入理解设计模式-创建型之单例模式
为什么要使用单例 1、表示全局唯一 如果有些数据在系统中应该且只能保存一份,那就应该设计为单例类。 如:配置类:在系统中,我们只有一个配置文件,当配置文件被加载到内存之后,应该被映射为一个唯一的【配…...

Vue中路由缓存问题及解决方法
一.问题 Vue Router 允许你在你的应用中创建多个视图,并根据路由来动态切换这些视图。默认情况下,当你从一个路由切换到另一个路由时,Vue Router 会销毁前一个路由的组件实例并创建新的组件实例。然而,有时候你可能希望保持一些页…...

Linux与bash(基础内容一)
一、常见的linux命令: 1、文件: (1)常见的文件命令: (2)文件属性: (3)修改文件属性: 查看文件的属性: ls -l 查看文件的属性 ls …...

NVIDIA Omniverse与GPT-4结合生成3D内容
全球各行业对 3D 世界和虚拟环境的需求呈指数级增长。3D 工作流程是工业数字化的核心,开发实时模拟来测试和验证自动驾驶车辆和机器人,操作数字孪生来优化工业制造,并为科学发现铺平新的道路。 如今,3D 设计和世界构建仍然是高度…...

Windows Server --- RDP远程桌面服务器激活和RD授权
RDP远程桌面服务器激活和RD授权 一、激活服务器二、设置RD授权 系统:Window server 2008 R2 服务:远程桌面服务 注:该方法适合该远程桌面服务器没网络状态下(离线),激活服务器。 一、激活服务器 1.打开远…...

关于游戏盾
游戏盾(Game Shield)是一种针对游戏行业特点的网络安全解决方案,主要针对游戏平台面临的各种网络攻击和安全威胁。以下是一些原因,说明为什么游戏平台需要加游戏盾: 1. DDoS攻击:游戏平台通常容易受到分布式…...

回归预测 | MATLAB实现基于SSA-KELM-Adaboost麻雀算法优化核极限学习机结合AdaBoost多输入单输出回归预测
回归预测 | MATLAB实现基于SSA-KELM-Adaboost麻雀算法优化核极限学习机结合AdaBoost多输入单输出回归预测 目录 回归预测 | MATLAB实现基于SSA-KELM-Adaboost麻雀算法优化核极限学习机结合AdaBoost多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本…...

《cpolar内网穿透》外网SSH远程连接linux(CentOS)服务器
本次教程我们来实现如何在外公网环境下,SSH远程连接家里/公司的Linux CentOS服务器,无需公网IP,也不需要设置路由器。 视频教程 [video(video-jrpesBrv-1680147672481)(type-csdn)(url-CSDN直播https://live-file.csdnimg.cn/release/live/…...

IDEA启动报错【java.sql.SQLSyntaxErrorException: ORA-00904: “P“.“PRJ_NO“: 标识符无效】
IDEA报错如下: 2023-08-17 11:26:15.535 ERROR [egrant-biz,b48324d82fe23753,b48324d82fe23753,true] 24108 --- [ XNIO-1 task-1] c.i.c.l.c.RestExceptionController : 服务器异常org.springframework.jdbc.BadSqlGrammarException: ### Error queryin…...

Nginx详解
1、高并发时代 单台tomcat在理想情况下可支持的最大并发数量在200~500之间,如果大于这个数量可能会造成响应缓慢甚至宕机。 解决方案是通过多台服务器分摊并发压力,这不仅需要有多台tomcat服务器,还需要一台服务器专门用来分配请求。这既是…...

摸清一下mysql授权语句的实际执行关系
样例 ---------------------------------------------------------------------- grant all PRIVILEGES on db1.* to test% identified by test1; grant all PRIVILEGES on db2.* to test% identified by test2; grant all PRIVILEGES on db3.* to test127.0.0.1 identified …...

sCrypt于8月12日在上海亮相BSV数字未来论坛
2023年8月12日,由上海可一澈科技有限公司(以下简称“可一科技”)、 临港国际科创研究院发起,携手美国sCrypt公司、福州博泉网络科技有限公司、复旦大学区块链协会,举办的BSV数字未来论坛在中国上海成功落下帷幕。 本次…...

Hbase的列式存储到底是什么意思?一篇文章让你彻底明白
一、 HBase 定义 Apache HBase™ 是以 hdfs 为数据存储的,一种分布式、可扩展的 NoSQL 数据库。 二、 HBase 数据模型 HBase 的设计理念依据 Google 的 BigTable 论文,论文中对于数据模型的首句介绍。 Bigtable 是一个稀疏的、分布式的、持久的多维排…...