news 2026/10/23 6:32:40

【STM32标准库】铁头山羊--[EXTI]工作原理(笔记)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【STM32标准库】铁头山羊--[EXTI]工作原理(笔记)

一.EXTI模块简介

EXTI模块也是单片机上的片上外设

GPIO模块和EXTI模块的关系

EXTI检测是电压的变化(上升沿和下降沿),不检测电压的高低

当电压发生变化时会被EXTI模块捕捉——>EXTI模块向外产生中断(中断中有对输入信号的处理函数)

总结:EXTI模块是捕捉输入信号的变化,并产生中断

二.EXTI应用举例

灯的亮灭状态,按钮按下不变,松开按钮才切换。

在过去如何捕捉按钮变化的瞬间:按钮按下时,GPIO引脚上电压由高(板载LED初始为高电压)变低(按钮按下时,GPIO接地,变为低电压)。这种可以通过while循环实现,把按钮上次的值记录在变量previous中,把按钮当前的值记录在变量current中,当两个变量不相同时,按钮状态发生改变。previous=1,current=0时,按钮按下;previous=0,current=1时,按钮松开。

EXTI:捕捉电压变化,产生中断,在中断函数中切换LED的亮灭状态

三.线的概念

在EXTI线x里共有20条,

GPIO引脚可以通过最多16条线产生16种不同的中断信号

四.线的内部

硬件触发需要电压变化

软件触发只需往对应位置写0/1

五.EXTI按钮实验

1.接线图

2.初始化板载LED,初始化按钮

void App_LED_Init(void); void App_Button_Init(void); void App_LED_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); GPIO_InitTypeDef GPIO_LED; GPIO_LED.GPIO_Pin=GPIO_Pin_13; GPIO_LED.GPIO_Mode=GPIO_Mode_Out_OD; GPIO_LED.GPIO_Speed=GPIO_Speed_2MHz; GPIO_Init(GPIOC,&GPIO_LED); GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET); } void App_Button_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_Button; //PA5 GPIO_Button.GPIO_Pin=GPIO_Pin_5; GPIO_Button.GPIO_Mode=GPIO_Mode_IPU; GPIO_Init(GPIOC,&GPIO_Button); //PA6 GPIO_Button.GPIO_Pin=GPIO_Pin_6; GPIO_Button.GPIO_Mode=GPIO_Mode_IPU; GPIO_Init(GPIOC,&GPIO_Button); // 开启AFIO的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // 线5选择端口A GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource5); // 线6选择端口A GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource6); }

3.分配EXTI线

void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, // 端口号 // GPIO_PortSourceGPIOA, GPIO_PortSourceGPIOB // GPIO_PortSourceGPIOC, GPIO_PortSourceGPIOD uint8_t GPIO_PinSource); // 线编号 // GPIO_PinSource0 ~ GPIO_PinSource15
// 开启AFIO的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // 线5选择端口A GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource5); // 线6选择端口A GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource6);

4.配置EXTI线参数

void App_EXIT(void); void App_EXIT(void) { //EXTI_Line5 EXTI_InitTypeDef EXTI_LED; EXTI_LED.EXTI_Line=EXTI_Line_5; EXTI_LED.EXTI_Mode=EXTI_Mode_Interrupt; EXTI_LED.EXTI_Trigger=EXTI_Trigger_Rising; EXTI_LED.EXTI_LineCmd=ENABLE; EXTI_Init(&EXTI_LED); //EXTI_Line6 EXTI_InitTypeDef EXTI_LED; EXTI_LED.EXTI_Line=EXTI_Line_6; EXTI_LED.EXTI_Mode=EXTI_Mode_Interrupt; EXTI_LED.EXTI_Trigger=EXTI_Trigger_Rising; EXTI_LED.EXTI_LineCmd=ENABLE; EXTI_Init(&EXTI_LED); }

5.配置NVIC模块

先中断分组(放在最前面)

int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置中断分组 App_LED_Init(); App_Button_Init(); App_EXIT(); while(1) { } }

再配置中断

查询中断名称

打开头文件--Ctrl+F 打开检索--查找eunm IRQn--在枚举里找到对应中断的名称

//配置中断 NVIC_InitTypeDef NVIC_LED; NVIC_LED.NVIC_IRQChannel=EXTI9_5_IRQn;//中断名称 NVIC_LED.NVIC_IRQChannelPreemptionPriority=0;//中断优先级 NVIC_LED.NVIC_IRQChannelSubPriority=0;//中断子优先级 NVIC_LED.NVIC_IRQChannelCmd=ENABLE;//闭合开关 NVIC_Init(&NVIC_LED);

6.编译中断响应函数

通过判断EXTI线标志位的值判断那条线触发中断

清除标志位:向图红圈位置标志位写0(因为触发后为1)

void EXTI9_5_IRQHandler(void){ if(EXTI_GetFlagStatus(EXTI_Line5) == SET) { // 线5触发的中断 EXTI_ClearFlag(EXTI_Line5); // 清除中断标志位 GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_RESET); // 亮灯 } if(EXTI_GetFlagStatus(EXTI_Line6) == SET) { // 线6触发的中断 EXTI_ClearFlag(EXTI_Line6); // 清除中断标志位 GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET); // 灭灯 } }
#include "stm32f10x.h" void App_LED_Init(void); void App_Button_Init(void); void App_EXIT(void); int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配置中断分组 App_LED_Init(); App_Button_Init(); App_EXIT(); while(1) { } } void App_LED_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); GPIO_InitTypeDef GPIO_LED; GPIO_LED.GPIO_Pin=GPIO_Pin_13; GPIO_LED.GPIO_Mode=GPIO_Mode_Out_OD; GPIO_LED.GPIO_Speed=GPIO_Speed_2MHz; GPIO_Init(GPIOC,&GPIO_LED); GPIO_WriteBit(GPIOC,GPIO_Pin_13,Bit_SET); } void App_Button_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_Button; //PA5 GPIO_Button.GPIO_Pin=GPIO_Pin_5; GPIO_Button.GPIO_Mode=GPIO_Mode_IPU; GPIO_Init(GPIOC,&GPIO_Button); //PA6 GPIO_Button.GPIO_Pin=GPIO_Pin_6; GPIO_Button.GPIO_Mode=GPIO_Mode_IPU; GPIO_Init(GPIOC,&GPIO_Button); // 开启AFIO的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // 线5选择端口A GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource5); // 线6选择端口A GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource6); } void App_EXIT(void) { //EXTI_Line5 EXTI_InitTypeDef EXTI_LED; EXTI_LED.EXTI_Line=EXTI_Line5; EXTI_LED.EXTI_Mode=EXTI_Mode_Interrupt; EXTI_LED.EXTI_Trigger=EXTI_Trigger_Rising; EXTI_LED.EXTI_LineCmd=ENABLE; EXTI_Init(&EXTI_LED); //EXTI_Line6 EXTI_LED.EXTI_Line=EXTI_Line6; EXTI_LED.EXTI_Mode=EXTI_Mode_Interrupt; EXTI_LED.EXTI_Trigger=EXTI_Trigger_Rising; EXTI_LED.EXTI_LineCmd=ENABLE; EXTI_Init(&EXTI_LED); //配置中断 NVIC_InitTypeDef NVIC_LED; NVIC_LED.NVIC_IRQChannel=EXTI9_5_IRQn; NVIC_LED.NVIC_IRQChannelPreemptionPriority=0; NVIC_LED.NVIC_IRQChannelSubPriority=0; NVIC_LED.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_LED); } void EXTI9_5_IRQHandler(void){ if(EXTI_GetFlagStatus(EXTI_Line5) == SET) { // 线5触发的中断 EXTI_ClearFlag(EXTI_Line5); // 清除中断标志位 GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_RESET); // 亮灯 } if(EXTI_GetFlagStatus(EXTI_Line6) == SET) { // 线6触发的中断 EXTI_ClearFlag(EXTI_Line6); // 清除中断标志位 GPIO_WriteBit(GPIOC, GPIO_Pin_13, Bit_SET); // 灭灯 } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/23 6:30:22

K8s上部署Hadoop集群:StatefulSet与持久化存储实践指南

这已经是我服务器搭建系列的第十五篇了。前面咱们把基础容器环境、持久化存储、监控告警和常用中间件都铺了一遍,这次来啃一块硬骨头:在 k8s 上部署一套 Hadoop 集群,而且直接用 2022 年的最新稳定版本。很多朋友学完 k8s 基础之后&#xff0…

作者头像 李华
网站建设 2026/10/23 6:30:08

黑客松强调“短时间验证创意”,BuilderX 2026 黑客松大赛也设置了智能硬件、Agent 智能体赋能等赛道

黑客松强调“短时间验证创意”,BuilderX 2026 黑客松大赛也设置了智能硬件、Agent 智能体赋能等赛道,参赛团队需要在有限时间内完成原型搭建、数据展示和成果汇报。在这种高强度场景下,一份能够自动生成的项目报告,往往比临时拼凑…

作者头像 李华
网站建设 2026/10/23 6:29:53

Linux内核bzImage构建原理与实战:从压缩到可启动镜像

1. 项目概述:从源码到可启动镜像的完整闭环“linux内核压缩制作bzImage”——这八个字背后,不是一条命令就能走完的捷径,而是一整套贯穿编译原理、内存布局、引导协议与硬件交互的底层工程实践。我第一次在某嵌入式实验室调试一块ARM64开发板…

作者头像 李华
网站建设 2026/10/23 6:28:45

如何写 Skill 第7课,子 agent 派工:买的是干净,不是人手

摘要:skill 里的活不必都由主对话自己干:产出大或脏、能自足收工的活可以派给子代理,它带着全新上下文干活,主对话只收结论。派工不是雇人手,是买干净,付 token,买隔离。本文用四问把这笔交易算…

作者头像 李华
网站建设 2026/10/23 6:26:20

PPA1510 功率分析仪:两台一起测怎么协同

Newtons4th 的 PPA1510 是一台功率分析仪。单台测功率没什么特别,但这台设备有个不太常见的能力——它自己就知道怎么跟另一台配合。驱动里的示例把这个用法专门做成了一个例子。为什么需要两台单台功率分析仪能测的通道数是有限的。当被测对象有多个端口——比如三…

作者头像 李华
网站建设 2026/10/23 6:26:19

ADK A2A协议深度剖析:从零搭建分布式智能体

ADK A2A协议深度剖析:从零搭建分布式智能体 【免费下载链接】adk-docs An open-source, code-first toolkit for building, evaluating, and deploying sophisticated AI agents with flexibility and control. 项目地址: https://gitcode.com/GitHub_Trending/ad…

作者头像 李华