中断(NVIC)的使用--EXTI--TIM

目录

中断是什么

轮询

中断

中断调用情况

中断的分类

内部中断(TIM、UART等)

tim.c

tim.h

外部中断EXTI

exti.c

exti.h


中断是什么

在处理事件的时候有两种方式:轮询和中断。

轮询

顾名思义,就是每轮都询问一次。比如while循环的每一次,就会执行检查,1.此处串口是否有数据到来。2.每次都检测一下引脚状态,是否为低电平。在有大量事件发生时,cpu按照事件到来的先后顺序依次执行,不考虑时间的紧急性和事件大小,也就是不考虑时间的优先级。

中断

中断也是一种对于数据获取的调度方式。通过中断源来提醒CPU,数据已经更新,可以读取新数据。给每个事件设置优先级,在有大量事件发生时,cpu按照事件的优先级率先完成紧急性事件和处理时间短的事件

中断调用情况

CPU对于调度频次不高的任务(函数),或者特别紧急的任务(刹车制动这种) 给出的一种任务执行关系,这种关系的本质就是函数功能一旦出现,就要立即实施。这两种形式的任务一般都以中断形式调度,对于上一种任 务,优势在于提升系统运行速率,后一种提升了系统的实时性。 中断是一种芯片的内部的宝贵资源,数量是十分有限的。

中断的分类

内部资源根据硬件细节不同分出内部中断,和外部中断两种。

内部中断(TIM、UART等)

CPU内部有一个硬件结构叫做NVIC,也叫做中断管理控制器, NVIC管理着很多引脚,当特定事件发生时,会给NVIC发送一个信号,NVIC调用相应的中断函数传给CPU让其执行。

tim.c

#include "stm32f4xx.h"                  // Device header
#include "stdio.h"

//定时器的初始化
void Time_Init()
{
	//时钟使能
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//1
	//参数配置,84M 84 000 000
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;//3
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;//4
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period=(5000-1);//工作量(路程),每一趟执行一次中断
	TIM_TimeBaseInitStruct.TIM_Prescaler=(8400-1);//84M除以8400=10 000,工作速度(10 000/s)
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
	
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);//2
	
	//让定时器开始工作
	
	TIM_Cmd(TIM2,ENABLE);
	
	//定时器开启中断,看到TIM_Period,数到头,给NVIC说一声
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
	
	//中断分组
	//分组方式,2位给抢占优先级,2位给响应优先级
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//从此处判断核心需求数量(2)
	
	//NVIC参数配置
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;
	
	NVIC_Init(&NVIC_InitStruct);
	
}
void TIM2_IRQHandler()
{
	//信号判断,中断进一步确认
	if(TIM_GetITStatus(TIM2,TIM_IT_Update))
	{
		printf("not apple tree!\n");
	}
	//中断信号清除
	TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}

tim.h

#include "stm32f4xx.h"                  // Device header
void Time_Init();

外部中断EXTI

上图紫色线路为轮询机制。黑色线路部分为内部中断。红色线路部分为外部中断NVIC处理的是中断信号,不是电平信号。

为什么GPIO需要接入EXTI产生中断信号,而不直接连到NVIC上?

usart,TIM,IIC这些芯片 内部器件本身就可以产生中断信号,因此就可以直接与NVIC连接。但是,光突突的GPIO本身就是一根电线,肯定不具备产生中断信号的功能。因此连接 EXTI,依靠EXTI产生中断信号。 原因2:中断通达数量比较少,EXTI的多路复选的功能扩充了接口。一个EXTI可 以接16个GPIO引脚呢。

exti.c

#include "stm32f4xx.h"                  // Device header
#include "BitBand.h"
#include "stdio.h"
#include "delay.h"

