STM32TIM定时器(1)

文章目录

  • 前言
  • 一、介绍部分
    • TIM简介
    • 了解定时器类型
      • 基本定时器框图
      • 通用定时器框图
      • 高级定时器框图
      • 定时器级联关系
    • 所需简化定时器中断流程图
    • 时序部分
      • 预分频器时序
      • 计数器时序
        • 无影子寄存器计数器时序
        • 有影子寄存器计数器时序
    • 时钟树
  • 二、实例部分
    • 使用定时器计数
    • 使用对射红外传感器来控制计数器
      • 电路连接
      • 代码部分
  • 总结
    • 所使用函数总结
    • NVIC分组与优先级分配的关系


前言

简介STM32的定时器,主要连接通用定时器的用法,了解定时器中断的原理,以及如何基础的利用定时器中断


一、介绍部分

TIM简介

在这里插入图片描述

了解定时器类型

注意定时器的编号以及所在总线

在这里插入图片描述

基本定时器框图

计数器加到阈值选择中断会进入NVIC(即框图的向上的箭头),称更新中断,向下的箭头表示产生一个新的事件,触发内部其他电路工作,而不是进入中断,称更新事件。

在这里插入图片描述
主模式触发DAC:即通过更新时间,映射到TRGO,这样就可以不需要频繁中断来输出波形

通用定时器框图

在这里插入图片描述
基本定时器计数器只有向上计数
通用和高级定时器计数器有三种方法如下图:
在这里插入图片描述

高级定时器框图

在这里插入图片描述

定时器级联关系

在这里插入图片描述

所需简化定时器中断流程图

在这里插入图片描述

时序部分

预分频器时序

在这里插入图片描述

计数器时序

在这里插入图片描述

无影子寄存器计数器时序

在这里插入图片描述

有影子寄存器计数器时序

在这里插入图片描述

时钟树

在这里插入图片描述

二、实例部分

使用定时器计数

硬件电路只需连接STM32最小电路与OLED即可
封装定时器初始化函数Timer.c内容如下:

#include "stm32f10x.h"                  // Device header

void Timer_Init(void){
	// 初始化时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	// 使用内部时钟(默认)
	TIM_InternalClockConfig(TIM2);
	// 配置事间基础(时基单元)
	TIM_TimeBaseInitTypeDef TIM_InitStructure;
	// 时钟分频
	TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	// 计算模式
	TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	// 重载值(有1的偏差)<计数值> 10000/10000=1
	TIM_InitStructure.TIM_Period = 10000-1;
	// 预分频(有1的偏差)<频率> 72000000/7200=10000
	TIM_InitStructure.TIM_Prescaler = 7200-1;
	// 重复计数器(不使用)
	TIM_InitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2,&TIM_InitStructure);
	
	// 由于时基初始化后会立即进入中断一次,提前清除以下标志位
	TIM_ClearFlag(TIM2,TIM_IT_Update);
	
	// 中断使能,更新中断到NVIC
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
	
	// NVIC分组
	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 = 1;
	// 响应优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
	NVIC_Init(&NVIC_InitStructure);
	
	// 启动定时器
	TIM_Cmd(TIM2,ENABLE);
}

uint16_t Num;

uint16_t GetNum(void){
	return Num;
}

//中断函数
void TIM2_IRQHandler(void){
	// 获取中断标志位
	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET){
		Num++;
		// 清除标志位
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
	}
}

主函数逻辑main.c内容如下:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"


int main(void)
{
	OLED_Init();
	Timer_Init();
	OLED_ShowString(1,1,"Num:");
	while (1)
	{
		OLED_ShowNum(2,1,GetNum(),4);
		// 查看计数器的变化
		OLED_ShowNum(3,1,TIM_GetCounter(TIM2),4);
	}
}

使用对射红外传感器来控制计数器

红外传感器每产生10次上升沿即Num+1

电路连接

在这里插入图片描述

代码部分

封装定时器内容Timer.c

#include "stm32f10x.h"                  // Device header

void Timer_Init(void){
	// 初始化时钟
	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);
	
	// 使用外部时钟模式2,不分频,中断方式,滤波
	/*
		@arg TIM_ExtTRGPolarity_Inverted: active low or falling edge active.
        @arg TIM_ExtTRGPolarity_NonInverted: active high or rising edge active.
	*/
	// 使用红外传感器的上升沿作为计数器+1
	TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x0f);
	
	// 配置事间基础(时基单元)
	TIM_TimeBaseInitTypeDef TIM_InitStructure;
	// 时钟分频
	TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	// 计算模式
	TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	// 重载值(有1的偏差)<计数值>
	TIM_InitStructure.TIM_Period = 9-1;
	// 预分频(有1的偏差)<频率>
	TIM_InitStructure.TIM_Prescaler = 1-1;
	// 重复计数器(不使用)
	TIM_InitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2,&TIM_InitStructure);
	
	// 由于时基初始化后会立即进入中断一次,提前清除以下标志位
	TIM_ClearFlag(TIM2,TIM_IT_Update);
	
	// 中断使能,更新中断到NVIC
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
	
	// NVIC分组
	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 = 1;
	// 响应优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
	NVIC_Init(&NVIC_InitStructure);
	
	// 启动定时器
	TIM_Cmd(TIM2,ENABLE);
}

uint16_t Num;

uint16_t GetNum(void){
	return Num;
}

//中断函数
void TIM2_IRQHandler(void){
	// 获取中断标志位
	if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET){
		Num++;
		// 清除标志位
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
	}
}

主函数main.c内容:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Timer.h"


int main(void)
{
	OLED_Init();
	Timer_Init();
	OLED_ShowString(1,1,"Num:");
	OLED_ShowString(2,1,"CNT:");
	while (1)
	{
		OLED_ShowNum(1,6,GetNum(),4);
		// 查看计数器的变化
		OLED_ShowNum(2,6,TIM_GetCounter(TIM2),4);
	}
}


总结

所使用函数总结

// 时钟初始化(时钟分频、计数模式、重载值、分频值、重复计数器值)
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
// 启动定时器
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
// 设置外部定时器模式2
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, 
                             uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
//  使中断更新到NVIC                          
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
// 获取定时器计数器的值
uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);
// 获取定时中断标志位
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
// 清除标志位
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
// 获取定时中断标志位(适用于中断函数内)
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
// 清除标志位(适用于中断函数内)
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);

NVIC分组与优先级分配的关系

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[计算机提升] 还原系统:系统映像

6.4 还原系统&#xff1a;系统映像 1、打开系统设置&#xff0c;进入到恢复页面&#xff0c;然后点击高级启动中的立即重新启动进入到高级启动页面。 2、点击疑难解答 3、点击高级选项 4、点选查看更多恢复选项到下一步系统映像修复&#xff1a; 5、点选系统映像恢复 …

.NET Core 实现 JWT 认证

写在前面 JWT&#xff08;JSON Web Token&#xff09;是一种开放标准, 由三部分组成&#xff0c;分别是Header、Payload和Signature&#xff0c;它以 JSON 对象的方式在各方之间安全地传输信息。通俗的说&#xff0c;就是通过数字签名算法生产一个字符串&#xff0c;然后在网络…

实例分割论文阅读之:《Mask Transfiner for High-Quality Instance Segmentation》

1.摘要 两阶段和基于查询的实例分割方法取得了显著的效果。然而&#xff0c;它们的分段掩模仍然非常粗糙。在本文中&#xff0c;我们提出了一种高质量和高效的实例分割Mask Transfiner。我们的Mask Transfiner不是在规则的密集张量上操作&#xff0c;而是将图像区域分解并表示…

Pymysql之Cursor常用API

Cursor常用API 1、cursor.execute(query, argsNone)&#xff1a;执行sql语句。 参数: query (str)&#xff1a;sql语句。 args (tuple, list or dict)&#xff1a;sql语句中如果有变量&#xff0c;或者格式化输出&#xff0c;会在这里填充数据。 Returns&#xff1a;返…

springboot项目启动报错:dynamic-datasource can not find primary datasource

项目启动报错信息 Caused by: com.baomidou.dynamic.datasource.exception.CannotFindDataSourceException: dynamic-datasource can not find primary datasourceat com.baomidou.dynamic.datasource.DynamicRoutingDataSource.determinePrimaryDataSource(DynamicRoutingDat…

七、Nacos源码系列:Nacos服务发现

目录 一、服务发现 二、getServices()&#xff1a;获取服务列表 2.1、获取服务列表 2.2、总结图 三、getInstances(serviceId)&#xff1a;获取服务实例列表 3.1、从缓存中获取服务信息 3.2、缓存为空&#xff0c;执行订阅服务 3.2.1、调度更新&#xff0c;往线程池中…

DC-8靶机渗透详细流程

信息收集&#xff1a; 1.存活扫描&#xff1a; arp-scan -I eth0 -l └─# arp-scan -I eth0 -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:dd:ee:6a, IPv4: 192.168.10.129 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.10…

uni使用openlayer加载本机离线地图

manifest.json添加配置 "runmode": "liberate"(默认为normal) 把地图打包进apk&#xff0c;这样手机每次访问地图就可以访问到工程文件夹的地图资源了&#xff0c;不用每次都请求云资源&#xff0c;消耗流量太大了

第9章 安全漏洞、威胁和对策(9.11-9.16)

9.11 专用设备 专用设备王国疆域辽阔&#xff0c;而且仍在不断扩张。 专用设备是指为某一特定目的而设计&#xff0c;供某一特定类型机构使用或执行某一特定功能的任何设备。 它们可被看作DCS、物联网、智能设备、端点设备或边缘计算系统的一个类型。 医疗设备、智能汽车、…

《MySQL 简易速速上手小册》第3章:性能优化策略(2024 最新版)

文章目录 3.1 查询优化技巧3.1.1 基础知识3.1.2 重点案例3.1.3 拓展案例 3.2 索引和查询性能3.2.1 基础知识3.2.2 重点案例3.2.3 拓展案例 3.3 优化数据库结构和存储引擎3.3.1 基础知识3.3.2 重点案例3.3.3 拓展案例 3.1 查询优化技巧 让我们来聊聊如何让你的 MySQL 查询跑得像…

【python】if __name__ == ‘__main__‘:

if __name__ __main__: 是一个Python脚本中使用的常见结构&#xff0c;用来判断该脚本文件是直接运行的还是被导入到其他文件中运行的。 当一个Python文件被运行时&#xff0c;Python解释器会自动创建一些特殊的变量&#xff0c;__name__就是其中之一。如果这个文件是作为主程…

米贸搜|Facebook在购物季使用的Meta广告投放流程

一、账户简化 当广告系列开始投放后&#xff0c;每个广告组都会经历一个初始的“机器学习阶段”。简化账户架构可以帮助AI系统更快获得广告主所需的成效。例如&#xff1a; 每周转化次数超过50次的广告组&#xff0c;其单次购物费用要低28%&#xff1b;成功结束机器学习阶段的…

Ondo宣布将其原生稳定币USDY带入Sui生态

重要提示&#xff1a;USDY是由短期美国国债支持的token化票据&#xff0c;持有者享受稳定币的实用性同时获得收益。USDY不得在美国或向美国人出售或以其他方式提供。USDY也未根据1933年美国证券法注册。 不到一年的时间&#xff0c;Sui已经成为全链TVL排名前十的区块链&#xf…

Netty源码 之 ByteBuf自适应扩缩容源码

Netty体系如何使得ByteBuf根据实际IO收发数据场景进行自适应扩容缩容的&#xff1f; IO收发数据的过程&#xff1a; read 读取&#xff08;"I"&#xff09;&#xff1a;网卡硬件通过网络传输介质读取对端传输过来的数据&#xff0c;网卡硬件再把数据写到recv-socke…

Flask 入门7:使用 Flask-Moment 本地化日期和时间

如果Web应用的用户来自世界各地&#xff0c;那么处理日期和时间可不是一个简单的任务。服务器需要统一时间单位&#xff0c;这和用户所在的地理位置无关&#xff0c;所以一般使用协调世界时&#xff08;UTC&#xff09;。不过用户看到 UTC 格式的时间会感到困惑&#xff0c;他们…

Linux系统安装(CentOS Vmware)

学习环境安装 VMware安装 VMware下载&安装 访问官网&#xff1a;https://www.vmware.com 在此处可以选择语言 点击China&#xff08;简体中文&#xff09; 点击产品&#xff0c;点击Workstation Pro 下滑&#xff0c;点击下载试用版 下滑找到Workstation 17 Pro for Wi…

如何查看端口映射?

端口映射是一种用于实现远程访问的技术。通过将外网端口与内网设备的特定端口关联起来&#xff0c;可以使外部网络用户能够通过互联网访问内部网络中的设备和服务。在网络中使用端口映射可以解决远程连接需求&#xff0c;使用户能够远程访问设备或服务&#xff0c;无论是在同一…

彻底学会系列:一、机器学习之线性回归(一)

1.基本概念(basic concept) 线性回归&#xff1a; 有监督学习的一种算法。主要关注多个因变量和一个目标变量之间的关系。 因变量&#xff1a; 影响目标变量的因素&#xff1a; X 1 , X 2 . . . X_1, X_2... X1​,X2​... &#xff0c;连续值或离散值。 目标变量&#xff1a; …

DAY7 作业

1.简易QQ登录页面 实际效果 qss界面代码 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget) {ui->setupUi(this);this->setWindowTitle("QQ"); /*设置窗口标题*/this->…

python官网下载慢怎么办?这里是一些解决方法

为什么Python官网下载速度慢&#xff1f; Python官网是开源软件的官方网站&#xff0c;提供了Python编程语言的最新版本和相关资源供开发者下载。然而&#xff0c;由于全球用户访问量较大&#xff0c;有时候会导致Python官网的下载速度变慢或不稳定。这对于急需获取Python的开…