STM32学习--6-1 定时器定时中断

news2024/10/27 23:30:20

定时器电路图

 第一步:RCC开启时钟,基本上每个代码都是第一步

第二步:选择时基单元的时钟源(内部时钟)

第三步:配置时基单元,包括预分频器、自动重装器、计数模式等,通过结构体配置

第四步:配置中断输出控制,允许更新中断输出到NVIC

第五步:配置NVIC,在NVIC中打开定时器中断的通道,并分配一个优先级

第六步:运行控制,整个模块配置完成后,还需要使能一下计数器,当定时器使能后,计数器就会开始计数了,当计数器更新时,触发中断,

最后再写一个中断函数,这样这个中断函数每隔一段时间就能自动执行一次了。

定时器库函数

  • void TIM_DeInit(TIM_TypeDef* TIMx);    // 恢复缺省配置 
  • void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);   // 时基单元初始化 TIMx 选择哪个定时器 对应2
  • void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct); //时基单元结构体初始化 对应2
  • void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);// 使能计时器,运行控制时开启  TIMx 选择哪个定时器 ;NewState:ENABLE 对应6
  • void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState); //使能中断输出控制  TIMx 选择哪个定时器;TIM_IT:选择配置哪个中断输出;NewState:ENABLE  对应4
  • 以下五个时钟源选择对应图中标志1
  • void TIM_InternalClockConfig(TIM_TypeDef* TIMx);
  • void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
  • void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource,uint16_t TIM_ICPolarity, uint16_t ICFilter);
  • void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity,uint16_t ExtTRGFilter);
  • void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler,uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);

  • void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t TIM_PSCReloadMode);  // 预分频设置  Prescaler 0代表1分频,1代表2分频即加1,TIM_PSCReloadMode 代表立即执行还是下个周期执行
  • void TIM_CounterModeConfig(TIM_TypeDef* TIMx, uint16_t TIM_CounterMode); // 选择计数模式是上升还是下降
  • void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState); // 自动预装功能  有无预装器
  • void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter); // 手动给一个计数值
  • void TIM_SetAutoreload(TIM_TypeDef* TIMx, uint16_t Autoreload); // 给自动重装器写入一个值
  • uint16_t TIM_GetCounter(TIM_TypeDef* TIMx); // 查看当前计数器记到哪里了
  • uint16_t TIM_GetPrescaler(TIM_TypeDef* TIMx);// 获取预分频器的值

// 获取标志位,清除标志位,前两个是CPU运行时获取,后两个为中断获取

  • FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
  • void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
  • ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
  • void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);

Time.c

#include "stm32f10x.h"                  // Device header

extern uint16_t Num;  // 告诉编译器已经定义过Num,自己去找  是main.c 中Num的引入

void Timer_Init(void)
{
	// 初始化定时器
	// 1.开启时钟  TIM2 为 APB1 外设
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	// 2.TIM2的时基单元由内部时钟来驱动了 ,不写也可以,默认上电使用内部时钟
	TIM_InternalClockConfig(TIM2);
	// 3.配置时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; // 配置进入时分频器
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; // 配置向上计数
	TIM_TimeBaseInitStruct.TIM_Period = 10000 - 1;  // ARR 的周期(都在65535以内)
	TIM_TimeBaseInitStruct.TIM_Prescaler = 7200 - 1; // 预分频的值 PSC
	// CK_CNT_OV = CK_CNT / (ARR + 1) = CK_PSC / (PSC + 1) / (ARR + 1)
	// 1Hz = 72M / 10000 / 7200
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter = 0; // 重复计数的值,此时用不着,设0
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
	// 避免刚初始化完就进中断的问题   void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG)
	TIM_ClearFlag(TIM2,TIM_FLAG_Update);
	// 4.配置使能中断 TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);  // TIM_IT_Update: TIM update Interrupt source
	// 5.NVIC配置 
	// 5.1 优先级分组 NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	// 5.2 NVIC初始化 void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn; // 中断通道
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; // 中断通道使能
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; // 设置抢占优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; // 设置响应优先级
	NVIC_Init(&NVIC_InitStruct);
	// 6 启动定时器 TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)
	TIM_Cmd(TIM2, ENABLE);	
}

