YoungTalk STM32——外部中断
程序员文章站
2024-02-24 10:24:28
...
中断基本概念
按键中断
如何使用外部中断:在程序上开启相应的外部中断同时开启嵌套向量中断控制器,确保各外部中断可以进入控制器,一旦产生中断,中断信号被送入NVIC,NVIC将整理好顺序的中断任务发送给ARM内核,RAM再进行处理。
键盘中断程序实例分析
中断初始化程序
#include "NVIC.h"
u8 INT_MARK;//中断标志位
void KEYPAD4x4_INT_INIT (void){ //按键中断初始化
NVIC_InitTypeDef NVIC_InitStruct; //定义结构体变量
EXTI_InitTypeDef EXTI_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //启动GPIO时钟 (需要与复用时钟一同启动)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE);//配置端口中断需要启用复用时钟
//第1个中断
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4); //定义 GPIO 中断
EXTI_InitStruct.EXTI_Line=EXTI_Line4; //定义中断线
EXTI_InitStruct.EXTI_LineCmd=ENABLE; //中断使能
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt; //中断模式为 中断
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling; //下降沿触发
EXTI_Init(& EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel=EXTI4_IRQn; //中断线
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; //使能中断
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2; //抢占优先级 2
NVIC_InitStruct.NVIC_IRQChannelSubPriority=2; //子优先级 2
NVIC_Init(& NVIC_InitStruct);
注意的是:需要启用GPIO时钟与复用时钟才能使用GPIO外部中断。
另外,在设置剩余3个中断时,需要设置的通道为5~9时,NVIC中断线应设置为NVIC_InitStruct.NVIC_IRQChannel=EXTI9_5_IRQn;
因为通道5到9为相同的处理函数。
中断服务程序
void EXTI4_IRQHandler(void){
if(EXTI_GetITStatus(EXTI_Line4)!=RESET){//判断某个线上的中断是否发生
INT_MARK=1;//标志位置1,表示有按键中断
EXTI_ClearITPendingBit(EXTI_Line4); //清除 LINE 上的中断标志位
}
}
void EXTI9_5_IRQHandler(void){
if(EXTI_GetITStatus(EXTI_Line5)!=RESET){//判断某个线上的中断是否发生
INT_MARK=2;//标志位置1,表示有按键中断
EXTI_ClearITPendingBit(EXTI_Line5); //清除 LINE 上的中断标志位
}
if(EXTI_GetITStatus(EXTI_Line6)!=RESET){//判断某个线上的中断是否发生
INT_MARK=3;//标志位置1,表示有按键中断
EXTI_ClearITPendingBit(EXTI_Line6); //清除 LINE 上的中断标志位
}
if(EXTI_GetITStatus(EXTI_Line7)!=RESET){//判断某个线上的中断是否发生
INT_MARK=4;//标志位置1,表示有按键中断
EXTI_ClearITPendingBit(EXTI_Line7); //清除 LINE 上的中断标志位
}
}
GPIO外部中断在主程序中的调用
int main (void){//主程序
u8 s;
delay_ms(500); //上电时等待其他器件就绪
RCC_Configuration(); //系统时钟初始化
RELAY_Init();//继电器初始化
I2C_Configuration();//I2C初始化
OLED0561_Init(); //OLED初始化
OLED_DISPLAY_8x16_BUFFER(0," YoungTalk "); //显示字符串
OLED_DISPLAY_8x16_BUFFER(3," KEYPAD4x4 TEST "); //显示字符串
INT_MARK=0;//标志位清0
NVIC_Configuration();//设置中断优先级
KEYPAD4x4_Init();//阵列键盘初始化
KEYPAD4x4_INT_INIT();//阵列键盘的中断初始化
while(1){
//其他程序内容
if(INT_MARK){ //中断标志位为1表示有按键中断
INT_MARK=0;//标志位清0
s=KEYPAD4x4_Read();//读出按键值
if(s!=0){ //如按键值不是0,也就是说有按键操作,则判断为真
OLED_DISPLAY_8x16_BUFFER(6," KEY NO. "); //显示字符串
OLED_DISPLAY_8x16(6,8*8,s/10+0x30);//
OLED_DISPLAY_8x16(6,9*8,s%10+0x30);//
}
}
}
}