基于STM32CubeMX和keil采用STM32F407的基本定时器中断实现LED闪烁

文章目录

  • 前言
  • 1. 电路原理图理解
  • 2. 基本定时器
    • 2.1 STM32定时器中断的流程:
    • 2.2 部分参数详解
      • 2.2.1 时钟源
      • 2.2.2 预分频系数
      • 2.2.3 自动重装载值
  • 3. STM32CubeMX参数配置
    • 3.1GPIO配置
    • 3.2 时钟配置
    • 3.2 配置定时器相关参数
    • 3.3 Debug配置
    • 3.4 中断配置
    • 3.5 代码生成
  • 4. keil代码编写
  • 总结

前言

定时器有三种,基本定时器,通用定时器,以及高级定时器。
这篇博客以最简单的基本定时器为例,实现LED的闪烁。
后面两种定时器的用法后面再写。

实现功能:
TIM6控制LED每隔0.5s变一次状态。
TIM7控制LED1常量2s后熄灭。


1. 电路原理图理解

因为都是用到LED,所以和上一篇基于STM32CubeMX与keil采用按键外部中断方式控制LED与蜂鸣器类似。
这里就直接复制粘贴了。
在这里插入图片描述
在这里插入图片描述

LED部分:
3.3V电压经过一个电阻R12连到DS0发光二极管,如果VCC和LED0对应的引脚之间存在压降,则DS0导通,发光。
3.3V电压经过一个电阻R14连到DS1发光二极管,如果VCC和LED1对应的引脚之间存在压降,则DS1导通,发光。

因此我们要先让LED发光的话,要让LED0和LED1标号对应的引脚输出低电平,才能确保LED0和LED1发光,但由于我们默认状态是LED亮的,所以这里都先要制为高电平。

2. 基本定时器

STM32F407ZET6芯片中
TIM6,TIM7是基本定时器
TIM2-5,TIM9~14是通用定时器
TIM1,TIM8是高级定时器

2.1 STM32定时器中断的流程:

定时器配置:首先,您需要配置定时器的参数,例如时钟源、预分频系数和计数器的自动重装载值。这些参数决定了定时器的计数速度和定时间隔。

中断配置:接下来,您需要配置定时器中断。在STM32中,每个定时器都有一个中断使能位和一个中断标志位。通过设置中断使能位,您可以启用或禁用定时器中断。中断标志位用于指示中断事件是否已经发生。您可以在中断处理函数中清除中断标志位。

中断处理函数:当定时器达到设定的计数值时,将触发定时器中断,并跳转到相应的中断向量表入口处执行中断处理函数。您需要实现该中断处理函数来执行所需的操作。在中断处理函数中,可以进行一些定时相关的任务,例如更新变量、发送数据或触发其他事件。

中断优先级:在多个中断同时发生时,优先级决定了哪个中断先被处理。STM32提供了优先级组的设置,您可以根据需要配置不同的中断优先级。

定时器相关参数详解参考:

2.2 部分参数详解

2.2.1 时钟源

STM32微控制器系列提供了多种时钟源选项,以满足不同的应用需求。以下是一些常见的时钟源选项:

HSI(High-Speed Internal)内部高速时钟:HSI是STM32内部集成的高频振荡器,通常为16MHz。它是默认的系统时钟源,在芯片上电后自动启动。HSI适用于大多数应用场景,提供相对较高的精度和稳定性。
HSE(High-Speed External)外部高速时钟:HSE使用外部晶体振荡器或时钟源提供稳定的时钟信号。HSE的频率范围可以根据具体的芯片型号而变化,通常为4MHz到25MHz。外部时钟源相对于内部时钟提供更高的精确性和稳定性。
LSI(Low-Speed Internal)内部低速时钟:LSI是低频振荡器,通常为32kHz。它用于一些低功耗应用,例如RTC(实时时钟)或独立看门狗定时器(IWDG)。
LSE(Low-Speed External)外部低速时钟:LSE使用外部晶体振荡器或时钟源提供低速时钟信号。它通常为32.768kHz,用于RTC和低功耗模式。
PLL(Phase-Locked Loop)锁相环:PLL是一种用于产生高频时钟的电路。它可以通过将输入时钟信号(如HSI或HSE)经过倍频和分频来产生更高频率的时钟。PLL提供了灵活的时钟频率调整能力,适合高性能应用。

请注意,具体的时钟源选项和配置方法可能因芯片型号和系列而有所不同。在使用特定型号的STM32芯片时,您应查阅芯片的数据手册和参考手册,以获取详细的时钟源配置信息。

2.2.2 预分频系数

