基于STM32+定时器中断和定时器外部时钟(标准库函数讲解)

前言


       本篇博客主要学习了解定时器的标准库函数,以及定时器中断进行LED灯的反转,还有定时器外部时钟获取脉冲计数功能。本篇博客大部分是自己收集和整理,如有侵权请联系我删除。

本篇博客主要是对通用定时器来讲解,功能适中比较常用。

本次博客开发板使用的是正点原子精英版,芯片是STM32F103ZET6,需要资料可以@我拿取。

本博客内容原创,创作不易,转载请注明
————————————————

一. STM32定时器标准库函数了解

对定时器不了解的可以先去看看: TIM定时器详解

在学习库函数之前,首先我们得先了解定时器的基本机构和框图来进行分析:

1.首先定时器的基本作用就是定时的功能,还有对外部脉冲检测

2.然后就是四个输入捕获通道,四个输出比较通道,获取预分频和重装载值,标志位等等

3.高级定时器的高级功能死区和刹车生成暂时不需要了解

4.时钟选择函数

由此可见,细分之后的定时器库函数并不多,接下来主要讲下新手常用的库函数了解就行。

接下来借鉴一下我群友做的笔记来了解一下常用标准库函数的组成和作用吧!

二 .  定时器中断步骤(内部时钟)

步骤详解:

  • RCC开启时钟,打开基准时钟和基本外设
  • 选择定时器的时钟(这次选择内部时钟)
  • 配置时基单元
  • 配置输出中断控制,允许更新中断
  • 配置NVIC,打开中断通道,分配优先级
  • 配置中断服务函数逻辑

定时器初始化

针对开发板的例子,本次说明使用通用定时器TIM3来控制LED定时翻转

如图所示,本次需要用到的就是前四个参数,最后一个是高级定时器才用到的,这里暂时不了解。

1)选择时钟源

TIM_InternalClockConfig(TIM3);

可以不选,芯片内部自动上电选择就是RCC时钟,但是用到外部时钟要配置。

2)时钟:需要使能定时器时钟        时钟总线的频率是72M

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

TIM3 是挂载在 APB1 之下,所以我们通过 APB1 总线下的使能使能函数来使能 TIM3。

3)预分频器 ARR:

TIM_TimeBaseStructure.TIM_Prescaler = 7199;

默认定时器时钟频率为72M,那么预分频器设置为7199,那么一次计数为1S

4)定时器周期 PSC:

设置为9999,那么产生一次定时器中断的时间为1ms  

TIM_TimeBaseStructure.TIM_Period = 10000 - 1;

//自动重装载寄存器为9999,则产生一次中断时间为1s

5)分频因子

时钟分频因子:一般选择1分频,就是不分频

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

6)计数模式:一般选择向上计数模式

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

// 计数器计数模式,选择向上计数模式

7)初始化定时器

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

8)配置对应的NVIC中断,优先级根据自己需要修改

9)开启定时器中断

TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);//允许更新中断

10)使能计数器 

TIM_Cmd(TIM3, ENABLE);

11)中断服务函数逻辑

12)初始化就进入中断的解决方法 

在初始化之后,开启中断之前

再次执行TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx更新中断标志  

 三. 定时器中断代码(例程time.c)


//通用定时器3中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
		NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
	
	//定时器TIM3初始化
	TIM_TimeBaseStructure.TIM_Period = arr; 				//设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
	TIM_TimeBaseStructure.TIM_Prescaler =psc; 			//设置用来作为TIMx时钟频率除数的预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; 		//设置时钟分割:TDTS = Tck_tim,不分频
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
 
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断

	//中断优先级NVIC设置
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器


	TIM_Cmd(TIM3, ENABLE);  //使能TIMx					 
}

//定时器3中断服务程序
void TIM3_IRQHandler(void)   //TIM3中断
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
		{
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志 
		LED1=!LED1;
		}
}

四 . 定时器外部时钟(获取外部脉冲计次) 

外部时钟操作介绍和注意点:

1.既然是通过外部输入的,我们的模块就选择一个输入引脚,本篇博客参考江科大的代码,实现对射红外传感器实现获取外部脉冲。

2.然后就是不选择内部时钟源了,我们可以选择外部时钟1或者外部时钟2,本次我们选择外部时钟2_ETR

TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x00);

核心代码是通过选择外部时钟,然后最后一个参数根据实际情况选择,因为有些人可能获取数据比较快,不稳定,就可以修改这个参数来滤波。

然后其他代码和中断基本相似,就贴代码看看就行了

最后一个滤波参数说明

 

外部时钟2代码:

#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);
	
	TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x00);
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;			//不分频
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;	//向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 10 - 1;							//获取十次之后计数器清0		
	TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;						//每获取一次记一个数
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;				//高级定时器才用这个,所以给0,
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);					//事件更新中断
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;						//定时器2
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;						//中断使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;	
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_Cmd(TIM2, ENABLE);
}

uint16_t Timer_GetCounter(void)
{
	return TIM_GetCounter(TIM2);		//获取脉冲计次
}

总结:

        以上就是本次博客的定时器中断和外部时钟的介绍和例程代码,具体都是通过预分频和重装载值来玩这个定时器,难度不高,属于定时器的基础内容,如有错误,欢迎各位交流指正。

   点赞收藏关注双击博主,不定期分享单片机知识,互相学习交流。
————————————————
 

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

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

相关文章

判断数组中每个元素是否为负数 numpy.signbit()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 判断数组中每个元素是否为负数 numpy.signbit() [太阳]选择题 请问以下代码中最后输出结果是? import numpy as np a np.array([-1, 0, 1]) print("【显示】a ",a) pr…

智能优化算法应用:基于帝国主义竞争算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于帝国主义竞争算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于帝国主义竞争算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.帝国主义竞争算法4.实验参数设定5.算…

运维知识点-PostgreSql

PostgreSql 下载安装地址安装组件数据目录设置superuser密码 端口安装语言安装完成,是否安装Stack Builder 下载 https://www.postgresql.org/download/windows/ https://get.enterprisedb.com/postgresql/postgresql-13.7-1-windows-x64.exe 我下载的 13.7 安装…

【MySQL数据库】SQL查询语句总结

目录 一、查询数据 1.1 基本查询语句 1.2 表单查询 1.3 WHERE子句 1.3.1 IN关键字查询 1.3.2 Between查询范围 1.3.3 Like匹配查询 1.3.4 AND多条件查询(等同于&&) 1.3.5 OR多条件查询(等同于||) 1.3.6 LIMIT子句 1.3.7 对…

基于Java SSM框架实现母婴儿用品网站系统项目【项目源码+论文说明】

基于java的SSM框架实现母婴儿用品网站系统演示 摘要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 母婴用品网站,主要的模块包括管理员;主页、个人中心、用户管理、商品分…

架构图是什么,该怎么制作?

架构图是指可视化展示软件、系统、应用程序、网络等各种体系结构的一类图表或图形,它能够形象地展示体系结构中各个组成部分和它们之间的关系。 架构图的类型 架构图的种类比较多,逐一列举不太合适,这里只列举一些常见的架构图类型&#…

Oracle E-Business Suite软件 任意文件上传漏洞(CVE-2022-21587)

0x01 产品简介 Oracle E-Business Suite(电子商务套件)是美国甲骨文(Oracle)公司的一套全面集成式的全球业务管理软件。该软件提供了客户关系管理、服务管理、财务管理等功能。 0x02 漏洞概述 Oracle E-Business Suite 的 Oracle…

LeetCode刷题---斐波那契数列模型

顾得泉:个人主页 个人专栏:《Linux操作系统》 《C/C》 《LeedCode刷题》 键盘敲烂,年薪百万! 一、第N个泰波那契数 题目链接:1137. 第 N 个泰波那契数 题目描述 泰波那契序列Tn定义如下: T00,T11,T2 1,且在n&g…

2023.11.30 homework

兴趣最重要了,没兴趣不喜欢勉强带来的苦楚,并不能促使变好变优秀。 虽然我们的社会环境依旧很残酷,各种各样的硬性要求。

Docker + Jenkins + Nginx实现前端自动化部署

