【STM32】外部中断实验代码详解
文章目錄
- main.c
- exit.c
- exit.h
STM32 的每個 IO 都可以作為外部 中斷的中斷輸入口,這點也是 STM32 的強大之處。
STM32F103 的 19 個外部中斷為:
庫函數中,配置 GPIO 與中斷線的映射關系通過以下函數來實現:void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
該函數將 GPIO 端口與中斷線映射起來,使用范例為:GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource2);
將中斷線 2 與 GPIOE 映射起來,那么很顯然是 GPIOE.2 與 EXTI2 中斷線連接了。
中斷線上中斷的初始化是通過以下函數實現的:void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
給一個例子,設置中斷線 4 上的中斷為下降沿觸發:
結構體 EXTI_InitTypeDef 的成員變量有:
我們配置好中斷線和 GPIO 映射關系,然后又設置好了中斷的觸發模式等初始化參數。既然是外部中斷,涉及到中斷我們當然還要設置 NVIC 中斷優先級。
接著上面的范例,我們設置中斷線 2 的中斷優先級。
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn; //使能按鍵外部中斷通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //搶占優先級 2, NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子優先級 2 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中斷通道 NVIC_Init(&NVIC_InitStructure); //中斷優先級分組初始化配置完中斷優先級之后,接著要做的就是編寫中斷服務函數 EXTIx_IRQHandler。
在編寫中斷服務函數的時候會經常使用到兩個函數,第一個函數是判斷某個中斷線上的中斷是否發生(標志位是否置位):ITStatus EXTI_GetITStatus(uint32_t EXTI_Line); 這個函數一半是用在中斷服務函數的開頭判斷中斷是否發生。
另一個函數是清除某個中斷線上的中斷標志位:void EXTI_ClearITPendingBit(uint32_t EXTI_Line); 這個函數一般應用在中斷服務函數結束之前,清除中斷標志位。
我們再總結一下 使用 IO 口外部中斷的一般步驟:
main.c
#include "led.h" #include "delay.h" #include "sys.h" #include "key.h" #include "usart.h" #include "exti.h" int main(void){ delay_init(); //延時函數初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 設置中斷優先級分組2uart_init(9600); //串口初始化為9600LED_Init(); //初始化與LED連接的硬件接口 EXTIX_Init(); //外部中斷初始化LED0=0; //點亮LEDwhile(1){ printf("OK\n"); delay_ms(1000); } }exit.c
#include "led.h" #include "key.h" #include "delay.h" #include "usart.h"//外部中斷初始化函數 void EXTIX_Init(void) {EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //外部中斷,需要使能AFIO時鐘KEY_Init();//初始化按鍵對應io模式//GPIOC.5 中斷線以及中斷初始化配置GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);EXTI_InitStructure.EXTI_Line = EXTI_Line5;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿觸發EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure); //根據EXTI_InitStruct中指定的參數初始化外設EXTI寄存器//GPIOA.15 中斷線以及中斷初始化配置GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15);EXTI_InitStructure.EXTI_Line = EXTI_Line15;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure); //根據EXTI_InitStruct中指定的參數初始化外設EXTI寄存器//GPIOA.0 中斷線以及中斷初始化配置GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);EXTI_InitStructure.EXTI_Line = EXTI_Line0;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure); //根據EXTI_InitStruct中指定的參數初始化外設EXTI寄存器NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //使能按鍵所在的外部中斷通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //搶占優先級2 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子優先級1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中斷通道NVIC_Init(&NVIC_InitStructure); //根據NVIC_InitStruct中指定的參數初始化外設NVIC寄存器NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //使能按鍵所在的外部中斷通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //搶占優先級2, NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; //子優先級1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中斷通道NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //使能按鍵所在的外部中斷通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //搶占優先級2, NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; //子優先級1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中斷通道NVIC_Init(&NVIC_InitStructure); }void EXTI0_IRQHandler(void) {delay_ms(10); //消抖if(WK_UP==1){ LED0=!LED0;LED1=!LED1; }EXTI_ClearITPendingBit(EXTI_Line0); //清除EXTI0線路掛起位 }void EXTI9_5_IRQHandler(void) { delay_ms(10); //消抖 if(KEY0==0) {LED0=!LED0;}EXTI_ClearITPendingBit(EXTI_Line5); //清除LINE5上的中斷標志位 }void EXTI15_10_IRQHandler(void) {delay_ms(10); //消抖 if(KEY1==0) {LED1=!LED1;}EXTI_ClearITPendingBit(EXTI_Line15); //清除LINE15線路掛起位 }exit.h
#ifndef __EXTI_H #define __EXIT_H #include "sys.h"void EXTIX_Init(void);//IO初始化#endif 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的【STM32】外部中断实验代码详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【STM32】typedef 类型及配合
- 下一篇: 【STM32】窗口看门狗 WWDG 实验