预分频系数用于设置定时器时钟频率的分频比。它确定了定时器计数器每个时钟周期递增的步长,从而影响定时器的计数速度和定时间隔。

具体的预分频系数选项和配置方法可能因芯片型号和系列而有所不同。以下是一些常见的预分频系数配置:

APB分频系数(PCLKx):APB(Advanced Peripheral Bus)是STM32中用于连接外设的总线。通过配置APB分频系数,可以将系统时钟(SYSCLK)分频得到适合外设工作的时钟频率。常见的预分频系数选项包括2、4、8和16。

TIMx预分频系数:定时器模块(TIM)有自己的预分频器,可以将时钟源的频率进一步分频。具体的预分频系数选项和配置方法因芯片型号和定时器模块而异。

PLL倍频系数(PLLM、PLLN、PLLP):如果使用PLL锁相环来产生高频时钟,可以通过设置不同的倍频系数来调整PLL输出时钟的频率。PLLM为输入分频器系数,PLLN为倍频器系数,PLLP为输出分频器系数。

2.2.3 自动重装载值

自动重装载值(Auto-reload value)是一个重要的参数,用于控制定时器计数器的溢出和重新加载。

定时器计数器在每个时钟周期递增,当达到自动重装载值时,计数器将重新加载为初始值,并触发中断(如果已启用)。这种重新加载的操作使定时器可以周期性地生成中断或触发其他事件。

自动重装载值的大小决定了定时器的定时间隔。通常,自动重装载值的设置可以通过以下公式计算:

自动重装载值 = (定时周期 / 时钟周期) - 1,这里减一是因为从0开始算,例如0~9实际上计数了10个.

其中,定时周期是所需的定时间隔,时钟周期是定时器的时钟频率。通过更改自动重装载值,可以调整定时器的定时间隔。

在STM32中,自动重装载值可以存储在定时器的自动重装载寄存器(ARR)中。通过将自动重装载寄存器设置为所需的值,可以实现定时器的周期性操作。

需要注意的是,自动重装载值应适当选择,以确保不会发生溢出。应根据所需的定时间隔和定时器的时钟频率来选择合适的值,避免溢出或过长的定时间隔。


3. STM32CubeMX参数配置

3.1GPIO配置

在这里插入图片描述

在这里插入图片描述

3.2 时钟配置

在这里插入图片描述

为了便于我们计算,我们这里最终的时钟设置为100MHz,前面的时钟源以及分频系数等都会自动设置好。
在这里插入图片描述给到定时器的时钟其实是APB1和APB2中获取的,因为我这篇博客写的是基本定时器的博客所以我们要找到的基本定时器TIM6,TIM7对应的时钟,这里是APB1。

在这里插入图片描述

STM32F407ZET3的其他的定时器所在总线等这里列个表

定时器类型定时器名称定时器所在总线
基本定时器TIM6、TIM7APB1
通用定时器TIM2~5,TIM12~14APB1
通用定时器TIM9~11APB2
高级定时器TIM1,TIM8APB2

3.2 配置定时器相关参数

在这里插入图片描述
在这里插入图片描述

这里分频系数是49999,即0~49999,长度为50000,我们APB1总线传过来的时钟是50MHz,所以说明每一个时钟周期都是1ms。

A P B 1 时钟 T I M 6 分频系数 = 50 ∗ 1 0 6 H z 5 ∗ 1 0 4 = 1 K H z = 1 T ( 时间 ) = > T = 1 m s \frac{APB1时钟}{TIM6分频系数}=\frac{50*10^6Hz}{5*10^4}=1KHz=\frac{1}{T(时间)}=>T=1ms TIM6分频系数APB1时钟=510450106Hz=1KHz=T(时间)1=>T=1ms
对于TIM6控制的LED,我们的目标是0.5s转换一次LED的状态,所以这里这里的计数重载是500-1,因为从0开始计数。

写到这,简单点理解就是,从时钟源分频时钟到总线,定时器从总线再分频,用来作为时间的分度值,这个说法可能不恰当,但意思就是一个时钟周期多少秒,接着用计数重载值 * 刚才的分度值就是我们想要的时间。即每隔多少时间,干什么。

TIM7的设置也同样,只不过计数重载值为1999,这里就不贴全图了。
在这里插入图片描述


3.3 Debug配置

在这里插入图片描述

3.4 中断配置

其实时钟配置里面的NVIC打开了之后,这里其实就自动勾选配好了。
在这里插入图片描述优先级抢占和响应:当两个中断发生且优先级不同时,优先级高的中断会抢占正在执行的低优先级中断。如果多个中断具有相同的优先级,则根据抢占式(Preemption)和响应式(Response)的设定来确定中断的顺序。先看抢占式优先级,前面数值越小,优先级越高,如果一样则看后面的优先级,数值也是越小越优先。