目录 前言一、前期准备工作1、示例环境2、安装docker3、安装Docker Compose4、安装Git5、安装Nginx和Jenkinsnginx.confdocker-compose.yml 6、启动环境7、验证Nginx8、验证Jenkins 二、Jenkins 自动化部署配置1、设置中文2、安装Publish Over SSH、NodeJS(1&#x…

PC端数据列表有头像显示头像,没有头像显示名字的第一个字

PC端数据列表有头像显示头像&#xff0c;没有头像显示名字的第一个字 .charAt(0) 是 JavaScript 字符串对象的方法&#xff0c;用于获取字符串的第一个字符。 字符串中的字符位置是从 0 开始的&#xff0c;所以.charAt(0) 就表示获取字符串的第一个字符。 <el-table ref&qu…

Android Studio Giraffe-2022.3.1-Patch-3安装注意事项

准备工作&#xff1a; android studio下载地址&#xff1a;https://developer.android.google.cn/studio/releases?hlzh-cn gradle下载地址&#xff1a;https://services.gradle.org/distributions/ 比较稳定的网络环境&#xff08;比较android studio相关的依赖需要从谷歌那边…

PlantUML语法(全)及使用教程-类图

目录 1. 类图1.1、什么是类图1.2、元素声明1.3、类之间的关系1.4、关系上的标签1.5、在元素名称和关系标签中使用非字母1.6、添加方法 1. 类图 类图的设计语法与编程语言的传统语法相似。这种相似性为开发人员提供了一个熟悉的环境&#xff0c;从而使创建图表的过程更简单、更直…

智慧公厕为城市智慧管理提供强力有的数据支持

在当今科技飞速发展的时代&#xff0c;城市管理正面临着前所未有的挑战与机遇。而在这个城市发展的脚步日新月异的同时&#xff0c;一项看似不起眼的技术却正在默默地为城市的智慧管理提供着强有力的支持——那就是智慧公厕。这些不起眼的公共设施不仅仅是人们日常生活的一部分…

PHP+ajax+layui实现双重列表的动态绑定

需求&#xff1a;商户下面有若干个门店&#xff0c;每个门店都需要绑定上收款账户 方案一&#xff1a;每个门店下面添加页面&#xff0c;可以选择账户去绑定。&#xff08;难度&#xff1a;简单&#xff09; 方案二&#xff1a;从商户进入&#xff0c;可以自由选择门店&#…

【网络奇缘】- 计算机网络|分层结构|深入学习ISO模型

&#x1f308;个人主页: Aileen_0v0&#x1f525;系列专栏: 一见倾心,再见倾城 --- 计算机网络~&#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 回顾链接&#xff1a;http://t.csdnimg.cn/nRRzR 这篇文章是关于深入学习OSI模型七层结构&#xff0c; “书山…

高项备考葵花宝典-项目范围管理输入、输出、工具和技术

项目范围管理包括确保项目“做”且“只做”所需的全部工作&#xff08;即不能少做&#xff0c;也不能多做&#xff0c;如果多做&#xff0c;就要消耗团队额外的时间和资源&#xff0c;并且无法被认可&#xff09;&#xff0c;以成功完成项目。项目范围管理主要在于定义和控制哪…

vue3跟vue2的区别?

​&#x1f308;个人主页&#xff1a;前端青山 &#x1f525;系列专栏&#xff1a;Vue篇 &#x1f516;人终将被年少不可得之物困其一生 依旧青山,本期给大家带来vue篇专栏内容:vue3和vue2的区别 目录 一、Vue3介绍 哪些变化 速度更快 体积更小 更易维护 compositon Api …

SparkSQL远程调试(IDEA)

启动Intellij IDEA&#xff0c;打开spark源码项目&#xff0c;配置远程调试 Run->Edit Configuration 启动远程spark-sql spark-sql --verbose --driver-java-options "-Xdebug -Xrunjdwp:transportdt_socket,servery,suspendy,address5005"运行远程调试&#xf…

详解—[C++ 数据结构]—AVL树

目录 一.AVL树的概念 二、AVL树节点的定义 三、AVL树的插入 3.1插入方法 四、AVL树的旋转 1. 新节点插入较高左子树的左侧---左左&#xff1a;右单旋 2. 新节点插入较高右子树的右侧---右右&#xff1a;左单旋 3.新节点插入较高左子树的右侧---左右&#xff1a;先左单旋…