【STM32开发之寄存器版】(六)-通用定时器中断

一、前言

STM32定时器分类

STM32103ZET6具备8个定时器TIMx(x = 1,2,...,8)。其中,TIM1和TIM8为高级定时器,TIM2-TIM6为通用定时器,TIM6和TIM7为基本定时器,本文将以TIM3通用定时器为例,分析STM32定时器工作的底层寄存器原理。

STM32通用定时器简介

STM32的通用定时器是一个通过可编程预分频器驱动的16位自动装载计数器构成。使用定时器预分频器和RCC时钟控制器预分频器,脉冲长度和波形周期可以在几个微秒到几个毫秒间调整。每个定时器都是完全独立的,没有互相共享任何资源。它们可以一起同步操作。它适用于多种场合,包括测量输入信号的脉冲长度(输入捕获)或者产生输出波形(输出比较和 PWM)。

本文DEMO目标

本次DEMO将使用STM32F103ZET6的定时器TIM3实现DS1的翻转(定时器中断),在主函数用DS0的翻转来提示程序正在运行。

二、通用定时器的主要功能

通用TIMx (TIM2、TIM3、TIM4和TIM5)定时器功能包括:
● 16位向上、向下、向上/向下自动装载计数器
● 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为  1~65536  之间的任意 数值
● 4个独立通道:
─ 输入捕获
─ 输出比较
─ PWM生成(边缘或中间对齐模式)
─ 单脉冲模式输出
● 使用外部信号控制定时器和定时器互连的同步电路
● 如下事件发生时产生中断/DMA:
─ 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
─ 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
─ 输入捕获
─ 输出比较
● 支持针对定位的增量(正交)编码器和霍尔传感器电路
● 触发输入作为外部时钟或者按周期的电流管理

三、时钟树解析

定时器的时钟来源一共有以下4个:

  • 内部时钟(CK_INT)
  • 外部时钟模式 1:外部输入脚(TIx)
  • 外部时钟模式 2:外部触发输入(ETR)
  • 内部触发输入(ITRx):使用 A 定时器作为 B 定时器的预分频器(A 为 B 提供时钟)。

这些时钟,具体选择哪个可以通过 TIMx_SMCR 寄存器的相关位来设置。这里的 CK_INT时钟是从 APB1 倍频的来的,除非 APB1 的时钟分频数设置为 1,否则通用定时器 TIMx 的时钟是 APB1 时钟的 2 倍,当 APB1 的时钟不分频的时候,通用定时器 TIMx 的时钟就等于 APB1的时钟。

本文选用CK_INT作为定时器时钟来源。

系统时钟为72MHz,AHB不分频,APB1后最大频率为36MHz,故APB1作2分频,故TIM3的时钟是APB1时钟的2倍,即TIM3CLK=72MHz。具体时钟树解析如下所示:

四、寄存器介绍

对通用定时器TIM3的控制主要涉及以下寄存器:

寄存器作用
TIMx_CR1控制寄存器1
TIMx_DIERDMA/中断使能寄存器
TIMx_PSC预分频器
TIMx_SMCR从模式控制寄存器
TIMx_CNT计数器
TIMx_ARR自动重装载寄存器
TIMx_SR状态寄存器

下面将对这些寄存器进行一一介绍。

4.1 TIMx_CR1控制寄存器1

《STM32中文手册》对TIMx_CR1寄存器的描述如下:

我们仅需要关注其第7位和第0位,第7位为自动重装载允许位,具体作用见4.6节。第0位为计数器的使能位,该位必须置1,才能让定时器开始计数

4.2 TIMx_DIER DMA/中断使能寄存器

《STM32中文手册》对TIMx_DIER寄存器的描述如下:

我们仅需关注其第0位,该位为允许更新中断位,该位需要置1,才能允许更新事件所产生的中断。

4.3 TIMx_PSC预分频器

《STM32中文手册》对TIMx_PSC寄存器的描述如下:

该寄存器用于设计时钟分频,然后提供给计数器,作为计数器的时钟,该寄存器中值的范围是0-65535,按照公式fCK_CNT=fCK_PSC/(PSC[15:0]+1)。分频系数的范围为1-65536,按照前文对时钟树的解析,这里的fCK_PSC为72MHz。