void exti_key_init()
{
	//时钟配置
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
	
	//给GPIO参数配置
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN;
	GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_3|GPIO_Pin_2;
	GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_UP;
	GPIO_InitStruct.GPIO_Speed=GPIO_High_Speed;
	
	GPIO_Init(GPIOE,&GPIO_InitStruct);
	//把GPIOE组的第2个引脚连接到EXTI2
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource2);
	//把GPIOE组的第3个引脚连接到EXTI3
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource3);
	
	//EXTI参数配置
	//告诉EXTI2、3,看见上升沿,就给NVIC发送中断信号
	EXTI_InitTypeDef EXTI_InitStruct;
	
	EXTI_InitStruct.EXTI_Line=EXTI_Line2|EXTI_Line3;
	EXTI_InitStruct.EXTI_LineCmd=ENABLE;
	EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising;
	
	EXTI_Init(&EXTI_InitStruct);
	
	//分组方式,2位给抢占优先级,2位给响应优先级
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//从此处判断核心需求数量(2)
	
	NVIC_InitTypeDef NVIC_InitStruct;
	NVIC_InitStruct.NVIC_IRQChannel=EXTI2_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;
	
	NVIC_Init(&NVIC_InitStruct);
	
	//分组方式,2位给抢占优先级,2位给响应优先级
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);//从此处判断核心需求数量(2)
	
	NVIC_InitStruct.NVIC_IRQChannel=EXTI3_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;
	
	NVIC_Init(&NVIC_InitStruct);
}

//中断服务子函数,给EXTI2服务
void EXTI2_IRQHandler()
{
	if(EXTI_GetITStatus(EXTI_Line2))
	{
		printf("key2 apple tree\n");
	}
	
	EXTI_ClearITPendingBit(EXTI_Line2);
}

//中断服务子函数,给EXTI3服务
void EXTI3_IRQHandler()
{
	if(EXTI_GetITStatus(EXTI_Line3))
	{
		printf("key3 apple tree\n");
	}
	
	EXTI_ClearITPendingBit(EXTI_Line3);
}
	

exti.h

#include "stm32f4xx.h"                  // Device header

void exti_key_init();

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

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

相关文章

结构体类型详细讲解(附带枚举,联合)

前言: 如果你还对结构体不是很了解,那么本篇文章将会从 为什么存在结构体,结构体的优点,结构体的定义,结构体的使用与结构体的大小依次介绍,同样会附带枚举与联合体 目录 为什么存在结构体: 结构…

毕业设计:日志记录编写(3/17起更新中)

目录 3/171.配置阿里云python加速镜像:2. 安装python3.9版本3. 爬虫技术选择4. 数据抓取和整理5. 难点和挑战 3/241.数据库建表信息2.后续进度安排3. 数据处理和分析 3/17 当前周期目标:构建基本的python环境:运行爬虫程序 1.配置阿里云pytho…

【C++】如何用一个哈希表同时封装出unordered_set与unordered_map

👀樊梓慕:个人主页 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 🌝每一个不曾起舞的日子,都是对生命的辜负 目录 前言 1.哈希桶源码 2.哈希…

(三维重建学习)已有位姿放入colmap和3D Gaussian Splatting训练

这里写目录标题 一、colmap解算数据放入高斯1. 将稀疏重建的文件放入高斯2. 将稠密重建的文件放入高斯 二、vkitti数据放入高斯 一、colmap解算数据放入高斯 运行Colmap.bat文件之后,进行稀疏重建和稠密重建之后可以得到如下文件结构。 1. 将稀疏重建的文件放入高…

windows10 WSL启动Ubuntu虚拟机,安装DolphinScheduler

文章目录 1. 启动WSL与虚拟机2. 安装Docker与DolphinScheduler容器 1. 启动WSL与虚拟机 使用管理员权限运行命令: Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux重启后即可创建虚拟机 在Microsoft Store中搜索Ubuntu&…

Wear-Any-Way——可控虚拟试衣一键试穿,可自定义穿着方式

概述 Wear-Any-Way 是阿里巴巴最新推出的虚拟试衣技术,它不仅可以让用户在虚拟环境中试穿衣服,还可以根据需要自定义衣服的样式,比如卷起袖子、打开或拖动外套等。这种技术的引入旨在帮助消费者更好地了解衣服在不同穿着方式下的效果&#x…

一个python实现的kline-chart图表程序(二)

前面一中简单介绍了kline-chart的图表程序,实际上这个程序最主要的功能不是显示K线,因为显示K线的程序太多了,没必要专门重写,这个程序最主要的功能是根据需要显示包含K线在内的各种指标,自己算的指标,或是…

plSql 大批量数据导入到表中

