STM32单片机(六)TIM定时器 -> 第二节:TIM定时中断练习(定时器定时中断和定时器外部时钟)

news2024/11/29 2:45:16

❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。
☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋。
🌙专栏目标:实现从零基础入门51单片机和STM32单片机,力求在玩好单片机的同时,能够了解一些计算机的基本概念,了解电路及其元器件的基本理论等。

⭐️ 专栏主要内容: 主要学习STM32单片机的功能、各个模块、单片机的外设、驱动等,最终玩好单片机和单片机的外设,全程手敲代码,实现我们所要实现的功能。
🌴 专栏说明 :如果文章知识点有错误的地方,欢迎大家随时在文章下面评论,我会第一时间改正。让我们一起学习,一起进步。
💑专栏主页:http://t.csdn.cn/HCD8v

本学习过程参考:https://space.bilibili.com/383400717

STM3单片机安装软件、各种资料以及源码的路径:
链接:https://pan.baidu.com/s/1snD0uuTfMhchFqOMWvAiHA?pwd=asdf#list/path=%2F
提取码:asdf

链接里压缩包的解压密码:32

本大节主要学习TIM定时器的相关知识,包含八小节:
第一小节主要学习定时器基本定时的功能,第二小节是对第一小节的内容写两个程序进行练习,分别是定时器定时中断和定时器外部时钟;
第三小节主要学习定时器输出比较的功能,第四小节是对第三小节的内容写三个程序进行练习,分别是PWM驱动LED呼吸灯、PWM驱动舵机以及PWM驱动直流电机;
第五小节主要学习定时器输入捕获的功能,第六小节是对第五小节的内容写两个程序进行练习,分别是输入捕获模式测频率和PWMI模式测频率占空比;
第七小节主要学习定时器的编码器接口功能,第八小节是对第七小节的内容写一个程序进行练习,即编码器接口测速;
最终附上所有的源代码;

本小节是对第一小节TIM定时中断的内容写两个程序进行练习,分别是定时器定时中断和定时器外部时钟;并附上源码;

文章目录

  • 一、本节目标
    • 目标1:定时器定时中断
    • 目标2:定时器外部时钟
  • 二、示例1:定时器定时中断
    • 2.1 接线图
    • 2.2 程序源码
  • 三、示例2:定时器外部时钟
    • 3.1 接线图
    • 3.2 程序源码

一、本节目标

目标1:定时器定时中断

定时器使用内部时钟定了一个1秒的时间,每隔1秒申请一下中断,然后在中断函数里执行Num++;最后在OLED上显示NUm;

现象是OLED上显示一个数字Num,并且每秒钟自动加1;如下图所示:

在这里插入图片描述

目标2:定时器外部时钟

使用外部时钟来驱动定时器,在定时器指定的外部引脚上,输入一个方波信号,来提供定时器计数的时钟,在此示例中,暂时用对射式红外传感器来手动模拟一个外部时钟;用挡光片依次遮挡、移开、遮挡、移开,提供一个方波,

现象如下所示:
可以看到OLED上显示的CNT就是定时器中计数器的值,每遮挡、移开一次,计数器加1;计数器计到9后自动清零;同时申请中断,执行Num++;如下图所示:

在这里插入图片描述

二、示例1:定时器定时中断

2.1 接线图

请添加图片描述

此接线图和之前的OLED显示屏的接线图是一样的,因为定时器和中断系统的电路都在STM32内部,定时中断也是位我们程序设计提供服务的,所以芯片外面只插一个OLED显示数据就行了;

硬件电路接线图如下所示:

在这里插入图片描述

2.2 程序源码

代码路径:

  • STM32入门教程资料\程序源码\STM32Project\6-1 定时器定时中断\User
  • STM32入门教程资料\程序源码\STM32Project\6-1 定时器定时中断\Hardware

具体代码

#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);
	}
}

void TIM2_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)//检查中断标志位,检查TIM_IT_Update是否更新
	{
		Num ++;
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

Time.c

#include "stm32f10x.h"                  // Device header

void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//开启TIM2的时钟函数
	
	TIM_InternalClockConfig(TIM2);//TIM2的时基单元由内部时钟控制
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//1分频模式
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//计数器模式选择为向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;//周期,ARR自动重装器的值,
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;//PSC预分频器的值,
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 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优先级分组
	
	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);//NVIC初始化
	
	TIM_Cmd(TIM2, ENABLE);//启动定时器TIM2
}

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

