stm32单片机个人学习笔记7(TIM定时中断)

news2024/11/14 20:08:22

前言

本篇文章属于stm32单片机(以下简称单片机)的学习笔记,来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记,只能做参考,细节方面建议观看视频,肯定受益匪浅。

STM32入门教程-2023版 细致讲解 中文字幕_哔哩哔哩_bilibili

一、TIM简介

二、定时器类型

三、基本定时器框图

向上的箭头UI表示,计数值等于重装值产生的中断称为“更新中断”,之后会通往NVIC,再配置好NVIC的定时器通道,定时器更新中断就能得到CPU的响应了 

向下的箭头U表示,“更新事件”,其不会触发中断,但能触发内部其它电路的工作

可以将U更新事件映射到TRGO上,然后TRGO就会直接去触发DAC了,实现硬件自动化 

四、通用定时器框图

通用定时器支持向上计数模式和向下计数模式和中央对齐模式

向上计数模式是从0自增,增到重装值(基本定时器仅支持这一模式)

向下计数模式是从重装值自减,减到0

中央对齐模式是先从0自增,增到重装值,再从重装值自减,减到0

ETRF提供外部时钟,就是“外部时钟模式2”

当TRGI当作外部时钟来使用时,就是“外部时钟模式1” ,ITR是来自其它定时器的时钟信号(具体连接关系参考下表),实现定时器的级联

五、定时中断基本结构

六、预分频器时序

预分配缓冲器(影子寄存器) 才是真正起作用的,预分频控制寄存器的供我们读写的,作用是当计数值计到一半时,改变分频系数,其计数频率不会立马发生改变,而是在下一个计数周期才真正改变频率

七、计数器时序

更新中断标志(UIF)需要我们在中断程序中手动清零 

1. 计数器无预装时序

2.计数器有预装时序

有预装就是启用了影子寄存器,作用与分频器的影子寄存器类似,不过这里对应的是重装值 

八、RCC时钟树

九、实例一(定时器定时中断)

1.开启内部时钟

2.设置为内部时钟模式

3.时基单元初始化

4.清除系统启动产生的中断标志位(不然一启动就会产生一个中断事件)

5.中断输出控制 

6.NVIC分组及初始化

7.运行控制(开启计数)

Timer.c 

#include "stm32f10x.h"                  // Device header

void Timer_Init(void)
{
	//开启内部时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	
	//设置为内部时钟模式
	TIM_InternalClockConfig(TIM2);
	
	//时基单元初始化
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period = 1000 - 1;
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	//清除系统启动产生的中断标志位
	TIM_ClearFlag(TIM2, TIM_IT_Update);
	
	//中断输出控制
	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 = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	//运行控制
	TIM_Cmd(TIM2, ENABLE);
}

//中断函数
/*
void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update)==SET)
	{
		
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}
*/

 main.c

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

uint16_t Num;

int main(void)
{

	OLED_Init();
	Timer_Init();
	OLED_ShowString(1,1,"Num:");

	while (1)
	{
		OLED_ShowNum(1,5,Num,5);
		OLED_ShowNum(2,5,TIM_GetCounter(TIM2),5);
	}
}

void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update)==SET)
	{
		Num++;
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

 十、实例二(定时器外部时钟)

思路与实例一基本相同

Timer.c 

#include "stm32f10x.h"                  // Device header

/**
  * @brief  定时器2初始化
  * @param  无
  * @retval 无
  */
void Timer_Init(void)
{
	//开启内部时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	//初始化GPIO
	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
	TIM_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_IT_Update);
	
	//中断输出控制
	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 = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	//运行控制
	TIM_Cmd(TIM2, ENABLE);
}

/**
  * @brief  获取TIM2的计数值
  * @param  无
  * @retval 计数值
  */
uint16_t Timer_GetCounter(void)
{
	return TIM_GetCounter(TIM2);
}

/**
  * @brief  定时器2中断函数
  * @param  无
  * @retval 无
  */
/*
void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update)==SET)
	{
		
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}
*/

 main.c

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

uint16_t Num;

