基于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 headervoid 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;						//定时器2NVIC_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.mzph.cn/news/181843.shtml

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

相关文章

Java高级技术(注解)

一,注解 二,案例 三,注解原理 四,元注解 五,案例 六,解析注解 七,案例

unity UI特效遮罩

using System.Collections; using System.Collections.Generic; using UnityEngine;/**UI特效遮罩 1.需要将ScrollRect 的遮罩Mask 换为 2D Mask2.将特效的Render里面的 Masking 设置为*/ public class UIParticleMaskControll : MonoBehaviour {// Start is called before …

低代码平台:房企建造领域数字化转型的必备利器

在数字化浪潮的推动下,越来越多的行业开始向数字化转型迈进,房地产建筑管理也不例外。低代码平台作为一种新兴的技术趋势,正逐渐成为推进房地产建筑管理数字化转型的重要工具。 房地产建筑管理作为一个庞大而复杂的行业,数字化转…

『Confetti 喜庆散花插件の使用』

以下用 VUE3 语法 举例使用&#xff1a; npm install js-confetti<script setup lang"ts"> import JSConfetti from js-confetticonst confetti new JSConfetti()function showConfetti() {confetti.addConfetti() } </script><template><h1 …

视频剪辑技巧:批量剪辑新思路,AI智剪来助阵

在视频制作过程中&#xff0c;剪辑是一项至关重要的任务。然而&#xff0c;对于许多创作者来说&#xff0c;批量剪辑视频是一项耗时且繁琐的工作。传统的批量剪辑方法通常要创作者逐个打开视频文件&#xff0c;进行剪辑、调整色彩等操作。这种方法不仅效率低下&#xff0c;而且…

探索低代码之路——JNPF

目录 一、低代码行业现状 二、产品分析 1.可视化应用开发 2.流程管理 3.整个平台源码合作 三、架构和技术 技术栈 四、规划和展望 低代码平台&#xff08;Low-code Development Platform&#xff09;是一种让开发者通过拖拽和配置&#xff0c;而非传统的手动编写大量代…

Linux 启动过程

linux启动步骤&#xff1a; <1>加电 <2>加载bios设置 <3>加载grup <4>加载内核系统到内存中 <5>加载配置文件 <6>加载内核模块 <7>完成相应的初始化工作和启动相应的服务 <8>启动系统进程 <9>出现登录界面 &l…

Python 装饰器与偏函数

目录 装饰器 概念 简单的装饰器 复杂点的装饰器 通用装饰器 定义通用装饰器 使用装饰器 偏函数 引入类库 应用 总结 装饰器 概念 装饰器就是个闭包&#xff1b;把一个函数当做参数&#xff0c;返回一个修改过功能的函数&#xff1b; 本质上是一个返回函数的函数。…

基于Java SSM框架+Vue实现垃圾分类网站系统项目【项目源码+论文说明】

基于java的SSM框架Vue实现垃圾分类网站系统演示 摘要 本论文主要论述了如何使用JAVA语言开发一个垃圾分类网站 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述…

2023年国内主流的低代码平台

低代码开发平台&#xff08;Low-Code Development Platform, LCDS&#xff09;为企业和开发者提供了高效的应用开发方式。这些平台使得开发者可以通过简化的设计界面快速创建和部署应用&#xff0c;大大提高了开发效率并降低了开发成本。 伴随数字化转型推进&#xff0c;选购低…

C++中用于动态内存的new和delete操作符

文章目录 1、动态分配内存的应用2、动态分配内存与分配给普通变量的内存有什么不同?3、C 中如何分配/释放内存4、new 操作符4.1 使用new的语法4.2 初始化内存4.3 分配内存块4.4 普通数组声明 Vs 使用new4.5 如果运行时没有足够内存可用怎么办&#xff1f; 5、delete 操作符 C/…

使用Perplexity AI免费白嫖GPT4的使用次数((智能搜索工具)

一、Perplexity AI是什么 Perplexity AI是一款高质量的智能搜索工具&#xff0c;它可以为用户提供简洁清晰的搜索体验。Perplexity AI内置了基于GPT-4的Copilot搜索功能&#xff0c;用户可以在每四个小时使用五次(白嫖GPT-4)。此外&#xff0c;Perplexity AI有免费和付费&#…

C++——取地址和自增运算

今天做了道题一下给我整蒙了&#xff0c;把实验探索发篇文章&#xff0c;题目如下&#xff1a; int a[]{10,11,12},*p&a[0];执行完*p;*p1;后a[0],a[1],a[2]的值各为多少 答案是 10, 12, 12怎么理解*p,*p1呢&#xff0c;我觉得可以用汉语把代码读一下&#xff0c;p&#xf…

【寒武纪(6)】MLU推理加速引擎MagicMind,最佳实践(三)使用框架模型ONNX

支持情况 Pytorch 只支持 1.6.0 导出。 如何生成ONNX&#xff1f; 解析失败 包括&#xff1a;Parse 过程转换失败node index&#xff0c;不支持的模型输入tensor name&#xff0c;不支持的控制流子图输入tensor name。 提取支持的子图

ArkTs变量类型、数据类型

可以参考官网学习路径学习HarmonyOS第一课|应用开发视频教程学习|HarmonyOS应用开发官网 一、变量 1、ArkTS语言 ArkTS是华为自研的开发语言。它在TypeScript&#xff08;简称TS&#xff09;的基础上&#xff0c;匹配ArkUI框架&#xff0c;扩展了声明式UI、状态管理等相应的…

【Android Jetpack】Room数据库

文章目录 引入EntitiesPrimary Key主键索引和唯一性对象之间的关系外键获取关联的Entity对象嵌套对象Data Access Objects&#xff08;DAOs&#xff09;使用Query注解的方法简单的查询带参数查询返回列的子集可被观察的查询 数据库迁移用法 引入 原始的SQLite有以下两个缺点: …

LCD屏接口与模式详解:干货超多

前言 随着时代的发展&#xff0c;现如今我们生活上已经随处可见的各种电子产品了&#xff0c;诸如手机、平板、电脑、一些其它智能单品上都有用到显示屏&#xff0c;它作为人机交互的重要桥梁之一&#xff0c;我认为它是生活中必不可少的存在&#xff0c;如果少了它&#xff0c…

【Electron】上下键切换消息

需求&#xff1a; 如图&#xff0c;需要监听上下键切换消息 Electron 注册 全局快捷键【globalShortcut】监听 在focus注册 在blur 注销 如苹果系统在使用某个软件(focus)时 右上角会有应用标题 Electron 代码&#xff1a; win.on(focus, ()>{globalShortcut.register(U…

啊哒-MISC-bugku-解题步骤

——CTF解题专栏—— 题目信息&#xff1a; 题目&#xff1a;啊哒 作者&#xff1a;第七届山东省大学生网络安全技能大赛 提示&#xff1a;无 解题附件&#xff1a; 解题思路&#xff1a; 图片的话还是老三样斧winwalk、010Editor、Stegsolve。ok直接开搞&#xff01; 解题…

基于UDP的TFTP文件传输

代码&#xff1a; #include <myhead.h>//实现下载功能 int download(int cfd,struct sockaddr_in sin) {char buf[516] ""; //定义资源包char fileName[128] ""; //定义文件名printf("请输入文件名:");scanf("%s",fileName…