定时器定时中断定时器外部中断

基础背景:TIM定时中断-CSDN博客

TIM的函数

// 恢复缺省设置
void TIM_DeInit(TIM_TypeDef* TIMx);
// 时基单元初始化,第一个参数TIMx选择某个定时器,第二个参数是结构体,包含了配置时基单元的一些参数。
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);// 把结构体变量赋一个默认值
void TIM_TimeBaseStructInit(TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
// 使能计数器的,第一个参数是选择定时器TIMx,第二个是NewState,新的状态,使能还是失能。
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
// 使能中断输出信号,第一个TIMx,第二个TIM_IT,选择要配置哪个中断输出,第三个新的状态,使能还是失能。
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);// 下面六个函数对应的是时基单元的时钟选择部分。
// 选择内部时钟,参数只有TIMx。
void TIM_InternalClockConfig(TIM_TypeDef* TIMx);
// 选择ITRx其他定时器的时钟,第一个参数是TIMx,选择要配置的定时器,第二个参数是选择要接入哪个其他的定时器。
void TIM_ITRxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_InputTriggerSource);
// 选择TIMx捕获通道的时钟,第一个参数是TIMx,第二个参数选择TIx具体的某个引脚,后面两个参数是输入的极性和滤波器。
void TIM_TIxExternalClockConfig(TIM_TypeDef* TIMx, uint16_t TIM_TIxExternalCLKSource, uint16_t TIM_ICPolarity, uint16_t ICFilter);
// 选择ETR通过外部时钟模式1输入的时钟,参数ExtTRGPrescaler,外部触发预分频器,可以对TER的外部时钟再提前做一个分频。
void TIM_ETRClockMode1Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
// 选择ETR通过外部时钟模式2输入的时钟。
void TIM_ETRClockMode2Config(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);
// 用来单独配置ETR引脚的预分频器、极性、滤波器这些参数的。
void TIM_ETRConfig(TIM_TypeDef* TIMx, uint16_t TIM_ExtTRGPrescaler, uint16_t TIM_ExtTRGPolarity, uint16_t ExtTRGFilter);// 单独写预分频值的函数,Prescaler写的预分频值,TIM_PSCReloadMode写入的模式。
void TIM_PrescalerConfig(TIM_TypeDef* TIMx, uint16_t Prescaler, uint16_t 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);// 获取标志位和清除标志位的
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);

定时器定时中断

线路图

代码

在每次复位时,发现值都是从1开始的,我们发现在TIM_TimeBaseInit()函数内部,最后会生成一个更新事件,来重装装载预分频器和重复计数器的值。

因为预分频器是有个缓冲寄存器的,写入的值只有在更新事件时才会真正起作用,所以为了让值立刻起作用,就在这最后,手动生成了一个更新事件。

但是由于更新事件和更新中断是同时发生的,更新中断会置更新中断标志位,当我们之后一旦初始化完了,更新中断就会立刻进入。

解决的方法:在TIM_TimeBaseInit()函数的后面,手动调用一下TIM_ClearFlag()函数。

Timer代码

#include "stm32f10x.h"                  // Device headervoid Timer_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);// 使用内部时钟TIM_InternalClockConfig(TIM2);// 初始化时基单元TIM_TimeBaseInitTypeDef TIM_TIMeBaseInitStructure;TIM_TIMeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TIMeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TIMeBaseInitStructure.TIM_Period = 10000 - 1;TIM_TIMeBaseInitStructure.TIM_Prescaler = 720 - 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);
}//void TIM2_IRQHandler(void)
//{
//	if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
//	{
//		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
//	}
//}

main代码

#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){Num++;TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}

定时器外部时钟

接线图

代码

Timer代码

#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);// 用于配置定时器的外部时钟模式2// TIM_ExtTRGPSC_OFF 表示关闭预分频器,即不对外部时钟进行预分频。// TIM_ExtTRGPolarity_NonInverted: 这个参数用于配置外部触发信号的极性。// 0x00 表示不使用滤波器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;TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);TIM_ClearFlag(TIM2, TIM_FLAG_Update);//配置TIM2定时器的中断,第二个参数表示定时器更新中断TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);// 配置NVIC的中断优先级分组NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitTypeDef NVIC_InitStructure;// 设置中断通道为TIM2NVIC_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);
//	}
//}

main代码

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

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

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

相关文章

【时间盒子】-【9.任务设置项】自定义任务名称、任务时长等设置项组件

Tips: Stage、Link装饰器的使用; 参考我的帖子:https://developer.huawei.com/consumer/cn/forum/topic/0208152234389094513?fid0101587866109860105 一、预览 红色框:任务设置项列表,把它定义为一个组件对象SettingList。绿…

linux基础 超级笔记

1.Linux系统的组成 Linux系统内核:提供系统最核心的功能,如软硬件和资源调度。 系统及应用程序:文件、任务管理器。 2.Linux发行版 通过修改内核代码自行集成系统程序,即封装。比如Ubuntu和centos这种。不过基础命令是完全相…

【C++ Primer Plus】4