4.4 TIMx_SMCR从模式控制寄存器

《STM32中文手册》对TIMx_SMCR寄存器的描述如下:

我们仅需关注该寄存器的位[2:0],即SMS从模式选择,将其设置为000,即关闭从模式,此时如果CEN=1,则预分频器直接由内部时钟驱动(CK_INT)。由于该寄存器的复位值为0X0000,故无需更改此寄存器的值。

4.5 TIMx_CNT计数器

《STM32中文手册》对TIMx_CNT寄存器的描述如下:

该寄存器是定时器的计数器,该寄存器存储了当前定时器的计数值。定时器的超时时间由下式计算:

Time = CNT / fCK_CNT

其中:

Time为超时时间,CNT为TIMx_CNT的计数值,fCK_CNT为定时器预分频频率。

4.6 TIMx_ARR自动重装载寄存器

《STM32中文手册》对TIMx_ARR寄存器的描述如下:

该寄存器包含了将要传送至实际的自动重装载寄存器的数值。该寄存器在物理上实际对应着 2 个寄存器。一个是程序员可以直接操作的,另外一个是程序员看不到的,这个看不到的寄存器在《STM32中文参考手册》里面被叫做影子寄存器。事实上真正起作用的是影子寄存器。根据 TIMx_CR1寄存器中 APRE 位的设置:APRE=0 时,预装载寄存器的内容可以随时传送到影子寄存器,此时 2 者是连通的;而 APRE=1 时,在每一次更新事件(UEV)时,才把预装在寄存器的内容传送到影子寄存器。我们将APRE值设置为0(复位时就是0,不用改)

4.7 TIMx_SR状态寄存器

《STM32中文手册》对TIMx_SR寄存器的描述如下:

我们只关注其第0位,该位为更新中断标记。当计数器 CNT 被重新初始化的时候,产生更新中断标记,通过这个中断标志位,就可以知道产生中断的类型。当该位为1时,表示中断产生,需要在中断服务函数中用软件对该位清0。

五、程序设计

该DEMO程序主要分为三个部分:定时器3初始化程序,定时器3中断服务程序以及轮询主函数。下面进行一一介绍。

5.1 定时器3初始化程序

该部分程序在HARDWARE/timer.c/TIM3_Int_Init(),主要作用是TIM3时钟使能、设置定时器超时值、允许中断更新、使能定时器3,并注册定时器3的中断,具体代码如下所示:

//通用定时器3中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{RCC->APB1ENR|=1<<1;	//TIM3时钟使能    TIM3->ARR=arr;  	//设定计数器自动重装值//刚好1ms    TIM3->PSC=psc;  	//预分频器7200,得到10Khz的计数时钟		  TIM3->DIER|=1<<0;   //允许更新中断	  TIM3->CR1|=0x01;    //使能定时器3MY_NVIC_Init(1,3,TIM3_IRQn,2);//抢占1,子优先级3,组2									 
}

5.2 定时器3中断服务程序

该部分程序在HARDWARE/timer.c/TIM3_IRQHandler(),主要作用是在定时器3中断溢出时进行LED1电平翻转,并清除SR寄存器中的中断标志位。具体代码如下所示:

//定时器3中断服务程序	 
void TIM3_IRQHandler(void)
{ 		    		  			    if(TIM3->SR&0X0001)//溢出中断{LED1=!LED1;			    				   				     	    	}				   TIM3->SR&=~(1<<0);//清除中断标志位 	    
}

5.3 轮询主函数

该部分程序在USER/test.c,主要作用是初始化定时器3(设置超时时间为500ms),在主循环函数中不断反转LED0电平,以示程序运行。具体代码如下所示:

#include "sys.h"
#include "delay.h"
#include "usart.h" 
#include "led.h" 
#include "timer.h" int main(void)
{					   Stm32_Clock_Init(9);	//系统时钟设置uart_init(72,115200); 	//串口初始化为115200delay_init(72);	   	 	//延时初始化 LED_Init();		  		//初始化与LED连接的硬件接口TIM3_Int_Init(4999,7199);//10Khz的计数频率,计数5K次为500ms  while(1){LED0=!LED0;delay_ms(200);		   }	
}	 