// TIM2中断函数  在Start -》 startup_stm32f10x_md_vl.s中 107 行
void TIM2_IRQHandler(void)
{
	// 检查标志位  ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT)  更新中断位
	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		Num++;
		// 清除标志位 防止不断进中断,使系统崩溃 void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT)
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
	}
}

Timer.h 

#ifndef __TIMER_H
#define __TIMER_H

void Timer_Init(void);

#endif

 main.c

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

uint16_t Num;  // 定义全局变量在中断中加1

int main(void)
{	
	OLED_Init();
	Timer_Init();
	OLED_ShowString(1,3,"Num:");  // 字符串用双引号括起来
	
	while(1)
	{
		OLED_ShowNum(1,7,Num,5);
		OLED_ShowNum(2,5,TIM_GetCounter(TIM2),5); // 获取计数器数值 
		// 由于设置的是 9999 故数值在0 - 9999 之间累加
	}
}

 

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

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

相关文章

Dockerfile(Jenkins)

1.创建⼀个jenkins的Dockerfile mkdir tomcat cd tomcat 2、上传需要的安装包 apache-tomcat-8.5.47.tar.gz jdk-8u211-linux-x64.tar.gz jenkins.war 3、编写Dockerfile vim Dockerfile # This my first jenkins Dockerfile # Version 1.0 FROM centos:7 MAINTAINER l…

Echarts+vue3+高德渲染地图

Echartsvue3高德渲染地图 一&#xff1a;安装 npm install echarts二&#xff1a;渲染地图 1. html <template><div class"content"><div ref"myChartsRef" id"map" style"width: 100%;height: 560px;" ></d…

JAVA自动化测试TestNG框架

1.TestNG简介 JAVA自动化测试最重要的基石。官网&#xff1a;https://testng.org 使用注解来管理我们的测试用例。 发现测试用例 执行测试用例 判断测试用例 生成测试报告 2.创建Maven工程 2.1创建一个maven工程 2.2设置maven信息 2.3设置JDK信息 2.4引入testng依赖 <dep…

Linux下Docker方式Jenkins安装和配置

一、下载&安装 Jenkins官方Docker仓库地址&#xff1a;https://hub.docker.com/r/jenkins/jenkins 从官网上可以看到&#xff0c;当前最新的稳定版本是 jenkins/jenkins:lts-jdk17。建议下在新的&#xff0c;后面依赖下不来 所以&#xff0c;我们这里&#xff0c;执行doc…

达梦数据库性能优化

1、SQL执行计划 拿到一条SQL的时候&#xff0c;首先要下达梦手册中提出的有效SQL规范&#xff0c;及是否命中了特殊OR子句的不规范&#xff0c;是否用了复杂的正则表达式&#xff0c;避免重复很高的索引&#xff0c;UINON ALL 是否可以替换UNION操作等,某些场景INSTR函数导致的…

FunASR离线文件转写服务开发指南-debian-10.13

FunASR离线文件转写服务开发指南-debian-10.13 服务器环境 debian10.13 64位 第一步 配置静态网卡 auto eth0 iface eth0 inet static address 192.168.1.100 netmask 255.255.255.0 gateway 192.168.1.1 dns-nameservers 8.8.8.8 8.8.4.4/etc/init.d/networking restart第…

C++面试速通宝典——25

473. HTTP如何减少重定向请求 重定向请求&#xff1a; ‌‌‌‌  服务器上的一个资源可能由于迁移、维护等原因从url1移至url2后&#xff0c;而客户端不知情&#xff0c;他还是继续请求url1&#xff0c;这时服务器不能粗暴地返回错误&#xff0c;而是通过302响应码和Locati…

甲方安全和乙方安全的区别

信息安全工作&#xff0c;总会被人分成甲方和乙方&#xff0c;甲乙方原本只是商务层面需方和供方的代称&#xff0c;在安全领域&#xff0c;成了做公司内部安全和为客户提供安全的区别。 通常意义上&#xff0c;什么是甲方安全人员呢&#xff1f;就是在非安全业务的公司从事信…

ROS2 通信三大件之动作 -- Action

通信最后一个&#xff0c;也是不太容易理解的方式action&#xff0c;复杂且重要 1、创建action数据结构 创建工作空间和模块就不多说了 在模块 src/action_moudle/action/Counter.action 下创建文件 Counter.action int32 target # Goal: 目标 --- int32 current_value…

