STM32学习和实践笔记(21):定时器中断实验

通用定时器配置步骤如下:

第一步:使能定时器时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//使能TIM4时钟

第二步:初始化定时器参数,包含自动重装值,分频系数,计数方式等

voidTIM_TimeBaseInit(TIM_TypeDef*TIMx,TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);

typedef struct

{

  uint16_t TIM_Prescaler;         //定时器预分频器

  uint16_t TIM_CounterMode;       //计数模式

  uint32_t TIM_Period;            //定时器周期

  uint16_t TIM_ClockDivision;     //时钟分频

  uint8_t TIM_RepetitionCounter;  //重复计数器

} TIM_TimeBaseInitTypeDef;

了解结构体成员功能后,就可以进行配置,例如

  TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;

  TIM_TimeBaseInitStructure.TIM_Period=1000;   //自动装载值

  TIM_TimeBaseInitStructure.TIM_Prescaler=35999; //分频系数

  TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;

  TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数模式

  TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);

  定时器定时时间计算公式如下:

Tout= ((per)*(psc+1))/Tclk;

公式中对应的各参数在框图上的位置如下所示:


 

per(Period)就是自动重装里需要装入的数值

PSC就是分频系数。

ClockDivision是指输入滤波通道后面的那个预分频器,是对输入信号进行分频的,一般设为1

TCLK是外设总结时钟的两倍,也就是36M*2=72MHZ

自动重装计数器装入初值,然后以CK_CNT的频率从0开始计数,当计到大于初值时,就产生事件或者溢出中断。

Tout= ((per)*(psc+1))/Tclk

=((1000)*(35999+1))/72MHZ =500ms

反过来,根据已知的需要定时多长时间,也可以算出需要装入的初值是多少。

第三步:设置定时器中断类型,并使能

void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState)

第四步:设置定时器中断优先级,使能定时器中断通道

NVIC初始化库函数是NVIC_Init()

第五步:开启定时器

void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);

第六步:编写定时器中断服务函数

TIM4_IRQHandler

ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);

if(TIM_GetITStatus(TIM4,TIM_IT_Update))

  {

  ...//执行TIM4更新中断内控制

  }

void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);

固件库中还有两个函数是用来读取状态标志位以及清除中断标志位,函

数分别为TIM_GetFlagStatusTIM_ClearFlag

以上6步,通过下面这个实验来熟悉和验证:

main.c

#include "system.h"
#include "led.h"
#include "SysTick.h"
#include "timer.h"



/*	本实验所要实现的功能是:通过TIM4的更新中断控制D2指示灯间隔
500ms秒状态取反,主函数控制D1指示灯不断闪烁。
程序框架如下:
(1)初始化TIM4,并使能更新中断等
(2)编写TIM4中断函数
(3)编写主函数
*/

int main()
{
	u8 i=0;
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组
	LED_Init();
	TIM4_Init(1000,36000-1); //因为分频系数不能为0,会自动加1,所以这里先减1。这里定时为500ms
	
	
	while(1)
	{
		
		i++;
		if(i%20 ==0)
		{
			led1=!led1;//LED1闪,用来指示主程序循环是否运行
		}
		delay_ms(10);
		
	}
}


timer.c

#include "timer.h"
#include "led.h"

void TIM4_Init(u16 period,u16 prescaler)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//结构体变量声明
	NVIC_InitTypeDef NVIC_InitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//使能TIM4时钟

	TIM_TimeBaseInitStructure.TIM_Period=period;   //装入函数传过来的自动装载值
	TIM_TimeBaseInitStructure.TIM_Prescaler=prescaler; //装入函数传过来的分频系数
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;//1分频(没有分频)
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数模式:从0开始计数到自动重载值后溢出产生中断
	TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);//初始化TIM4各参数:自动重装值、分频系统、计数方式等

	TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);//设置定时器中断类型(溢出更新中断),并使能
	TIM_ClearITPendingBit(TIM4, TIM_IT_Update);//清除之前可能存在的溢出标志
	
	//设置定时器中断优先级,使能定时器中断通道
	NVIC_InitStructure.NVIC_IRQChannel=	TIM4_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
	TIM_Cmd(TIM4, ENABLE);//开启定时器
	
}