六、上机测试

将程序烧录至STM32F103ZET6,可见LED1按照500ms进行翻转(定时器中断),LED0按照200ms闪烁(轮询主函数)。具体效果如下所示:

至此完成通用定时器3中断DEMO! 

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

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

相关文章

You must konw JS!!(超详细的javascript套餐,适合计算机专业有基础的,包含常见前端开发面试题)

1.起源 JavaScript 起源于 1995 年&#xff0c;当时它主要是为了满足网页交互的需求而被创建。它最初的设计目的是为了让网页开发者能够在网页中添加一些简单的交互效果和动态内容。在那个时期&#xff0c;网页大多是静态的&#xff0c;而 JavaScript 的出现为网页带来了新的活…

jmeter学习(7)beanshell

beanshell preprocessor 发送请求前执行 beanshell postprocessor 发送请求前执行 获取请求相关信息 String body sampler.getArguments().getArgument(0).getValue(); String url sampler.getPath(); 获取响应报文 String responseprev.getResponseDataAsString(); 获…

CMake 教程跟做与翻译

目录 STEP 1: 入门与理解 cmake_minimum_required设置CMake版本的最小值 project声明工程属性 add_executable添加可执行文件 使用CMake构建工程 根据自己的构建工具自行构建 Reference STEP 1: 入门与理解 我们起手的&#xff0c;最基本的 CMake 项目是从单个源代码文件…

【Blender Python】1.概述和基础使用

概述 众所周知&#xff0c;Blender是一款开源免费的3D建模软件&#xff08;当然不限于3D建模&#xff09;。在Blender中&#xff0c;可以使用其内置的Python解释器执行Python代码&#xff0c;用于程序化的生成网格以及其他内容。你可以基于此创建Blender插件。 这个系列就是快…

Electron桌面应用打包现有的vue项目

1 环境准备 Node&#xff1a;v16.20.2&#xff08;本地vue项目nodejs版本&#xff09;Electron&#xff1a;22.3.7vue&#xff1a;2 版本管理 2 Vue项目准备 更新相关依赖npm install --registry https://registry.npmmirror.com/npm run dev 3、引入Electorn 安装指定版…

算法剖析:双指针

文章目录 双指针算法一、 移动零1. 题目2. 算法思想3. 代码实现 二、 复写零1. 题目2. 算法思想3. 代码实现 三、 快乐数1. 题目2. 算法思想3. 代码实现 四、 盛水最多的容器1. 题目2. 算法思想3. 代码实现 五、有效三角形的个数1. 题目2. 算法思想3. 代码实现 六、 和为 s 的两…

UART驱动学习三(TTY驱动部分源码解析)

目录 全局框架图一、tty_io.c 分析1. 关键数据结构和定义2. 文件操作结构体3. 初始化和注册4. 读写操作5. 挂起和恢复6. 信号处理7. 设备类8. 控制台通知9. 辅助函数10. 代码功能11. 带有注释的部分tty_io.c源码 二、tty_ldisc.c 分析1. 关键数据结构和定义2. 行规程操作函数3.…

Android车载——VehicleHal运行流程(Android 11)

1 概述 本篇主要讲解VehicleHal的主要运行流程&#xff0c;包括设置属性、获取属性、订阅属性、取消订阅、持续上报属性订阅等。 2 获取属性流程 2.1 获取属性流程源码分析 作为服务注册到hwServiceManager中的类是VehicleHalManager&#xff0c;所以&#xff0c;CarServic…

判断是否为二叉排序树(二叉搜索树,二叉查找树)

1.判断给定的二叉树是否为二叉排序树&#xff0c;如果是返回1&#xff0c;不是返回0。 思想&#xff1a; 二叉树是左子树<根<右子树。中序遍历是递增有序&#xff0c;可以通过比较当前结点与前驱关系来进行判断。 代码&#xff1a; //pre为全局变量&#xff0c;保存当…