2 字符串 字符串是存储在内存的连续字节中的一系列字符;C处理字符串的方式有两种, c-风格字符串(C-Style string)string 类 2.1 c-风格字符串(C-Style string) 2.1.1 char数组存储字符串(c-…

『网络游戏』自适应制作登录UI【01】

首先创建项目 修改场景名字为SceneLogin 创建一个Plane面板 - 将摄像机照射Plane 新建游戏启动场景GameRoot 新建空节点重命名为GameRoot 在子级下创建Canvas 拖拽EventSystem至子级 在Canvas子级下创建空节点重命名为LoginWnd - 即登录窗口 创建公告按钮 创建字体文本 创建输入…

Java:数据结构-初始结合框架 时间复杂度和空间复杂度 初识泛型

一 初始结合框架 1.什么是Java的集合框架 Java 的集合框架(Java Collection Framework,JCF)是 Java 标准库中的一部分,用于存储和操作一组数据。它提供了一些常用的数据结构和接口,用来高效管理和操作数据。Java 的…

TOP-K问题

目录 TOP-K问题 1.对TOP-K问题的理解 1.1.TOP-K问题定义 1.2.TOP-K问题的解决思路 1.3.以求N个数据中的前K个最大元素为例,阐述建堆来解决TOP-K的原理 1.4.TOP-K问题的类型 2.类型1:数据量N较小,可以全部加载到内存中。求数据量N的前K…

2024 ciscn WP

一、MISC 1.火锅链观光打卡 打开后连接自己的钱包,然后点击开始游戏,答题八次后点击获取NFT,得到有flag的图片 没什么多说的,知识问答题 兑换 NFT Flag{y0u_ar3_hotpot_K1ng} 2.Power Trajectory Diagram 方法1: 使用p…

集合论基础 - 离散数学系列(一)

目录 1. 集合的基本概念 什么是集合? 集合的表示方法 常见的特殊集合 2. 子集与幂集 子集 幂集 3. 集合的运算 交集、并集与补集 集合运算规则 4. 笛卡尔积 5. 实际应用 6. 例题与练习 例题1 练习题 总结 引言 集合论是离散数学的基础之一&#xff…

Linux 外设驱动 应用 1 IO口输出

从这里开始外设驱动介绍,这里使用的IMX8的芯片作为驱动介绍 开发流程: 修改设备树,配置 GPIO1_IO07 为 GPIO 输出。使用 sysfs 接口或编写驱动程序控制 GPIO 引脚。编译并测试。 这里假设设备树,已经配置好了。不在论述这个问题…

金融教育宣传月 | 平安养老险百色中心支公司开展金融知识“消保县域行”宣传活动

9月22日,平安养老险百色中心支公司积极落实国家金融监督管理总局关于开展金融教育宣传月活动的相关要求,联合平安人寿百色中心支公司共同组成了平安志愿者小队,走进百色市四塘镇百兰村开展了一场别开生面的金融消费者权益保护宣传活动。此次活…

通用mybatis-plus查询封装(QueryGenerator)

结果如下图所示 java类代码分别如下 1 package com.hdx.contractor.util.mybatis;import com.hdx.contractor.common.user.SecurityUser; import com.hdx.contractor.common.user.UserDetail; import com.hdx.contractor.util.query.oConvertUtils; import lombok.extern.slf…

YOLO11改进|卷积篇|引入线性可变形卷积LDConv

目录 一、【LDConv】卷积1.1【LDConv】卷积介绍1.2【LDConv】核心代码 二、添加【LDConv】卷积2.1STEP12.2STEP22.3STEP32.4STEP4 三、yaml文件与运行3.1yaml文件3.2运行成功截图 一、【LDConv】卷积 1.1【LDConv】卷积介绍 下图是【LDCNV】的结构图,让我们简单分析…

Ajax面试题:(第一天)

目录 1.说一下网络模型 2.在浏览器地址栏键入URL,按下回车之后会经历以下流程: 3.什么是三次握手和四次挥手? 4.http协议和https协议的区别 1.说一下网络模型 注:各层含义按自己理解即可 2.在浏览器地址栏键入URL,…

盲拍合约:让竞拍更公平与神秘的创新解决方案

目录 前言 一、盲拍合约是什么? 二、盲拍合约工作原理 1、合约创建与初始化 2、用户出价(Bid) 3、出价结束 4、披露出价(Reveal) 5、处理最高出价 6、结束拍卖 7、退款与提款 三、解析盲拍合约代码…

阿里云域名解析和备案

文章目录 1、域名解析2、新手引导3、ICP备案 1、域名解析 2、新手引导 3、ICP备案

类的特殊成员函数——三之法则、五之法则、零之法则

系统中的动态资源、文件句柄(socket描述符、文件描述符)是有限的,在类中若涉及对此类资源的操作,但是未做到妥善的管理,常会造成资源泄露问题,严重的可能造成资源不可用,如申请内存失败、文件句…

【redis-05】redis保证和mysql数据一致性

redis系列整体栏目 内容链接地址【一】redis基本数据类型和使用场景https://zhenghuisheng.blog.csdn.net/article/details/142406325【二】redis的持久化机制和原理https://zhenghuisheng.blog.csdn.net/article/details/142441756【三】redis缓存穿透、缓存击穿、缓存雪崩htt…

57.对称二叉树

迭代 class Solution {public boolean isSymmetric(TreeNode root) {if(rootnull){return true;}Deque<TreeNode> denew LinkedList<>();TreeNode l,r;int le;de.offer(root.left);de.offer(root.right);while(!de.isEmpty()){lde.pollFirst();rde.pollLast();if(…

BMC pam认证的使用

1.说明 1.1 文档参考资料 https://www.chiark.greenend.org.uk/doc/libpam-doc/html/Linux-PAM_ADG.htmlhttp://www.fifi.org/doc/libpam-doc/html/pam_appl-3.htmlpdf文档: https://fossies.org/linux/Linux-PAM-docs/doc/adg/Linux-PAM_ADG.pdflinux-pam 中文文档pam 旧文p…

<数据集>工程机械识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;2644张 标注数量(xml文件个数)&#xff1a;2644 标注数量(txt文件个数)&#xff1a;2644 标注类别数&#xff1a;3 标注类别名称&#xff1a;[dump truck, wheel loader, excavators] 序号类别名称图片数框数1dum…