这篇博客其实对优先级要求不是那么高,不会怎么涉及抢占优先级等情况。所以这里默认0 , 0就行。

还有一个就是代码生成的时候是否生成对应的中断服务函数之类的,都默认勾选上。
在这里插入图片描述


3.5 代码生成

在这里插入图片描述

在这里插入图片描述


4. keil代码编写

打开生成的项目中的stm32f4xx_it.c文件
在这里插入图片描述
再最下面直接添加下列代码

在这里插入图片描述

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(htim->Instance==TIM6)
	{
		HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);
	}
	if(htim->Instance==TIM7)
	{
		HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
	}
}

说明一下为什么重写这个函数,当定时器达到设定的计数值时,将触发定时器中断,并跳转到相应的中断向量表入口处执行中断处理函数。您需要实现该中断处理函数来执行所需的操作。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

计数值超过500就会触发中断,调用功能这个回调函数,这里我们看函数名就知道了。PeriodElapseCallback和我们设置的那个值对应。

在这里插入图片描述


最后就是烧录程序了,这个和我这个专栏第一篇都一样,具体参考这篇博客

总结

这篇博客详细记录了定时器的简单使用,从目标出发到原理阐释再到配置与代码编写,一步一步实现功能。难度不是很大,中断处理部分与上一篇有很多共性的地方,学习起来也比较快。就是记录的时候比较费时间。写这篇博客的部分内容用了下chatGPT工具,效果也挺好,确实提高了部分效率。

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

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

相关文章

关于Java中的Lambda变量捕获

博主简介:想进大厂的打工人博主主页:xyk:所属专栏: JavaEE进阶 目录 一、Lambda表达式语法 二、Lambda中变量捕获 一、Lambda表达式语法 基本语法: (parameters) -> expression 或 (parameters) ->{ statements; } Lambda表达式由三部分组成&a…

小米新专利曝光:解决升降摄像头痛点,隐藏式摄像头指日可待

根据国家知识产权局官方网站的最新消息,小米移动软件公司的“摄像头隐藏式电子设备及隐藏式摄像头”的专利申请在今天获得了授权。 这款电子设备的主要组成部分包括壳体、摄像模组和可伸缩的反射组件。壳体上设有一个开口,可以让反射组件向外伸出。反射组…

美容店预约小程序制作教程详解

现在,制作一个专属于美容店的预约小程序不再需要编程经验,通过乔拓云网提供的后台管理系统,你可以轻松地完成整个制作过程。下面,我将为你详细介绍如何DIY一个美容店预约小程序。 首先,登录乔拓云网的后台管理系统&…

redis到底几个线程?

通常我们说redis是单线程指的是从接收客户端请求->解析请求->读写->响应客户端这整个过程是由一个线程来完成的。这并不意味着redis在任何场景、任何版本下都只有一个线程 为何用单线程处理数据读写? 内存数据储存已经很快了 redis相比于mysql等数据库是…

Qt完成文本转换为语音播报与保存(系统内置语音引擎)(二)

一、前言 随着人工智能技术的不断发展,语音技术也逐渐成为人们关注的焦点之一。语音技术在很多领域都有着广泛的应用,例如智能家居、智能客服、语音识别等等。其中,语音转文字技术是语音技术中的一个重要分支,它可以将语音转换成可编辑的文本,为人们的生活和工作带来了更…

中缀表达式转后缀表达式,使用逆波兰计算。可以计算小数

1、使用方法 传递一个分开保存符号与数字的List即可&#xff1a;List SumNumber; 获取参数的构造方法如下&#xff1a; public ReversePolish(List<String> sumNumber) {SumNumber sumNumber;}要求的List保存数据的方式如下&#xff1a; 例如&#xff1a;123 然后使用…

MFC表格控件CListCtrl的改造及用法

1、目的 简单描述MFC的表格控件使用方法。Qt适用习惯了以后MFC用的比较别扭&#xff0c;因此记录一下以备后续复制代码使用。由于MFC原生的CListCtrl比较局限&#xff0c;比如无法改变表格的背景色、文字颜色等设定&#xff0c;因此先对CListCtrl类进行重写&#xff0c;以便满足…

Jenkins 拉取 GitHub 私有仓库失败问题

添加仓库的时候提示 stderr: fatal: Cannot prompt because user interactivity has been disabled. 把在 GitHub账户设置中生成的个人访问令牌填到地址里

第54步 深度学习图像识别:MLP-Mixer建模(Pytorch)