代码解释:

代码基本就是按照下图一步步实现:
在这里插入图片描述

  • TIM_TimeBaseInit()函数:配置初始化时基单元,第一个参数是选择具体的定时器,第二个参数是配置时基单元的一些参数
  • RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//开启TIM2的时钟函数
  • TIM_InternalClockConfig(TIM2);//TIM2的时基单元由内部时钟控制
  • 代码详细解释看注释

三、示例2:定时器外部时钟

3.1 接线图

在这里插入图片描述

3.2 程序源码

代码路径:

  • STM32入门教程资料\程序源码\STM32Project\6-2 定时器外部时钟\User
  • STM32入门教程资料\程序源码\STM32Project\6-2 定时器外部时钟\Hardware

具体代码:

#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);
	}
}

key.c

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

void Key_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

uint8_t Key_GetNum(void)
{
	uint8_t KeyNum = 0;
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0)
	{
		Delay_ms(20);
		while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0);
		Delay_ms(20);
		KeyNum = 1;
	}
	if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0)
	{
		Delay_ms(20);
		while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0);
		Delay_ms(20);
		KeyNum = 2;
	}
	
	return KeyNum;
}

Timer.c

#include "stm32f10x.h"                  // Device header

void Timer_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启GPIOA  APB2的外设时钟
	
	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, 0x0F);//选择外部时钟模式2
	
	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_FLAG_Update);
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	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);
}

uint16_t Timer_GetCounter(void)
{
	return TIM_GetCounter(TIM2);
}

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

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

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

相关文章

vivado:引脚已约束但是报错

一、问题引入 报错信息如下: [DRC UCIO-1] Unconstrained Logical Port: 3 out of 3 logical ports have no user assigned specific location constraint (LOC). This may cause I/O contention or incompatibility with the board power or connectivity affect…

msvc编译qt源码(qt6之前版本)

配置环境 根据源码里的readme(D:\Qt\Qt5.9.9\5.9.9\Src\readme)安装对应的依赖环境,如果是整个源码编译必须都安装 Qt for Windows - Requirements | Qt 5.15 Qt for Windows - Building from Source | Qt 5.15 Qt WebEngine Platform Not…

day02--java基础编程:变量,数据类型,类型转换,运算规则,运算符,分支结构,循环(随机数),方法,重载,可变参数,递归,数组,冒泡排序

1 Day02–变量数据类型类型转换 1.1 前言 1.1.1 标识符 可以简单的理解为一个名字。在Java中,我们需要标识代码的很多元素,包括包名、类名、方法、字段、变量等。我们选择的名称就称为标识符,并且遵循以下规则: A.标识符可以由…

docker-compose部署单点apm链路追踪

一.docker-compose 安装下载 1、登入 GitHub ,找到对应版本 curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-uname -s-uname -m -o /usr/local/bin/docker-compose2、将下载后的文件放到 /usr/local/bin 目录下,并…

客服部2023年中总结|用心服务,稳步提升用户体验

一、人工智能相辅相成:提升服务效能 2023年上半年,CSDN人工客服处理客诉总量为26859条,同比去年客诉量38695,下降30.59%;问题解决效率为72min,同比下降19%。 客诉量TOP5: 付费专栏质量问题退费博文审核未…

一文吃透低代码平台的衍生历程、优势及未来趋势

一、低代码概念 低代码开发平台是一种无需编码或者只需要少量代码即可快速生成应用程序的开发平台,通过可视化进行应用程序开发的方法,让不同经验水平的开发人员可以通过图形化的用户界面,使用拖拽组件和模型驱动的逻辑来创建网页和移动应用程…

Unity3D:场景可见性

推荐:将 NSDT场景编辑器 加入你的3D工具链 3D工具集: NSDT简石数字孪生 场景可见性 Unity 的场景可见性控件可用于在 Scene 视图中快速隐藏和显示游戏对象,而无需更改它们在游戏中的可见性。 这可用于处理难以查看和选择特定游戏对象的大型或…

Pytorch中的数据操作和预处理

Pytorch中的数据操作和预处理 整体概述 在Pytorch中的torch.util.data模块包含着一些常用的数据预处理的操作,主要用于数据的读取、切分、准备等 常用的数据操作类如下表所示 类功能torch.utils.data.TensorDataset()将数据处理为张量torch.utils.data. ConcatDat…

