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

news2024/12/27 21:27:39

前言


       本篇博客主要学习了解定时器的标准库函数,以及定时器中断进行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);		//获取脉冲计次
}

总结:

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

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

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

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

相关文章

C语言进阶指南(15)(函数指针的创建与使用)

*欢迎来到博主的专栏——C语言进阶指南 博主id 文章目录 函数指针函数指针的应用——回调函数函数指针数组 函数指针 函数也有地址(函数在调用的时候会占用内存空间,所以函数是有地址的),因此我们也可以用一个指针指向函数 1 函数…

OSCP系列靶场-Esay保姆级

总结 getwebshell : ftp可匿名登录 → 发现隐藏文件夹 → 发现ssh密钥 → 猜解ssh用户名 → ssh密钥登录 提 权 思 路 : 发现suid权限文件 → cpulimit提权 准备工作 启动VPN 获取攻击机IP → 192.168.45.191 启动靶机 获取目标机器IP → 192.168.179.130 信息收集-端口扫…

基于SpringBoot实现的教务查询系统

一、系统架构 前端:html | js | css | jquery | bootstrap 后端:springboot | springdata-jpa 环境:jdk1.7 | mysql | maven 二、代码及数据库 三、功能介绍 01. 登录页 02. 管理员端-课程管理 03. 管理员端-学生管理 04. 管理员端-教师管理…

又有两大巨头官宣加入鸿蒙, 鸿蒙已成, 华为余承东说得没错

自从华为发布HarmonyOS 4系统后,宣布下一个鸿蒙版本将不再支持安卓应用,并启动鸿蒙原生应用,随后国内巨头纷纷响应,为鸿蒙系统开发原生应用。 如今,又有两大巨头官宣加入鸿蒙,一家是广汽传祺,M…

智慧工地解决方案,Spring Cloud智慧工地项目平台源码

智慧工地一体化信息管理平台源码,微服务架构JavaSpring Cloud UniApp MySql 智慧工地云平台是专为建筑施工领域所打造的一体化信息管理平台。通过大数据、云计算、人工智能、物联网和移动互联网等高科技技术手段,将施工区域各系统数据汇总,建…

Flutter创建TabBar

使用TabBar和TabBarView来创建一个包含"首页"、"分类"和"我的"的TabBar。每个Tab对应一个Tab控件,TabBarView中的每个页面对应一个Widget。 1.Tab使用自定义图标和颜色 一般UI设计的图会带渐变色之类的,应该保持图片的原…

由于找不到steam_api64.dll如何修复?steam_api64.dll丢失多种解决方法

steam_api64.dll文件介绍 steam_api64.dll是Steam平台的一个关键组件,主要用于支持Steam客户端和相关游戏的应用程序。这个文件缺失或损坏会导致Steam及相关游戏无法正常运行。它位于Steam安装目录的bin子文件夹中。 steam_api64.dll丢失的原因 系统误删&#xf…

品味丰富美食,羊大师温暖心灵

品味丰富美食,羊大师温暖心灵 冬季来临,寒冷的天气让人们渴望寻找一种温暖和满足感,这时候美食便成了一种心灵享受。冬季与美食的结合,使得人们在寒冷的冬日也能感受到温暖与欢乐。本文小编羊大师将带大家领略冬季与美食的完美结…

C库函数—sprintf

函数介绍: C 库函数 int sprintf(char *str, const char *format, ...) 发送格式化输出到 str 所指向的字符串。 参数: str -- 这是指向一个字符数组的指针,该数组存储了 C 字符串。format -- 这是字符串,包含了要被写入到字符串 …

网络入门---网络的大致了解

目录标题 网络发展的简单认识协议作用的理解协议的本质什么是协议分层网络通信所面对的问题OSI七层模型TCP/IP模型协议报头的理解局域网通信局域网通信基本原理报头的问题局域网的特点跨网的网络链接如何查看mac地址 网络发展的简单认识 通过之前的学习我们知道计算机是给人提…

九章正式推出『智能驾驶产业数据库』

为了更好地研究产业变化趋势,在定性分析之外增加更多定量分析的内容,从而帮助自动驾驶产业内的朋友们更快速、更精准地把握市场变化,2022年底,九章决定要做智能驾驶产业数据库。 历时将近一年后,从敲定数据库负责人&am…

【古月居《ros入门21讲》学习笔记】10_话题消息的定义与使用

目录 说明: 1. 话题模型 2. 实现过程(C) 自定义话题消息 Person.msg文件内容 Person.msg文件内容说明 编译配置 在package.xml文件中添加功能包依赖 在CMakeLists.txt中添加编译选项 编译生成语言相关文件 创建发布者代码&#xff…

【Android Jetpack】Hilt 依赖注入框架

文章目录 依赖注入DaggerHiltKoin添加依赖项Hilt常用注解的含义HiltAndroidAppAndroidEntryPointInjectModuleInstallInProvidesEntryPoint Hilt组件生命周期和作用域如何使用 Hilt 进行依赖注入 依赖注入 依赖注入是一种软件设计模式,它允许客户端从外部源获取其依…

高级IO—poll,epoll,reactor

高级IO—poll,epoll,reactor 文章目录 高级IO—poll,epoll,reactorpoll函数poll函数接口poll服务器 epollepoll的系统调用epoll_createepoll_ctlepoll_wait epoll的工作原理epoll的工作方式水平触发边缘触发 epoll服务器 reactor poll函数 poll函数是一个用于多路复用的系统调…

docker-compose Foxmic dt版

Foxmic dt 版前言 实现企业对资产的基本管理,包含对资产的登记、维修、调拨、转移等基本功能的支持,并提供对资产的耗材、库存进行管理,有完善的组织架构,非常适合中小企业的需求系统整体覆盖了基本的资产管理、合同管理、运维服务、运维服务、数据中心设备管理等多个模块。…

白盒测试 接口测试 自动化测试

一、什么是白盒测试 白盒测试是一种测试策略,这种策略允许我们检查程序的内部结构,对程序的逻辑结构进行检查,从中获取测试数据。白盒测试的对象基本是源程序,所以它又称为结构测试或逻辑驱动测试,白盒测试方法一般分为…

JVM执行引擎以及调优

1.JVM内部的优化逻辑 1.1JVM的执行引擎 javac编译器将Person.java源码文件编译成class文件[我们把这里的编译称为前期编译],交给JVM运行,因为JVM只能认识class字节码文件。同时在不同的操作系统上安装对应版本的JDK,里面包含了各自屏蔽操作…

Linux下Docker 离线安装详细步骤,亲测成功

1.离线原因:公司新创不能使用开元linux,使用了一个变种centOS,致使yum被禁 2.步骤: 2.1 下载docker tar包,下载地址:Index of linux/https://download.docker.com/linux/ 2.2 新建自己的软件目录&am…

数字化转型的核心是数据,还是应用?_光点科技

数字化转型是当今世界各行各业的热门话题。它不仅仅是将传统的业务流程、产品和服务数字化,更是一种全面的业务战略转变。在这个转变过程中,数据和应用都扮演着至关重要的角色。但究竟哪一个是数字化转型的核心?这个问题值得深入探讨。 我们来…

【JavaEE初阶】死锁问题

目录 一、死锁的三种典型场景 1、一个线程,一把锁 2、两个线程,两把锁 3、N个线程,M把锁 死锁,是多线程代码中的一类经典问题。我们知道加锁是能解决线程安全问题的,但是如果加锁的方式不当,就可能产生死…