数学与生活

多学科交叉 信号处理 小波 经济 政策 计算机 统计 信号处理与市场分析 经济与数据分析 政策与统计 过去的数学家没有一个是纯粹的数学家&#xff1b;生活中各方面工程的&#xff0c;物理的&#xff0c;天文&#xff0c;地理的&#xff0c;赌博&#xff0c;政治的&#xff1b…

5-25 JQuery

jQuery简介 jQuery是什么 jQuery基本语法 测试jQuery <head> <meta charset"utf-8"> <title>无标题文档</title><script type"text/javascript" src"jquery-3.5.1.js"></script><script type"tex…

FastAdmin Apache下设置伪静态

FastAdmin Apache下设置伪静态 一、引言 FastAdmin 是一个基于ThinkPHP和Bootstrap框架开发的快速后台开发框架&#xff0c;它以其简洁、高效、易于扩展的特点&#xff0c;广受开发者的喜爱。在部署FastAdmin项目时&#xff0c;为了提高访问速度和用户体验&#xff0c;我们通…

Redis介绍及整合Spring

目录 Redis介绍 Spring与Redis集成 Redis介绍 Redis是内存数据库&#xff0c;Key-value型NOSQL数据库&#xff0c;项目上经常将一些不经常变化并且反复查询的数据放入Redis缓存&#xff0c;由于数据放在内存中&#xff0c;所以查询、维护的速度远远快于硬盘方式操作数据&#…

【NIO基础】基于 NIO 中的组件实现对文件的操作(文件编程),FileChannel 详解

目录 1、FileChannel (1&#xff09;获取 FileChannel (2&#xff09;读取文件 (3&#xff09;写入文件 (4&#xff09;关闭通道 (5&#xff09;当前位置与文件大小 (6&#xff09;强制写入磁盘 2、两个 FileChannel 之间的数据传输 (1&#xff09;使用 transferTo()…

leetcode-42. 接雨水 单调栈

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表…

微软发布Windows 11 2024更新,新型Copilot+ AI PC功能亮相

前言 微软在Windows 11的2024更新中加强了对人工智能的应用&#xff0c;推出了新功能Copilot。 此次更新的版本号为26100.1742&#xff0c;Copilot将首先在Windows Insider中推出&#xff0c;计划于11月向特定设备和市场推广&#xff0c;用户需开启“尽快获取最新更新”选项以…

RESTful风格接口+Swagger生成Web API文档

RESTful风格接口Swagger生成Web API文档 文章目录 RESTful风格接口Swagger生成Web API文档1.RESTful风格接口RESTful简介RESTful详细图示常见http状态码springboot实现RESTfulRESTful springboot设计实例demo 2.Swagger生产Web API文档Swagger简介使用Swagger1.加入依赖2.配置S…

基于STM32的超声波测距仪设计

引言 本项目将基于STM32微控制器设计一个超声波测距仪&#xff0c;通过超声波传感器实现距离测量&#xff0c;并将结果显示在液晶屏上。该项目展示了STM32微控制器与超声波传感器、LCD显示器的接口通信&#xff0c;以及信号处理和距离计算的过程。 环境准备 1. 硬件设备 ST…

技术速递|Python in Visual Studio Code 2024年9月发布

排版&#xff1a;Alan Wang 我们很高兴地宣布将于 2024 年 9 月发布适用于 Visual Studio Code 的 Python 和 Jupyter 扩展&#xff01; 此版本包括以下公告&#xff1a; Django 单元测试支持使用 Pylance 从 inlay 提示转到定义 如果您有兴趣&#xff0c;可以在我们的 Pyth…

提升 CI/CD 稳定性:Jenkins 开机自检与推送通知

简介&#xff1a;Jenkins 是一个广泛使用的开源自动化服务器&#xff0c;常用于持续集成和持续交付。在某些情况下&#xff0c;服务器重启可能导致 Jenkins 构建任务中断或失败。为了解决这个问题&#xff0c;可以使用一个自检服务&#xff0c;定期检查系统的启动时间&#xff…