void TIM4_IRQHandler(void)//中断服务函数,注意函数内容根据功能自行编写但这个函数名是约定好的
{
	if(TIM_GetITStatus(TIM4, TIM_IT_Update)==1)//判断是否产生溢出中断
	{
		led2=!led2;
	}
	TIM_ClearITPendingBit(TIM4, TIM_IT_Update);//清除溢出标志
}
	




timer.h

#ifndef _timer_H
#define _timer_H

#include "system.h"

void TIM4_Init(u16 period,u16 prescaler);


#endif

烧写到开发板上,实验是成功的。

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

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

相关文章

C++编译器如何实现 const(常量)?

C编译器如何实现 const(常量)? 表面上看,我们在讨论 “编译器怎么保证一个常量不会被程序员强行改变呢?”;其实,我们说的是:如果你表明自己就是要强行修改一个常量,那么…

每日一题:托普利茨矩阵

给你一个 m x n 的矩阵 matrix 。如果这个矩阵是托普利茨矩阵,返回 true ;否则,返回 false 。 如果矩阵上每一条由左上到右下的对角线上的元素都相同,那么这个矩阵是 托普利茨矩阵 。 示例 1: 输入:matrix…

【原创教程】EPLAN如何制作专属的封面

想要给EPLAN制作专属封面吗?没问题,我来给你支个招。在EPLAN设计电气图纸时,封面就是第一印象,得好好弄。咱们以口罩机项目为例,来看看怎么做吧! 首先,得新建个封面。在项目属性里找到表格名称,点那个数值下拉菜单,选择“查找”。在弹出的表格里挑个你喜欢的模版,点击…

【IC设计】边沿检测电路(上升沿、下降沿、双沿,附带源代码和仿真波形)

文章目录 边沿检测电路的概念上升沿检测电路下降沿检测电路双边沿检测电路代码和仿真RTL代码Testbench代码仿真波形 参考资料 边沿检测电路的概念 边沿检测指的是检测一个信号的上升沿或者下降沿,如果发现了信号的上升沿或下降沿,则给出一个信号指示出来…

OurBMC开源大赛高校获奖队伍专访来啦!

精彩纷呈的 OurBMC 开源大赛已告一段落,经历为期四个月的实战,各个参赛队伍也积淀了丰富的实践经验与参赛心得。本期,社区特别邀请 OurBMC 开源大赛获奖高校团队分享「走进OurBMC开源大赛,共同践行开放包容、共创共赢的开源精神」…

【春秋云境】文件上传漏洞合集

CVE-2022-30887 1.题目简介 2.CVE-2022-30887简介 使用工具: 蚁剑 burpsuite 一句话木马 3.渗透测试 输入用户名密码进行抓包 猜测账号密码 无有用信息,根据页面现有信息找到作者邮箱: mayuri.infospacegmail.com,猜测密码为&a…

每日一题:跳跃游戏II

给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j < n 返回到达 nums[n - 1] 的最…

YOLOv3没有比这详细的了吧

YOLOv3&#xff1a;目标检测基于YOLOv2的改进 在目标检测领域&#xff0c;YOLO&#xff08;You Only Look Once&#xff09;系列以其出色的性能和速度而闻名。YOLOv3作为该系列的第三个版本&#xff0c;不仅继承了前身YOLOv2的优势&#xff0c;还在多个方面进行了创新和改进。…

机器学习理论基础—支持向量机的推导(一)

机器学习理论基础—支持向量机的推导 算法原理 SVM:从几何角度&#xff0c;对于线性可分数据集&#xff0c;支持向量机就是找距离正负样本都最远的超平面&#xff0c;相比于感知机&#xff0c;其解是唯一的&#xff0c;且不偏不倚&#xff0c;泛化性能更好。 超平面 n维空间…

如何拿取 macOS 系统中的图标文件