主要2种思路,一为insert插入sql,二是借助plsql提供的工具 insert语句odbc importer/导入器 insert语句 把要插入的数据转为insert语句,直接复制到plsql的sql窗口,运行即可;或者在命令行窗口回车键,选择要执…

使用 RunwayML 对图像进行 Camera 操作

RunwayML 是一個功能強大的平台,可以讓您使用 AI 和机器学习来增强您的图像和视频。 它提供一系列预训练模型,可用于各种任务,包括图像编辑、风格化和特效。 在本文中,我们将介绍如何使用 RunwayML 对图像进行 Camera 操作。我们…

[AIGC] SQL中的数据添加和操作:数据类型介绍

SQL(结构化查询语言)作为一种强大的数据库查询和操作工具,它能够完成从简单查询到复杂数据操作的各种任务。在这篇文章中,我们主要讨论如何在SQL中添加(插入)数据,以及在数据操作过程中&#xf…

数据结构(五)——树森林

5.4 树和森林 5.4.1 树的存储结构 树的存储1:双亲表示法 用数组顺序存储各结点,每个结点中保存数据元素、指向双亲结点(父结点)的“指针” #define MAX_TREE_SIZE 100// 树的结点 typedef struct{ElemType data;int parent; }PTNode;// 树的类型 type…

学习或复习电路的game推荐:nandgame(NAND与非门游戏)、Turing_Complete(图灵完备)

https://www.nandgame.com/ 免费 https://store.steampowered.com/app/1444480/Turing_Complete/ 收费,70元。据说可以导出 Verilog !

关于安卓调用文件浏览器(一)打开并复制

背景 最近在做一个硬件产品,安卓应用开发。PM抽风,要求从app打开文件浏览器,跳转到指定目录,然后可以实现文件复制粘贴操作。 思考 从应用开发的角度看,从app打开系统文件浏览器并且选择文件,这是很常见…

馆室一体化查档平台制度有哪些

馆室一体化查档平台制度是指图书馆或档案馆在数字化和信息化的背景下,建立起的集查阅、借阅、咨询、文献传递等多项功能于一体的平台制度。下面是一些常见的馆室一体化查档平台制度: 1. 馆藏管理制度:包括图书和档案的采购、编目、分类、整理…

那些王道书里的题目-----计算机网络篇

注:仅记录个人认为有启发的题目 p155 34.下列四个地址块中,与地址块 172.16.166.192/26 不重叠,且与172.16.166.192/26聚合后的地址块不会引入多余地址的是() A.172.16.166.192/27 B.172.16.166.128/26 …

day06vue2学习

day06 路由的封装抽离 问题:所有的路由配置都堆在main.js中不太合适么?不好,会加大代码的复杂度 目标:将路由模块抽离出来。好处:差分模块,利于维护。 大致的做法就是,将路由相关的东西都提…

codeTop102:二叉树的层序遍历

前言 在已知BFS的方式后,知道每次从队列中取一个节点,就要将这个节点的所有子节点按照顺序放入队列。 难点在于怎么确定将同一层的节点放在一个数组里面的输出,也就是输出一个二维数组? 解决方法: 每次while循环将队列上轮放入的…

蓝桥集训之矩形牛棚

蓝桥集训之矩形牛棚 核心思想&#xff1a;单调队列 模板&#xff1a;Acwing.131.直方图矩形面积首先遍历所有下界 然后确定以该下界为底的直方图 求最大矩形 #include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N 30…

Java学习day2

命名规则 在JAVA中&#xff0c;公共类的明朝必须与包含该类的源文件的文件名向匹配&#xff0c;即 这两个名称要一致 变量类型 与c/c基本一致 需要注意的是&#xff0c;long类型的数据在后面需要加上l或L&#xff08;建议加L&#xff0c;l可能会被误判&#xff09;&#xff…

【Redis】优惠券秒杀

全局唯一ID 全局唯一ID生成策略&#xff1a; UUIDRedis自增snowflake算法数据库自增 Redis自增ID策略&#xff1a;每天一个key&#xff0c;方便统计订单量ID构造是 时间戳 计数器 Component public class RedisIdWorker {// 2024的第一时刻private static final long BEGIN…