STM32:基本定时器原理和定时程序
一、初识定时器TIM
定时器就是计数器,定时器的作用就是设置一个时间,然后时间到后就会通过中断等方式通知STM32执行某些程序。定时器除了可以实现普通的定时功能,还可以实现捕获脉冲宽度,计算PWM占空比,输出PWM波形,编码器计数等。
STM32共11个定时器,2个高级控制定时器TIM1和TIM8,4个通用定时器TIM2~TIM5,两个基本定时器TIM6和TIM7,两个看门狗定时器和一个系统滴答定时器Systick.
高级定时器TIM1和TIM8的时钟由APB1产生,其它六个通用定时器的时钟由APB2产生。它们的最大频率都可以配置成系统时钟的频率。
| 定时器种类 | 位数 | 计数模式 | 捕获/比较通道 | 应用场景 |
|---|---|---|---|---|
| 通用定时器 TIM2~TIM5 | 16 | 向上,向下,双向 | 4 | 定时计数,PWM,输入捕获,输出比较 |
| 高级定时器 TIM1和TIM8 | 16 | 向上,向下,双向 | 4 | 在通用的基础上,多了刹车信号输入,死区时间互补输出等工业电机功能 |
| 基本定时器 TIM6和TIM7 | 16 | 向上,向下,双向 | 4 | 定时计数 |
二、基本定时器
(1)计数功能原理
在上一期文章提到,时钟树提供稳定频率的方波信号,APB1上的时钟线连接了基本定时器和通用寄存器,APB2上的时钟线连接了高级定时器。

对于实现计数功能,只需要一个寄存器就可以满足,寄存器只需要读到时钟信号的上升沿数值就加1。假如72MHZ的时钟信号作为输入,当该寄存器数值累加到7.2*10^7,就代表时间过去了1秒。但是寄存器通常只有16bit,最多能计数 65536个数。因此在该寄存器前面还要加一个类似的计数器,当计数满足条件时才往后续电路发送高电平,预分频器就可以充当这个角色,其本质也是一个16bit的计数器。当只需要将其设置为n-1,就可以进行n分频,从0开始计数,一直计数到n-1才会向后续电路发送高电平。预分频器最多可以进行65536分频。因此一个由预分频器和一个计数器组合成的定时器,最多可以计数65536^2次。m个定时器串联,就可以计数65536^(2*m)次。

(2) 自动重装载寄存器
自动重装载寄存器,它的作用就是实时监控计数器的值是否与自己的值相同。当计数器的值与自己的值相同时,便将计数器重置为0,并触发定时器更新中断。

(3)影子寄存器
所谓的影子寄存器就是某个寄存器的拷贝。在上图中工作在一线的预分频器和自动重装载寄存器其实都是自己的影子寄存器。当定时器正在工作时,如果重新设置预分频器值或者重新这是自动重装载寄存器的值,那么只有当计数器和自动重装载寄存器的值一样时才会将新值更新到自身影子寄存器中。也就是给定时器设置的新参数值要等下个计数周期才生效。
自动重装载寄存器可以根据程序员选择是否开启影子寄存器。如果不开启,那么将自动重装载寄存器数值调小时,可能会错过计数器的值,使计数器一路上到65536才会归0。
三、定时程序
(1)准备工作
为了发送数据进行模拟,需打开USART2用于设置模式为“异步”,在NVIC Settings中打开中断,打上√,在DMA Settings,打开DMA传输功能,添加传输通道。

为提高计数精度,将外部时钟源设置为"晶振",在时钟设置界面中的HCLK的频率设置为72MHZ,自动调整其它器件的时钟频率。


对于我使用的STM32F108T6芯片只有4个定时器,即1个高级,3个通用寄存器。虽然没有基本定时器,但是这些定时器都包含了基本定时器功能。只需要对定时器的时钟源选择 Internal Clock (内部时钟源)就算打开了定时器。因为本次模拟的时钟频率是72MHZ,设置预分频器7200,自动重装载寄存器为10000,那么完成一个周期的计数就是1s,也就是1s触发一次定时器更新中断。同第一步类似,TIM也可以开启中断和DMA通道。保存并生成代码。