[Python学习日记-45] Python 中模块的介绍与导入

[Python学习日记-45] Python 中模块的介绍与导入 简介 模块的概念与好处 模块的分类 模块导入和调用 自定义模块 模块的查找路径 简介 在前面的学习当中偶尔我们会看到 import ... 一个什么东西的&#xff0c;或者 from ... import ...&#xff0c;那时候并没有进行介绍&…

react+ts+vite 别名一直爆红问题

已经配置如下代码安装了types/node import path from "path"; // https://vitejs.dev/config/ export default defineConfig({plugins: [react()],server: {proxy: {"/api": {target: "http://localhost:3000",changeOrigin: true,rewrite: (pa…

如何选择安全的谷歌浏览器插件

在数字时代&#xff0c;浏览器插件为我们提供了极大的便利&#xff0c;增强了我们的浏览体验。然而&#xff0c;随着便利性的增加&#xff0c;安全性问题也日益凸显。选择安全的谷歌浏览器插件是保障个人信息安全的重要步骤。以下是详细的教程&#xff0c;帮助你选择和使用安全…

81 NAT-静态NAT

一 NAT 出口方向实验 1 配置接口的IP地址 2 配置nat 静态映射 3 测试 无法ping 通 202.38.1.100 4 接口上开启静态Nat映射规则 [FW-Router-BJ-GigabitEthernet0/1]nat static enable 6 5 查看配置 [FW-Router-BJ]display nat static 6 测试 7 查看NAT 会话状态 8 静态…

Qt自定义一个圆角对话框

如何得到一个圆角对话框&#xff1f; 步骤&#xff1a; 1、继承自QDiaglog 2、去掉系统自带的边框 3、设置背景透明,不设置4个角会有多余的部分出现颜色 4、对话框内部添加1个QWidget&#xff0c;给这个widget设置圆角&#xff0c;并添加到布局中让他充满对话框 5、后续对…

Redis协议详解及其异步应用

目录 一、Redis Pipeline&#xff08;管道&#xff09;概述优点使用场景工作原理Pipeline 的基本操作步骤C 示例&#xff08;使用 [hiredis](https://github.com/redis/hiredis) 库&#xff09; 二、Redis 事务概述事务的前提事务特征&#xff08;ACID 分析&#xff09;WATCH 命…

【HarmonyOS】HMRouter使用详解(二)路由跳转

路由跳转 HMRouter中使用HMRouterMgr的静态方法push()和replace()来实现路由跳转。使用pop()方法来实现页面返回 push &#xff1a;目标页面不会替换当前页&#xff0c;而是插入页面栈。可以使用pop实现页面的返回操作。replace&#xff1a;目标页面会替换当前页&#xff0c;并…

西门子828d的plc一些信息记录

1、虽然是200的plc但是引入了DB的形式替代原来的V存储区。 2、用户自定义DB块范围&#xff0c;DB9000-DB9063,共64个DB块。 可用地址范围如上图 机床MCP483面板地址表&#xff0c;其它类型的面板地址自己在828d简明调试手册里查看。 如何上载828d的plc程序&#xff1a; 1.通…

web-105linux权限提升

rsync未授权本地覆盖 Rsync 是 linux 下一款数据备份工具&#xff0c;默认开启 873 端口 https://vulhub.org/#/environments/rsync/common/ 借助 Linux 默认计划任务调用/etc/cron.hourly&#xff0c;利用 rsync 连接覆盖 前提条件就是需要知道rsync的密码或者存在未授权 -提…

【成品设计】基于Arduino平台的物联网智能灯

《基于Arduino平台的物联网智能灯》 整体功能&#xff1a; 这个任务中要求实现一个物联网智能灯。实际测试环境中要求设备能够自己创建一个热点&#xff0c;连接这个热点后能自动弹出控制界面&#xff08;强制门户&#xff09;。 功能点 基础功能 (60分) 要求作品至少有2个灯…

发布-订阅模式(Publisher-Subscriber)

实际上&#xff0c;发布-订阅模式只是观察者模式的一个别称。 但是经过时间的沉淀&#xff0c;似乎他已经强大了起来&#xff0c;已经独立于观察者模式&#xff0c;成为另外一种不同的设计模式。在现在的发布订阅模式中&#xff0c;称为发布者的消息发送者不会将消息直接发送给…