sqli-labs靶场通关(11-20)

接着上一条博客 Less-11 打开题我们发现界面发生了明显的变化,变成了登录界面。前十关的注入点都在上方的url中(get型),从11关开始就变为了post型,本题的注入点就在输入框中。 我们随便输入比如1,会出现以下界面,上方…

外贸企业必备的客户服务系统!

客户服务已经成为现在市场中,各个企业关注的重点对象。特别是对于外贸企业来讲,优质的客户服务不仅能为客户留下好的印象,提升企业的品牌形象,还能为企业带来长期的收益。而想要做好客户服务,选择一款合适的客户服务系…

验证码就用它,一键接入,优雅又有趣

现在登录什么账号,基本都用到验证码,多数是短信验证码,不知道大家是什么感受,了不起倒不太喜欢这种操作,每次一登录一个账号就要去手机清理一下短信,不然小红点看着难受。不过近两年行为验证码异军突起&…

估计一个点云的表面法线

包含相关头文件 #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/features/normal_3d.h> #include <pcl/visualization/pcl_visualizer.h> 定义了两个类型别名 PointT 和 PointNT&#xff0c;用于表示输入点云和输出点云中各…

Splashtop 在2023年 IT Europa 渠道奖评选活动中当选“特别推荐供应商”

2023年5月24日 加利福尼亚州库比蒂诺 Splashtop 最近在 IT Europa 渠道奖评选活动中&#xff0c;因与 Beyond Digital Solutions 合作的创新客户应用程序而当选年度垂直应用解决方案类别的“特别推荐供应商”。 Beyond Digital Solutions 是一家综合广告公司&#xff0c;主要…

SpringBoot + K8S 中的滚动发布、优雅停机、弹性伸缩、应用监控、配置分离

来源&#xff1a;blog.csdn.net/qq_14999375/article/details/123309636 前言 配置 健康检查 滚动更新 弹性伸缩 Prometheus集成 配置分离 汇总配置 业务层面 运维层面 前言 K8s SpringBoot实现零宕机发布&#xff1a;健康检查滚动更新优雅停机弹性伸缩Prometheus监控…

基于java jsp+mybatis+Spring+的SSM二手交易网站设计实现

基于java jspmybatisSpring的SSM二手交易网站设计实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源码联系方式 …

如何做好软件开发项目管理?

软件越来越多地出现在我们的生活中。为了快速向大众提供这些产品&#xff0c;软件公司必须知道如何有效管理他们的软件项目。 本文将讨论软件项目管理的重要性&#xff0c;以及投资软件项目管理平台的一些好处。 什么是软件开发的项目管理&#xff1f; 软件项目是创建完整的…

车辆管理系统为企业带来4大作用,原来拥有该系统也如此简单

什么是车辆管理系统 车辆管理系统&#xff08;Vehicle Management System&#xff09;是一种用于管理车辆、驾驶员和交通管理的系统。它可以便捷地管理车辆信息&#xff0c;包括车辆的基本信息、行驶记录、保养维修记录、司机信息以及车辆运营成本等。车辆管理系统可以为车队管…

开源赋能 工业铸魂|2023开放原子全球开源峰会开源工业软件分论坛圆满举行

6 月 12 日&#xff0c;由开放原子开源基金会主办&#xff0c;开源工业软件工作委员会&#xff08;以下简称“工委会”&#xff09;承办&#xff0c;工业和信息化部电子第五研究所、哈尔滨工程大学青岛创新发展基地协办的 2023 开放原子全球开源峰会开源工业软件分论坛在京举行…

Linux: 关于blocked for more than 600 seconds的解决方法

背景 在Centos 7的系统日志 /var/log/message中出现大量的 “blocked for more than 600 seconds”和“echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.” 的错误。 如下图所示&#xff1a; 问题原因 默认情况下&#xff0c; Linux最多会使…

这所211非常保护一志愿,录取最低分263分,多个专业上线即录取!

一、学校及专业介绍 云南大学&#xff08;Yunnan University&#xff09;&#xff0c;简称云大&#xff08;YNU&#xff09;&#xff0c;位于云南省昆明市&#xff0c;是教育部与云南省“以部为主、部省合建”的全国重点大学&#xff0c;国家“双一流”建设高校&#xff0c;云南…