| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 嵌入式 -> STM32实现外部中断 -> 正文阅读 |
|
[嵌入式]STM32实现外部中断 |
如何配置外部中断,一共分为五步。 1) 初始化用来产生中断的 GPIO; 2) 配置 NVIC; 3) 初始化 EXTI; 4) 选择 EXTI 的信号源 5) 编写中断服务函数; 下面进行具体操作。
1.打开GPIO对应的时钟。 2.初始化GPIO_InitTypeDef结构体。 3.调用GPIO_Init()函数。 代码如下: ????? RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);?? ????? GPIO_InitTypeDef GPIO_InitStruct; ????? GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0; ????? GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;??? ????? GPIO_Init(GPIOA,&GPIO_InitStruct);
1.配置中断优先级分组 2.初始化 NVIC_InitTypeDef 结构体,设置抢占优先级和子优先级,使能中断请求。NVIC_InitTypeDef 结构体在固件库头文件 misc.h 中定义。 a. NVIC_IROChannel:用来设置中断源,不同的中断中断源不一样,且不可写错,即使写错了程序也不会报错,只会导致不响应中断。具体的成员配置可参考 stm32f10x.h 头文件里面的 IRQn_Type结构体定义,这个结构体包含了所有的中断源。 b. NVIC_IRQChannelPreemptionPriority:抢占优先级,具体的值要根据优先级分组来确定,具体参考表格优先级分组真值表 优先级分组真值表。 c. NVIC_IRQChannelSubPriority:子优先级,具体的值要根据优先级分组来确定,具体参考表格优先级分组真值表 优先级分组真值表。 d. NVIC_IRQChannelCmd:中断使能(ENABLE)或者失能(DISABLE)。操作的是 NVIC_ISER和 NVIC_ICER 这两个寄存器 3.调用NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) 代码如下: static void NVIC_Configuration(void) { ?????? NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);? //中断优先级分组,组1 ?????? //初始化 NVIC_InitTypeDef 结构体 ?????? NVIC_InitTypeDef? NVIC_InitStruct; ?????? NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn; ?????? NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; ?????? NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1; ?????? NVIC_InitStruct.NVIC_IRQChannelSubPriority=1; ?????? NVIC_Init(&NVIC_InitStruct); }
1.打开EXTI对应的时钟。 2.初始化EXTI_InitTypeDef结构体。 1) EXTI_Line:EXTI 中断/事件线选择,可选 EXTI0 至 EXTI19,可参考表 EXTI 中断 _事件线选择。 2) EXTI_Mode:EXTI 模式选择,可选为产生中断 (EXTI_Mode_Interrupt) 或者产生事件(EXTI_Mode_Event)。 3) EXTI_Trigger:EXTI 边沿触发事件,可选上升沿触发 (EXTI_Trigger_Rising)、下降沿触发 (EXTI_Trigger_Falling) 或者上升沿和下降沿都触发 ( EXTI_Trigger_Rising_Falling)。 4) EXTI_LineCmd:控制是否使能 EXTI 线,可选使能 EXTI 线 (ENABLE) 或禁用 (DISABLE)。 3.调用EXTI_Init( )函数。 代码如下: ????? RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); ????? EXTI_InitTypeDef EXTI_InitStruct; ????? EXTI_InitStruct.EXTI_Line=EXTI_Line0; ????? EXTI_InitStruct.EXTI_LineCmd=ENABLE; ????? EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt; ????? EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising;??? ????? EXTI_Init(&EXTI_InitStruct);
GPIO_EXTILineConfig 函数用来指定中断/事件线的输入源,它实际是设定外部中断配置寄存器的AFIO_EXTICRx 值,该函数接收两个参数,第一个参数指定 GPIO 端口源,第二个参数为选择对应 GPIO 引脚源编号。 前四步的总代码为: static void NVIC_Configuration(void) { ????? NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);? //中断优先级分组,组1 ????? //初始化 NVIC_InitTypeDef 结构体 ????? NVIC_InitTypeDef? NVIC_InitStruct; ????? NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn; ????? NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; ????? NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1; ????? NVIC_InitStruct.NVIC_IRQChannelSubPriority=1; ????? NVIC_Init(&NVIC_InitStruct); } void EXTI_Key_Config(void) {??? ????? //1初始化PA0 ????? RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); ????? GPIO_InitTypeDef GPIO_InitStruct; ????? GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0; ????? GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;??? ????? GPIO_Init(GPIOA,&GPIO_InitStruct);????? ????? ????? // 2配置 NVIC; ????? NVIC_Configuration(); ????? ????? // 3初始化 EXTI; ????? RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); ????? EXTI_InitTypeDef EXTI_InitStruct; ????? EXTI_InitStruct.EXTI_Line=EXTI_Line0; ????? EXTI_InitStruct.EXTI_LineCmd=ENABLE; ????? EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt; ????? EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising; ????? EXTI_Init(&EXTI_InitStruct); ????? ????? /* 4选择 EXTI 的信号源 */ ????? GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0); }
在启动文件 startup_stm32f10x_hd.s 中我们预先为每个中断都写了一个中断服务函数,只是这些中断函数都是为空,为的只是初始化中断向量表。实际的中断服务函数都需要我们重新编写,为了方便管理我们把中断服务函数统一写在 stm32f10x_it.c 这个库文件中。 关于中断服务函数的函数名必须跟启动文件里面预先设置的一样,如果写错,系统就在中断向量表中找不到中断服务函数的入口,直接跳转到启动文件里面预先写好的空函数,并且在里面无限循环,实现不了中断。 一般为确保中断确实发生,我们会在中断服务函数中调用中断标志位状态读取函数读取外设中断标志位并判断标志位状态。 EXTI_GetITStatus 函数用来获取 EXTI 的中断标志位状态,如果 EXTI 线有中断发生函数返回“SET”否则返回“RESET”。实际上,EXTI_GetITStatus 函数是通过读取 EXTI_PR 寄存器值来判断 EXTI 线状态的。 void EXTI0_IRQHandler() {??? ????? if(EXTI_GetITStatus(EXTI_Line0)) ????? { ???????????? ????? } ????? EXTI_ClearITPendingBit(EXTI_Line0); //清除中断标志位 } |
|
嵌入式 最新文章 |
基于高精度单片机开发红外测温仪方案 |
89C51单片机与DAC0832 |
基于51单片机宠物自动投料喂食器控制系统仿 |
《痞子衡嵌入式半月刊》 第 68 期 |
多思计组实验实验七 简单模型机实验 |
CSC7720 |
启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
STM32初探 |
STM32 总结 |
【STM32】CubeMX例程四---定时器中断(附工 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 22:37:51- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |