STM32F103标准库开发----目录
STM32F103标准库开发----外部中断(EXTI)实验----程序源码
本文章技术信息均出自:STM32F103系列超详细参考手册-中文版
一、外部中断(EXTI)—简介
EXTI (External interrupt/event controller)——外部中断/事件控制器。
互联型STM32有20个能够产生事件/中断请求的边沿检测器,STM32F103系列有19个能够产生事件/中断请求的边沿检测器。
每个输入线可以独立地配置输入类型(脉冲或挂起)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。
每个输入线都可以独立地被屏蔽。挂起寄存器保持着状态线的中断请求。
二、外部中断(EXTI)—框图
三、外部中断(EXTI)—线路映像
通用I/O端口以下图的方式连接到16个外部中断/事件线上:
四、外部中断(EXTI)—寄存器
从外部中断(EXTI)结构框图可以知道,外部中断功能由六个寄存器配置。
1. 中断屏蔽寄存器(EXTI_IMR)
2. 事件屏蔽寄存器(EXTI_EMR)
3. 上升沿触发选择寄存器(EXTI_RTSR)
4. 下降沿触发选择寄存器(EXTI_FTSR)
5. 软件中断事件寄存器(EXTI_SWIER)
6. 挂起寄存器(EXTI_PR)
五、外部中断(EXTI)—配置
1. 外部中断(EXTI)—映射关系
2. 外部中断(EXTI)—GPIO引脚配置
由上图可知,外部中断的GPIO引脚可以配置一下三种:
GPIO_Mode_IN_FLOATING//浮空输入GPIO_Mode_IPU//上拉输入GPIO_Mode_IPD//下拉输入
3. 外部中断(EXTI)—触发方式
外部中断(EXTI)有三种触发方式:
EXTI_Trigger_Rising//上升沿触发EXTI_Trigger_Falling //下降沿触发EXTI_Trigger_Rising_Falling//上升沿和下降沿都可以触发
六、外部中断(EXTI)—程序
外部中断配置程序
void EXTIX_Init(void){EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;//初始化时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//外部中断,需要使能AFIO时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);//使能PORTA,PORTB,PORTC时钟//初始化GPIO端口GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_4;//PA0,PA4GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //PA0设置成浮空输入,默认下拉GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //最高输出速率50MHzGPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOAGPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_8;//PB6,PB8GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入,默认下拉GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //最高输出速率50MHzGPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOBGPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_14;//PC12,PC14GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //设置成下拉输入,默认下拉GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //最高输出速率50MHzGPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC/*GPIOA0中断初始化配置*/ EXTI_ClearITPendingBit(EXTI_Line0);//清除线0 IO口中断清除挂起位(清除中断标志位)EXTI_InitStructure.EXTI_Line=EXTI_Line0;//中断线选择EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//EXTI为中断模式EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//上升沿触发EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能中断EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);//将GPIOA0挂到中断上/*GPIOA4中断初始化配置*/ EXTI_ClearITPendingBit(EXTI_Line4);//清除线4 IO口中断清除挂起位(清除中断标志位)EXTI_InitStructure.EXTI_Line=EXTI_Line4;//中断线选择EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//EXTI为中断模式EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能中断EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource4);//将GPIOA4挂到中断上/*GPIOB6中断初始化配置*/ EXTI_ClearITPendingBit(EXTI_Line6);//清除线6 IO口中断清除挂起位(清除中断标志位)EXTI_InitStructure.EXTI_Line=EXTI_Line6;//中断线选择EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//EXTI为中断模式EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;//上升沿和下降沿都可以触发EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能中断EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource6);//将GPIOB6挂到中断上/*GPIOB8中断初始化配置*/ EXTI_ClearITPendingBit(EXTI_Line8);//清除线8 IO口中断清除挂起位(清除中断标志位)EXTI_InitStructure.EXTI_Line=EXTI_Line8;//中断线选择EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//EXTI为中断模式EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能中断EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource8);//将GPIOB8挂到中断上/*GPIOC12中断初始化配置*/ EXTI_ClearITPendingBit(EXTI_Line12);//清除线12 IO口中断清除挂起位(清除中断标志位)EXTI_InitStructure.EXTI_Line=EXTI_Line12;//中断线选择EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//EXTI为中断模式EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//上升沿触发EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能中断EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource12);//将GPIOC12挂到中断上/*GPIOC14中断初始化配置*/ EXTI_ClearITPendingBit(EXTI_Line14);//清除线14 IO口中断清除挂起位(清除中断标志位)EXTI_InitStructure.EXTI_Line=EXTI_Line14;//中断线选择EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//EXTI为中断模式EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;//上升沿和下降沿都可以触发EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能中断EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource14);//将GPIOC14挂到中断上/*NVIC初始化配置*/NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //配置NVIC优先级分组为0NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//使能线0所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道NVIC_Init(&NVIC_InitStructure); //初始化外设NVIC寄存器NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;//使能线4所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//子优先级2NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道NVIC_Init(&NVIC_InitStructure); //初始化外设NVIC寄存器NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;//使能线9到线5所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级0, NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//子优先级1NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;//使能线15到线10所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//子优先级0NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道NVIC_Init(&NVIC_InitStructure); }
外部中断服务函数
//外部中断0服务函数 void EXTI0_IRQHandler(void){if(EXTI_GetITStatus(EXTI_Line0)!= RESET)//有中断申请{/**其他功能程序**/EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中断标志位 }}//外部中断4服务函数 void EXTI4_IRQHandler(void){if(EXTI_GetITStatus(EXTI_Line4)!= RESET)//有中断申请{/**其他功能程序**/EXTI_ClearITPendingBit(EXTI_Line4); //清除LINE4上的中断标志位 }}//外部中断9_5服务函数 void EXTI9_5_IRQHandler(void){if(EXTI_GetITStatus(EXTI_Line6)!= RESET)//有中断申请{/**其他功能程序**/EXTI_ClearITPendingBit(EXTI_Line6); //清除LINE6上的中断标志位 }if(EXTI_GetITStatus(EXTI_Line8)!= RESET)//有中断申请{/**其他功能程序**/EXTI_ClearITPendingBit(EXTI_Line8); //清除LINE8上的中断标志位 }}//外部中断15_10服务函数 void EXTI15_10_IRQHandler(void){if(EXTI_GetITStatus(EXTI_Line12)!= RESET)//有中断申请{/**其他功能程序**/EXTI_ClearITPendingBit(EXTI_Line12); //清除LINE12上的中断标志位 }if(EXTI_GetITStatus(EXTI_Line14)!= RESET)//有中断申请{/**其他功能程序**/EXTI_ClearITPendingBit(EXTI_Line14); //清除LINE14上的中断标志位 }}