(2)实现定时任务和获取计数器数值:
以下示例代码为开启TIM中断和USART2中断实现,以及开启了自动重装载寄存器的影子寄存器
1.开启定时器
HAL_TIM_Base_Start(&htim); //用阻塞的方式开始定时器
HAL_TIM_Base_Start_IT(&htim); //用中断(非阻塞)的方式开始定时器
HAL_TIM_Base_Start_DMA(&htim); //用DMA(非阻塞)的方式开始定时器
2.中断回调函数
在路径 ~/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c中
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
当计数器数值和自动重装载寄存器值一样时调用
3.读写定时器中寄存器的宏定义操作
__HAL_TIM_GET_ANTORELOAD //获取自动重装载寄存器数值
__HAL_TIM_SET_ANTORELOAD //设置自动重装载寄存器数值
__HAL_TIM_GET_COUNTER //获取计数器数值
__HAL_TIM_SET_COUNTER //设置计数器数值
__HAL_TIM_SET_PRESCALER //设置预分频器数值
4.示例代码
/* USER CODE BEGIN Includes */
#include <string.h>
#include <stdio.h>
/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim4;UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_rx;
DMA_HandleTypeDef hdma_usart2_tx;/* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_TIM4_Init(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
char message2[]="☺☹";
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){if(htim == &htim4){HAL_UART_Transmit_IT(&huart2, (uint8_t*)message2,strlen(message2));}
}
/* USER CODE END 0 *//*** @brief The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_DMA_Init();MX_USART2_UART_Init();//TIM4的初始化MX_TIM4_Init();/* USER CODE BEGIN 2 *///用中断的方式开启定时器HAL_TIM_Base_Start_IT(&htim4);int counter = 0;char message[20];/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){counter = __HAL_TIM_GET_COUNTER(&htim4);sprintf(message,"counter:%d",counter);//每隔100ms发送 counter计数器数值//HAL_UART_Transmit_IT(&huart2, (uint8_t*)message,strlen(message));//延迟100msHAL_Delay(100-1);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}
相关文章:
STM32:基本定时器原理和定时程序
一、初识定时器TIM 定时器就是计数器,定时器的作用就是设置一个时间,然后时间到后就会通过中断等方式通知STM32执行某些程序。定时器除了可以实现普通的定时功能,还可以实现捕获脉冲宽度,计算PWM占空比,输出PWM波形&am…...
EntityFramework 批量删除操作
刚刚开始使用Entityframwork 来操作数据库。遇到了批量删除数据。 EF内部用的方法是:dbcontext.Datas.RemoveRange(list); 这总方法,少量数据是可行的。 但遇到大数据量的时候,这个方法完全不能用。 所以找了另一种方法: stri…...
springboot使用的设计模式
设计模式是在软件设计中常用的一些通用解决方案。在开发商城编码时,以下设计模式可能会有用: 工厂模式(Factory Pattern): 用于创建对象的模式。在商城中,可能会涉及到创建不同类型的商品、订单等对象&…...
IP地址定位技术发展与未来趋势
随着互联网的快速发展,人们对网络的需求和依赖程度越来越高。在海量的网络数据传输中,IP地址定位技术作为网络安全与信息追踪的重要手段,其精准度一直备受关注。近年来,随着技术的不断进步,IP地址定位的精准度得到了显…...
AI与交通运输
人工智能(AI)正在改变几乎所有行业,交通运输也不例外。 虽然与某些行业相比,我们运输货物和乘客的方式在过去 50 年里变化相对较小,但人工智能有望引发一场运输革命—如果你正在寻找人工智能的机会,不要错过…...
window.requestAnimationFrame+localStorage+canvas实现跨窗口小球连线效果
文章目录 前言效果代码后言 前言 hello world欢迎来到前端的新世界 😜当前文章系列专栏:前端系列文章 🐱👓博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板。(如果出现错误,感谢大家…...
使用AndResGuard报错:copy res file not in resources.arsc file:Ezi.xml
Android使用AndResGuard进行资源混淆,压缩。 源码地址:GitHub - shwenzhang/AndResGuard: proguard resource for Android by wechat team 集成完成后编译过程中出现如下错误: 14:57:05 copy res file not in resources.arsc file:IUk.xml…...
插入排序(形象类比)
最近在看riscv手册的时候,里面有一段代码是插入排序,但是单看代码的时候有点迷,没看懂咋操作的,后来又查资料复习了一下,最终才把代码看明白,所以写篇博客记录一下。 插入排序像打扑克牌 这是我听到过比较形…...
ElasticSearch 同步的方式
ElasticSearch 同步的方式 ElasticSearch是一款强大的分布式搜索和分析引擎,支持多种方式同步数据和日志。下面介绍几种常见的同步方式: 1. Logstash Logstash 是 ElasticStack 的一部分,用于收集、处理和转发日志和事件数据。通过配置 Lo…...
easyExcel实现分批导入,动态表头分批导出,以及导出表格样式设置
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.6</version></dependency> 一,分批导入 1.首先配置表格头映射类 Getter Setter EqualsAndHashCode public class …...
Android BottomNavigationView底部菜单栏文字显示问题
1. BottomNavigationView 如果tab栏数据小于等于3个,那么图标和文字都是展示出来; 2. BottomNavigationView 如果tab栏数据大于3个,那么图标会显示出来,但是文字会隐藏; 3. 解决方式: (当底部…...
从零开始学习typescript——运算符(条件运算法、逻辑运算符、类型运算符、位运算)
条件运算符 条件运算符是一个根据条件返回不同运算结果的运算符 关键字:?: 三元运算符 它可以换成if …else 判断 ? true : false 判断为true,返回?号后面的,判断为false ,返回: 号后面的 逻辑运算符 用…...
【开源】基于Vue.js的康复中心管理系统
项目编号: S 056 ,文末获取源码。 \color{red}{项目编号:S056,文末获取源码。} 项目编号:S056,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 普通用户模块2.2 护工模块2.3 管理员…...
抢先看|第二届世界直播电商大会邀您共话时代“新电商”
党的二十大报告指出,要加快发展数字经济,促进数字经济和实体经济深度融合。要深化国家数字经济创新发展试验区建设,打造一批具有国际竞争力的战略性新兴产业集群和数字产业集群。电子商务作为数字经济中规模最大、表现最活跃、发展势头最好的…...
火爆火爆!影响超250万读者,Python入门圣经全新升级!
人生苦短,快学Python! 什么?你没用过,也没开始学习,甚至没有认真了解过这门语言?那你一定这一秒就开始发力——下面让我们先简单看看 Python 有多火。权威编程语言排行榜 TIOBE,2022 和 2023 都…...
大数据学习(23)-hive on mapreduce对比hive on spark
&&大数据学习&& 🔥系列专栏: 👑哲学语录: 承认自己的无知,乃是开启智慧的大门 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一下博主哦ᾑ…...
通过这个简单的技巧让我们的 JavaScript 代码变得异常快
通过这个简单的技巧让我们的 JavaScript 代码变得异常快 秘诀:了解JavaScript 虚拟机(VM)的内部工作原理。 首先,我们来谈谈像 V8 这样的JavaScript 虚拟机(VM)。可以把它想象成我们的操作的大脑 —— 它将我们简洁的代码变成计算机可以理解和执行的东…...
vue怎么实现国际化? vue-i18n 插件实现国际化,支持切换不同语言
依赖的文档开始 | Vue I18n 一、安装 npm install vue-i18n 如果在一个模块系统中使用它,你必须通过 Vue.use() 明确地安装 vue-i18n: import Vue from vue import VueI18n from vue-i18nVue.use(VueI18n)二、使用 在 src 下创建 lang 文件夹 1.准…...
rabbit MQ的延迟队列处理模型示例(基于SpringBoot延时插件实现)
rabbitMQ安装插件rabbitmq-delayed-message-exchange 交换机由此type 表示组件安装成功 生产者发送消息时设置延迟值 消息在交换机滞纳至指定延迟后,进入队列,被消费者消费。 组件注解类: package com.esint.configs;import org.springfra…...
虽不想承认,但这就是CSGO游戏搬砖行业的现状
CSGO搬砖日常出货更新 其实整个搬砖市场,现在已经变得乌烟瘴气,散发着“恶臭”。我个人非常鄙视那些虚有其表,大小通吃的做法,那些甚至连搬砖数据都看不懂的人,也出来吹嘘着“实力强大,经验丰富”。这个世界…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
高防服务器价格高原因分析
高防服务器的价格较高,主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因: 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器,因此…...
怎么开发一个网络协议模块(C语言框架)之(六) ——通用对象池总结(核心)
+---------------------------+ | operEntryTbl[] | ← 操作对象池 (对象数组) +---------------------------+ | 0 | 1 | 2 | ... | N-1 | +---------------------------+↓ 初始化时全部加入 +------------------------+ +-------------------------+ | …...
【大模型】RankRAG:基于大模型的上下文排序与检索增强生成的统一框架
文章目录 A 论文出处B 背景B.1 背景介绍B.2 问题提出B.3 创新点 C 模型结构C.1 指令微调阶段C.2 排名与生成的总和指令微调阶段C.3 RankRAG推理:检索-重排-生成 D 实验设计E 个人总结 A 论文出处 论文题目:RankRAG:Unifying Context Ranking…...
【R语言编程——数据调用】
这里写自定义目录标题 可用库及数据集外部数据导入方法查看数据集信息 在R语言中,有多个库支持调用内置数据集或外部数据,包括studentdata等教学或示例数据集。以下是常见的库和方法: 可用库及数据集 openintro库 该库包含多个教学数据集&a…...
Vue3学习(接口,泛型,自定义类型,v-for,props)
一,前言 继续学习 二,TS接口泛型自定义类型 1.接口 TypeScript 接口(Interface)是一种定义对象形状的强大工具,它可以描述对象必须包含的属性、方法和它们的类型。接口不会被编译成 JavaScript 代码,仅…...
【见合八方平面波导外腔激光器专题系列】用于干涉光纤传感的低噪声平面波导外腔激光器2
----翻译自Mazin Alalus等人的文章 摘要 1550 nm DWDM 平面波导外腔激光器具有低相位/频率噪声、窄线宽和低 RIN 等特点。该腔体包括一个半导体增益芯片和一个带布拉格光栅的平面光波电路波导,采用 14 引脚蝶形封装。这种平面波导外腔激光器设计用于在振动和恶劣的…...