如何拿取 macOS 系统中的图标文件 比如在 Finder 中看到这个文件夹图标很好看&#xff0c;想用一下&#xff0c;就是不知道它在什么位置&#xff0c;我来告诉你。 它在系统中的位置是 /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/如何打开这个位置&am…

计算机网络物理层思维导图+大纲笔记

大纲笔记&#xff1a; 物理层的基本概念 解决如何在连接各种计算机的传输媒体上传输数据比特流&#xff0c;而不是具体的传输媒体 主要任务 确定与传输媒体接口有关的一些特性 机械特性 电气特性 功能特性 规程特性信道上传送的信号 基带信号 来自信源的信号&#xff0c;直接表…

【CLI命令行接口和Java连接openLooKeng查询数据 】

CLI命令行接口和Java连接openLooKeng查询数据 一、摘要二、正文0. 环境说明1. CLI命令行工具的使用2. Java API 的使用三、小结一、摘要 通过CLI命令行接口工具连接openLooKeng,可帮助初学者能够使用SQL语句的方式快速操作openLooKeng,任何只要熟悉SQL的人都可以快速切换到op…

解决 uniapp uni.getLocation 定位经纬度不准问题

【问题描述】 直接使用uni.getLocation获取经纬度不准确&#xff0c;有几百米的偏移。 【解决办法】 加偏移量 //加偏移 let x longitude let y latitude let x_pi (3.14159265358979324 * 3000.0) / 180.0 let z Math.sqrt(x * x y * y) 0.00002 * Math.sin(y * x_pi)…

ArcGIS Pro专题地图系列教程

专题地图系列是ArcGIS Pro3.2的新功能。之前&#xff0c;如果要做8张相同区域的专题图&#xff0c;可能需要新建8个布局&#xff0c;分别进行排版&#xff0c;再导出。现在&#xff0c;一幅地图&#xff0c;一个布局&#xff0c;就可以完成这个流程。 原理是&#xff0c;根据单…

Swift-24-集合对象

概述 在了解正式内容之前可以先回顾下objectiveC中提供的集合特性。 它的特点是&#xff0c;拿NSArray举例&#xff0c;包含NSArray 和 NSMutableArray两个API&#xff0c;前者是不可变数组&#xff0c;一旦创建其值和数量就不能改变了&#xff1b;NSMutableArray是可变数组&…

tableau基础学习——添加标靶图、甘特图、瀑布图

标靶图 添加参考线 添加参考分布 甘特图 创建新的字段 如设置延迟天数****计划交货日期-实际交货日期 为正代表提前交货&#xff0c;负则代表延迟交货 步骤&#xff1a;创建——计算新字段 把延迟天数放在颜色、大小里面就可以 瀑布图 两个表按照地区连接 先做个条形图&…

工业4.0的基石:探索工业级光模块的力量

引言 工业4.0代表着智能制造的新时代&#xff0c;而工业级光模块则是这一革命性转变的基石。这些高科技组件不仅是现代通信网络的核心&#xff0c;更是连接智能工厂、智慧城市和远程服务的关键。本文将深入探讨工业级光模块的技术特性、应用领域以及它们如何塑造未来工业的面貌…

公司网页制作需要多少钱

公司网页制作需要多少钱&#xff1f;这是一个非常常见的问题。答案取决于您需要的功能和设计。一些小型企业网站可能只需要一些基本的功能&#xff0c;花费可能低至几百美元&#xff0c;而一些大型企业网站可能需要高级功能和设计&#xff0c;可能需要几万美元。 以下是一些考虑…

js如何获取对象的属性值

获取对象的属性值&#xff0c;有两种方式。 方式一&#xff1a; 对象.属性名 let obj {name:张三,age:23 }; console.log(obj.name); //张三方式二&#xff1a; 对象[属性名] let obj {name:张三,age:23 }; console.log(obj[name]); //张三 两种方式有什么不同&am…

Mac安装telnet

一、安装Homebrew 1、打开官网&#xff1a;Homebrew — The Missing Package Manager for macOS (or Linux) 2、打开终端输入&#xff1a; /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 二、安装Telnet bre…