int main(void)
{
	OLED_Init();
	Timer_Init();
	OLED_ShowString(1,1,"Num:");
	OLED_ShowString(2,1,"CNT:");

	while (1)
	{
		OLED_ShowNum(1,5,Num,5);
		OLED_ShowNum(2,5,Timer_GetCounter(),5);
	}
}

void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update)==SET)
	{
		Num++;
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python可迭代对象(1)---从C++开发者学习python日记

目录 1。什么是可迭代对象? 2。列表(list) 列表的创建 列表基本操作 以上全部代码的总运行结果 列表脚本操作符 列表常用的方法和函数 列表推导式 ​编辑列表的嵌套 以上全部代码的总运行结果 复习列表内容 3。元组(tuple) 元组的基本运算 元组的方法 …

SFUD库移植

1.源码 GitHub - armink/SFUD: An using JEDECs SFDP standard serial (SPI) flash universal driver library | 一款使用 JEDEC SFDP 标准的串行 (SPI) Flash 通用驱动库 2.介绍 这个通用驱动库,实际就是帮你封装好了读写spiflash的函数, 我们只需要对接以下底层,就可以轻松…

快速了解使用路由器

插槽的使用和用法:slot 为什么要使用插槽: 在Vue.js等前端框架中 在Vue.js等前端框架中,插槽(Slot)是一种强大的工具,允许开发者在组件之间动态地传递和呈现内容。使用插槽的主要原因包括: …

【LTW】Domain General Face Forgery Detection by Learning to Weight

文章目录 Domain General Face Forgery Detection by Learning to Weightkey points方法LTW元分割策略学习过程损失函数实验评价结果消融实验总结Domain General Face Forgery Detection by Learning to Weight 会议:AAAI-21 作者: code: https://github.com/skJack/LTW 上…

用uniapp 及socket.io做一个简单聊天 升级 9

比这之前优化了以下功能 上线通知 群聊里适时显示在线人数 约请好友 通过好友通过socket 相应端自动变化 PC端可以拉取摄象头拍照 PC端可以录音发送 拉起摄象头发送录象 <template><view class""><scroll-view scroll-y"true" class&…

2024 离线ASR和TTS推荐与示例

2024 离线ASR和TTS推荐 文章目录 2024 离线ASR和TTS推荐一、前言二、安装与使用1、EdgeTTS的安装和使用&#xff08;1&#xff09;Edge TTS介绍与效果试听&#xff08;2&#xff09;Edge TTS安装&#xff08;3&#xff09;Edge TTS查看支持的音色&#xff08;4&#xff09;Edge…

16【Protues51单片机仿真】智能洗衣机倒计时系统

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 用直流电机转动模拟洗衣机。要求 有弱洗、普通洗、强洗三种模式&#xff0c;可通过按键选择。可以设置洗衣时长&#xff0c;通关按键选择15、30、45、60、90分钟。时间到蜂鸣器报警提示。LCD 显示…

MySQL:事务的ACID特性隔离级别脏读/不可重复读/幻读/Next-Key锁——场景复现

目录 1、什么是事务 2、 事务的ACID特性 2.1 事务的隔离性 3、为什么要使用事务&#xff1f; 4、查看支持事务的存储引擎 5、使用事务 5.1 控制事务 5.1.1 开启事务 5.1.2 关闭事务 5.2 开始一个事务&#xff0c;执行修改后回滚 5.3 开始一个事务&#xff0c;执行修…

set-ExecutionPolicy RemoteSigned 提示不是内部或外部命令,也不是可运行的程序或批处理文件

这个错误一般发生在使用命令提示符或者PowerShell窗口中找不到set-ExecutionPolicy RemoteSigned。如果你想在命令提示符或者PowerShell窗口运行set-ExecutionPolicy RemoteSigned&#xff0c;你需要搜索打开Window PowerShell ISE&#xff0c;并以管理员身份打开&#xff0c;输…

图结构感知的Transformer:一种新的图表示学习方法

人工智能咨询培训老师叶梓 转载标明出处 尽管图神经网络&#xff08;GNNs&#xff09;在处理图数据方面取得了显著成就&#xff0c;但它们在表达能力和捕获长距离依赖方面存在局限性。为了突破这些局限&#xff0c;研究者们开始探索将Transformer架构应用于图表示学习。在此基…

使用Electron打包一个Vue3项目全步骤

1.创建一个Vue3项目 2.使用 WebStorm打开项目&#xff0c;并安装依赖项 npm install 等待完成后&#xff0c; 安装electron npm install --save-dev electron 等待完成后&#xff0c; 安装electron 打包依赖项(打包成可执行文件) npm install electron-packager --save-dev 3…

从零开始一个git操作实例,图文并茂

徒弟不懂git怎么用&#xff0c; 于是写了篇文章&#xff0c; 把本地git操作从头写了一遍&#xff0c; 自己去看吧&#xff01; 0、基本概念 •Git是一个免费、开源的、分布式版本控制系统 •它使用一个特殊的叫做仓库的数据库来记录文件的变化 •仓库中的每个文件都有一个…

ccfcsp-202406(1、2、3、4、5)

矩阵重塑&#xff08;其一&#xff09; #include <bits/stdc.h> using namespace std; int main() {int n,m,p,q;cin >> n >> m >> p >> q;vector<int> vec(n * m);vector<vector<int>> res(p, vector(q,0));int k 0;for(in…

力扣反转链表系列【25. K 个一组翻转链表】——由易到难,一次刷通!!!

力扣《反转链表》系列文章目录 刷题次序&#xff0c;由易到难&#xff0c;一次刷通&#xff01;&#xff01;&#xff01; 题目题解206. 反转链表反转链表的全部 题解192. 反转链表 II反转链表的指定段 题解224. 两两交换链表中的节点两个一组反转链表 题解325. K 个一组翻转…

HarmonyOS---权限和http/Axios网络请求

网络请求(http,axios) 目录 一、应用权限管理1.1权限的等级1.2授权方式1.3声明权限的配置1.4如何向用户进行申请 二、内置http请求使用三、Axios请求使用&#xff08;建议&#xff09;3.1 使用方式一3.2 使用方式二&#xff08;建议&#xff09; 一、应用权限管理 应用权限保护…

git仓库服务器端损坏如何用本地code重新部署

文章目录 1. **在新服务器上创建一个新的 Git 仓库**2. **将本地仓库推送到新服务器**2.1. 添加新服务器为远程仓库2.2. 推送代码和历史记录2.3. 推送 tags&#xff08;如果有 tags&#xff09; 3. **在新服务器上拉取代码并部署**4. **确保修改记录和历史完整**5. **可选&…

Flink Task 日志文件隔离

Flink Task 日志文件隔离 任务在启动时会先通过 MdcUtils 启动一个 slf4j 的 MDC 环境&#xff0c;然后将 jobId 添加到 slf4j 的 MDC 容器中&#xff0c;随后任务输出的日志都将附带 joid。 MDC 介绍如下&#xff1a; MDC ( Mapped Diagnostic Contexts )&#xff0c;它是一个…

Linux 线程互斥

文章目录 3. Linux 线程互斥3.1 相关概念3.2 互斥量mutex3.3 互斥量的接口3.4 改进3.2中的代码3.5 互斥量&#xff08;锁&#xff09;的原理3.6 封装一下原生锁的接口&#xff0c;RAII风格的锁3.7 可重入 和 线程安全 3. Linux 线程互斥 3.1 相关概念 临界资源&#xff1a;多…

web自动化学习笔记

目录 一、web自动化测试环境搭建二、web自动化测试第一个脚本三、selenium 8种定位方式3.1、通过id定位3.2、通过name定位3.3、通过tag_name&#xff08;标签名&#xff09;定位3.4、通过class值进行定位3.5、通过链接文本定位3.6、通过部分链接文本定位3.7、通过xpath定位3.8、…

MySQL:SQL语句执行过程

本篇文章会分析下一个 SQL 语句在 MySQL 中的执行流程&#xff0c;包括 SQL 的查询在 MySQL 内部会怎么流转&#xff0c;SQL 语句的更新是怎么完成的。 在分析之前我会先带着你看看 MySQL 的基础架构&#xff0c;知道了 MySQL 由那些组件组成以及这些组件的作用是什么&#xf…