基于WIN10的64位系统演示 一、写在前面 &#xff08;1&#xff09;MLP-Mixer MLP-Mixer&#xff08;Multilayer Perceptron Mixer&#xff09;是Google在2021年提出的一种新型的视觉模型结构。它的主要特点是完全使用多层感知机&#xff08;MLP&#xff09;来处理图像&#…

Docker Compose(九)

一、背景&#xff1a; 对于现代应用来说&#xff0c;大多数都是通过很多的微服务互相协同组成一个完整的应用。例如&#xff0c;订单管理、用户管理、品类管理、缓存服务、数据库服务等&#xff0c;他们构成了一个电商平台的应用。而部署和管理大量的服务容器是一件非常繁琐的事…

Sentinel Dashboard集成Nacos

1.前言 当项目上Sentinel Dashboard做流量监控的时候&#xff0c;我们可以通过Sentinel控制台修改限流配置&#xff0c;但当我们使用Nacos作为配置中心动态配置流控规则的时候&#xff0c;问题就来了。 首先我们要明白&#xff0c;Sentinel Dashboard的配置是从机器的内存中加…

【kubernetes系列】flannel之vxlan模式原理

概述 在Kubernetes中要保证容器之间网络互通&#xff0c;网络至关重要。而Kubernetes本身并没有自己实现容器网络&#xff0c;而是而是借助CNI标准&#xff0c;通过插件化的方式自由接入进来。在容器网络接入进来需要满足如下基本原则&#xff1a; Pod无论运行在任何节点都可…

运算放大器--------加减运算电路

反向求和运算电路 电路 公式 同向加法运算电路 电路 公式 加减运算电路 分别求正向输入的输出和反相输入的输出&#xff0c;然后求和就可以得到到最终的输出。 切记&#xff0c;虚短虚断不是真正的断路和短路。

this关键字和同步异步宏认为微任务理解

目录 js面试常见问题&#xff1a;1.this指向 2.闭包定义和作用 3.原型链 4.异步协程 this关键字 this主要有以下几个使用场合。 1&#xff09;全局环境 &#xff08;2&#xff09;构造函数 &#xff08;3&#xff09;对象的方法 避免多层this 避免数组处理方法中的 this 避免回…

C++(14):重载运算与类型转换

当运算符被用于类类型的对象时&#xff0c;允许我们为其指定新的含义&#xff1b;同时&#xff0c;也能自定义类类型之间的转换规则。和内置类型的转换一样&#xff0c;类类型转换隐式地将一种类型的对象转换成另一种我们所需类型的对象。 当运算符作用于类类型的运算对象时&a…

lc154.寻找旋转排序数组中的最小值

最小元素的位置以旋转次数为索引的位置&#xff0c;但是没有告诉旋转次数&#xff0c;换一种思路 当遇到arr[index] > arr[index1]时&#xff0c;index1为最小元素的位置。首位位置独立比较。但是这种方法还是遍历数组 观察两组数的中间值与首尾的值&#xff0c;又由于数组…

【C++】图

目录 图的存储结构邻接矩阵&#xff08;Adjacency Matrix&#xff09;无向(网)图邻接矩阵代码实现&#xff1a; 邻接表(Adjacency Lists) 图的遍历邻接矩阵深度和广度遍历DFS_BFS邻接表深度和广度遍历DFS_BFS 最小生成树普里姆&#xff08;Prim&#xff09;算法克鲁斯卡尔&…

Spring 6【单例设计模式、bean标签的scope属性、Spring 循环注入问题】(八)-全面详解(学习总结---从入门到深化)

目录 十五、单例设计模式 十六、bean标签的scope属性 十七、Spring 循环注入问题 十五、单例设计模式 设计模式&#xff1a;根据面向对象五大设计思想衍生出的23种常见代码写法&#xff0c;每种写法可以专门解决一类问题。 单例设计模式&#xff1a;保证某个类在整个应用程…

PLC的高端版本通常具有以下特点:

高速处理能力&#xff1a;高端PLC通常具有更快的处理速度和更高的运行频率&#xff0c;可以处理更复杂的控制逻辑和更多的输入/输出信号。 大容量存储&#xff1a;高端PLC通常具有更大的存储容量&#xff0c;可以保存更多的程序和数据&#xff0c;以满足更复杂的应用需求。 多种…

uniapp 选择城市定位 根据城市首字母分类排序

获取城市首字母排序&#xff0c;按字母顺序排序 <template><view class"address-wrap" id"address"><!-- 搜索输入框-end --><template v-if"!isSearch"><!-- 城市列表-start --><view class"address-sc…