1、Embedded System DevelopmentEmbedded System Development嵌入式系统与应用嵌入式系统与应用 第第9 9章章 STM32STM32外部中断设计外部中断设计F9.1 GPIO9.1 GPIO键盘设计键盘设计F9.2 GPIO9.2 GPIO外部中断外部中断EXTIEXTI设计设计9.1 GPIO 9.1 GPIO 键盘设计键盘设计F每个每个GPIOGPIO引脚都可配置为引脚都可配置为8 8种模种模式。式。FGPIOGPIO端口如何进行键盘设计?端口如何进行键盘设计?F下面两种办法效果一样。下面两种办法效果一样。F一是采用上拉输入模式,按键在一是采用
2、上拉输入模式,按键在没按下的时候,默认为高电平。没按下的时候,默认为高电平。PE5 key1PE5 key1PE6 key2 PE6 key2 F二是直接采用浮空输入模式,在二是直接采用浮空输入模式,在芯片外部接上拉电阻。芯片外部接上拉电阻。按键原理图按键原理图实现LEDLED反转,main()函数int main(void)int main(void)/*config the led config the led*/LED_GPIO_Config();LED_GPIO_Config();LED1(ON);LED1(ON);/*config keyconfig key*/Key_GPIO_Co
3、nfig();Key_GPIO_Config();while(1)while(1)if(Key_Scan(GPIOE,GPIO_Pin_5)=KEY_ON)if(Key_Scan(GPIOE,GPIO_Pin_5)=KEY_ON)/*LED1LED1反转反转*/GPIO_WriteBit(GPIOC,GPIO_Pin_3,GPIO_WriteBit(GPIOC,GPIO_Pin_3,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOC,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_3);GPIO_Pin_
4、3);读取PC3的当前输出电平当前状态反相后写入到PC3实现LEDLED反转,main()函数F1 1、关于、关于LedLed灯的代码,把前面写的灯的代码,把前面写的led.cled.c和和led.hled.h文件复制文件复制一份添加到工程就可以了。一份添加到工程就可以了。F2 2、启动文件调用了、启动文件调用了SystemInit()SystemInit()将系统时钟将系统时钟SYSCLKSYSCLK配置配置为为72MHz72MHz。F3 3、接着进入到、接着进入到mainmain函数,第一步先调用了在函数,第一步先调用了在LEDLED灯例程中灯例程中编写的编写的LED_GPIO_Confi
5、g()LED_GPIO_Config(),配置,配置LEDLED用到的用到的I/OI/O。F4 4、再使用、再使用LED1(ON)LED1(ON)宏,把宏,把LEDLED设置为点亮状态。设置为点亮状态。F5 5、配置按键用到的、配置按键用到的I/OI/O口口 Key_GPIO_ConfigKey_GPIO_Config函数。函数。F6 6、按键检测函数,按键时调用、按键检测函数,按键时调用GPIO_WriteBitGPIO_WriteBit函数,实现函数,实现灯反转。灯反转。设计按键函数头文件bsp_key.hbsp_key.h#ifndef _KEY_H /#ifndef _KEY_H /条
6、件编译条件编译#define _KEY_H#define _KEY_H#include stm32f10 x.h#include stm32f10 x.h#define KEY_ON#define KEY_ON 0 /0 /按键按下标志按键按下标志#define KEY_OFF#define KEY_OFF1 /1 /无按键标志无按键标志void Key_GPIO_Config(void);void Key_GPIO_Config(void);uint8_t Key_Scan(GPIO_TypeDefuint8_t Key_Scan(GPIO_TypeDef*GPIOx,u16 GPIO_Pi
7、n);GPIOx,u16 GPIO_Pin);#endif#endif设计按键函数Key_GPIO_Config()Key_GPIO_Config()#include#include bsp_key.hbsp_key.h void void Key_GPIO_ConfigKey_GPIO_Config(void)(void)GPIO_InitTypeDefGPIO_InitTypeDef GPIO_InitStructureGPIO_InitStructure;/*开启按键端口开启按键端口GPIOEGPIOE(PE5PE5)的时钟)的时钟*/RCC_APB2PeriphClockCmd(RCC
8、_APB2Periph_GPIOE,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);GPIO_InitStructure.GPIO_PinGPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;=GPIO_Pin_5;GPIO_InitStructure.GPIO_ModeGPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPUGPIO_Mode_IPU;GPIO_InitGPIO_Init(GPIOE,&(GPIOE,&GPIO_InitStructureGPIO_Ini
9、tStructure););F跟跟LEDLED的的GPIOGPIO初始化函数初始化函数LED_GPIO_ConfigLED_GPIO_Config()()类似。类似。F可用符号可用符号|同时配置多个:同时配置多个:GPIO_Pin_5|GPIO_Pin_6;GPIO_Pin_5|GPIO_Pin_6;按键检测函数按键检测函数 Key_Scan()Key_Scan()/*输入输入 :GPIOxGPIOx、GPIO_Pin GPIO_Pin:待读取的端口、引脚:待读取的端口、引脚 *输出输出 :KEY_OFF(KEY_OFF(没按下按键没按下按键)、KEY_ONKEY_ON(按下按键)(按下按键)
10、*/u8 u8 Key_ScanKey_Scan(GPIO_TypeDef(GPIO_TypeDef*GPIOx,u16 GPIO_Pin)GPIOx,u16 GPIO_Pin)/*检测是否有按键按下检测是否有按键按下 */if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)=KEY_ON)if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)=KEY_ON)Delay(10000);/Delay(10000);/延时消抖延时消抖 if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)=KEY_ON)if(GPIO
11、_ReadInputDataBit(GPIOx,GPIO_Pin)=KEY_ON)while while(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)=KEY_ON);(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)=KEY_ON);return KEY_ON;/return KEY_ON;/等待按键释放等待按键释放 else else return KEY_OFF;return KEY_OFF;else else return KEY_OFF;return KEY_OFF;检测是否有按键按下检测是否有按键按下 F库函数库函数GPIO_
12、ReadInputDataBit(GPIO_ReadInputDataBit(端口号,引脚号端口号,引脚号);F返回引脚数据,返回引脚数据,0 0为低电平,为低电平,KEY_ONKEY_ON,可能有按键按下,可能有按键按下,调用延时函数消抖;否则返回调用延时函数消抖;否则返回1 1为高电平,为高电平,KEY_OFFKEY_OFF,表示,表示按键没有被按下。按键没有被按下。F延时之后再次读取该引脚数据,若依然为低电平,表明确延时之后再次读取该引脚数据,若依然为低电平,表明确实有按键被按下了;否则返回实有按键被按下了;否则返回KEY_OFFKEY_OFF,表示没按键。,表示没按键。Fwhilewh
13、ile循环调用循环调用GPIO_ReadInputDataBit()GPIO_ReadInputDataBit(),等待按键释放,等待按键释放,条件变为假退出循环,返回表示按键被按下的标志,条件变为假退出循环,返回表示按键被按下的标志KEY_ONKEY_ON。F同理,通过输入不同的实参,来检测其它按键的引脚。这同理,通过输入不同的实参,来检测其它按键的引脚。这就是库的魅力!就是库的魅力!作业:课下任务作业:课下任务F1 1、进一步熟悉、进一步熟悉GPIOGPIO,掌握,掌握GPIOGPIO设计。设计。F2 2、掌握、掌握GPIOGPIO键盘实验,实验报告。键盘实验,实验报告。9.2 GPIO外
14、部中断EXTI设计设计FEXTI(External interrupt)EXTI(External interrupt):通过:通过GPIOGPIO检测输入脉冲,检测输入脉冲,引起中断事件,打断原来的代码执行流程,进入到中断服引起中断事件,打断原来的代码执行流程,进入到中断服务函数,处理完后,再返回到中断之前的代码中执行。务函数,处理完后,再返回到中断之前的代码中执行。FSTM32STM32的所有的所有GPIOGPIO都可以用作外部中断源,可把按键轮询都可以用作外部中断源,可把按键轮询检测改为由中断来处理,大大提高软件执行的效率。检测改为由中断来处理,大大提高软件执行的效率。FCortexCo
15、rtex内核具有强大的异常响应系统,能够打断当前代码内核具有强大的异常响应系统,能够打断当前代码执行流程的事件分为异常执行流程的事件分为异常exceptionexception和中断和中断interruptinterrupt,用,用一个异常向量表管理起来,编号为一个异常向量表管理起来,编号为015015的称为内核异常,的称为内核异常,而而1616以上的则称为外部中断。以上的则称为外部中断。FSTM32STM32向量表,优先级从向量表,优先级从-3-3至至6 6的中断向量称为系统异常,的中断向量称为系统异常,优先级为负的不能设置优先级,如复位优先级为负的不能设置优先级,如复位ResetReset
16、、不可屏蔽、不可屏蔽中断中断NMINMI、硬错误、硬错误HardfaultHardfault。F从优先级从优先级7 7开始的称为外部中断,优先级可自行设置。开始的称为外部中断,优先级可自行设置。STM32中断向量表STM32中断向量表-详见参考手册GPIO外部中断EXTIF中断控制器中断控制器NVICNVIC属于属于CortexCortex内核的器件,能配置内核的器件,能配置1616种中断种中断向量,超过向量,超过1616个中断向量时,必然有个中断向量时,必然有2 2个以上的中断向量是个以上的中断向量是使用相同的中断种类。注意:相同种类的中断不能嵌套。使用相同的中断种类。注意:相同种类的中断不
17、能嵌套。FGPIOGPIO与与EXTIEXTI的连接方式:的连接方式:FPAxPGxPAxPGx端口的中断事件都连接端口的中断事件都连接到了到了EXTIxEXTIx,可以分时复用。,可以分时复用。F可以配置为下降沿中断,上升可以配置为下降沿中断,上升沿中断和上升下降沿中断这三沿中断和上升下降沿中断这三种模式。种模式。FEXTIEXTI最普通的应用就是接上一最普通的应用就是接上一个按键,设置为下降沿触发,个按键,设置为下降沿触发,用中断来检测按键。用中断来检测按键。外部中断0 与NVIC 的关系EXTIEXTI寄存器EXTIEXTI寄存器结构:寄存器结构:typedef struct typed
18、ef struct vu32 IMR;vu32 IMR;vu32 EMR;vu32 EMR;vu32 RTSR;vu32 RTSR;vu32 FTSR;vu32 FTSR;vu32 SWIER;vu32 SWIER;vu32 PR;EXTI_TypeDef;vu32 PR;EXTI_TypeDef;EXTIEXTI库函数NVICNVIC寄存器NVICNVIC库函数NVIC配置Fmiscmisc库中库中NVIC_Init()NVIC_Init()函数对函数对NVICNVIC初始化,用到初始化,用到NVIC_InitTypeDef NVIC_InitTypeDef 结构体,其中四个成员:结构体,其
19、中四个成员:NVIC_IRQChannelNVIC_IRQChannel参数来选择将要配置的中断向量;参数来选择将要配置的中断向量;NVIC_IRQChannelCmdNVIC_IRQChannelCmd参数来进行使能参数来进行使能(ENABLE)(ENABLE)或关闭或关闭(DISABLEDISABLE)该中断;)该中断;NVIC_IRQChannelPreemptionPriorityNVIC_IRQChannelPreemptionPriority成员要配置中断成员要配置中断向量的抢占优先级;向量的抢占优先级;NVIC_IRQChannelSubPriorityNVIC_IRQChann
20、elSubPriority需要配置中断向量的响需要配置中断向量的响应优先级。应优先级。FNVICNVIC只可配置只可配置1616种中断向量的优先级:编号越小,优先级种中断向量的优先级:编号越小,优先级别越高;别越高;F抢占优先级:是指打断其它中断,会出现嵌套中断;抢占优先级:是指打断其它中断,会出现嵌套中断;F响应优先级:先处理响应优先级高的中断;响应优先级:先处理响应优先级高的中断;中断检测按键实验F硬件连接:硬件连接:PE5 key1PE5 key1、PE6 key2 PE6 key2,key1key1按下时,按下时,进入线中断处理函数,进入线中断处理函数,LED1LED1状态取反。状态取
21、反。F配置工程环境:配置工程环境:除使用除使用GPIOGPIO和和RCCRCC片上外设;片上外设;还要使用还要使用extiexti片上外设,片上外设,stm32f10 x_exti.cstm32f10 x_exti.c包含了支包含了支持持extiexti配置和操作的函数;配置和操作的函数;misc.cmisc.c文件则包含了文件则包含了NVICNVIC的配置函数;的配置函数;F本实验中还会在本实验中还会在stm32f10 x_it.cstm32f10 x_it.c中编写中断服务函数。中编写中断服务函数。Main函数F配置好配置好LEDLED用到的用到的I/OI/O后,调用后,调用LED1()L
22、ED1()点亮一盏点亮一盏LEDLED灯;配灯;配置中断,等待中断发生。置中断,等待中断发生。intint main(void)main(void)/*configconfig the led the led*/LED_GPIO_ConfigLED_GPIO_Config();();LED1(ON);LED1(ON);/*extiexti line line configconfig */EXTI_PE5_Config();EXTI_PE5_Config();/*wait interrupt wait interrupt*/while(1)while(1)配置外部中断配置外部中断exti.ce
23、xti.cFEXTI_PE5_Config()EXTI_PE5_Config()函数,配置函数,配置 PE5 PE5 为线中断口,并设置为线中断口,并设置中断优先级。中断优先级。F主要步骤:主要步骤:1.1.使能使能EXTIxEXTIx线的时钟和第二功能线的时钟和第二功能AFIOAFIO时钟时钟 2.2.配置配置EXTIxEXTIx线的中断优先级线的中断优先级 3.3.配置配置EXTI EXTI 中断线中断线I/O I/O 4.4.选定要配置为选定要配置为EXTIEXTI的的I/OI/O口线和口线和I/OI/O口的工作模式口的工作模式 5.EXTI 5.EXTI 中断线工作模式配置中断线工作模
24、式配置 EXTI_PE5_Config()EXTI_PE5_Config()函数函数8.void EXTI_PE5_Config(void)8.void EXTI_PE5_Config(void)9.9.10.GPIO_InitTypeDef GPIO_InitStructure;10.GPIO_InitTypeDef GPIO_InitStructure;11.EXTI_InitTypeDef EXTI_InitStructure;11.EXTI_InitTypeDef EXTI_InitStructure;13.13./*config the extiline(PE5)clock and
25、AFIO clock config the extiline(PE5)clock and AFIO clock*/14.RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|14.RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO,ENABLE);RCC_APB2Periph_AFIO,ENABLE);16./16./*config the NVIC(PE5)config the NVIC(PE5)*/17.NVIC_Configuration();17.NVIC_Configurat
26、ion();/NVIC/NVIC初始化配置初始化配置19.19./*EXTI line gpio config(PE5)EXTI line gpio config(PE5)*/20.GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;20.GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;21.GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;21.GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;/上拉输入上拉输入 EXTI_PE5_Config()EXTI_PE5_
27、Config()函数函数_ _续续22.22.GPIO_InitGPIO_Init(GPIOE,&(GPIOE,&GPIO_InitStructureGPIO_InitStructure););24.24./*EXTI line(PE5)mode config EXTI line(PE5)mode config*/25.25.GPIO_EXTILineConfigGPIO_EXTILineConfig(GPIO_PortSourceGPIOEGPIO_PortSourceGPIOE,GPIO_PinSource5);GPIO_PinSource5);/PE5/PE5设置为设置为EXTIEXTI
28、输入线输入线26.26.EXTI_InitStructure.EXTI_LineEXTI_InitStructure.EXTI_Line=EXTI_Line5;=EXTI_Line5;27.27.EXTI_InitStructure.EXTI_ModeEXTI_InitStructure.EXTI_Mode=EXTI_Mode_InterruptEXTI_Mode_Interrupt;28.28.EXTI_InitStructure.EXTI_TriggerEXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_FallingEXTI_Trigger_Fall
29、ing;/下降沿触发中断下降沿触发中断 29.29.EXTI_InitStructure.EXTI_LineCmdEXTI_InitStructure.EXTI_LineCmd=ENABLE;=ENABLE;30.30.EXTI_InitEXTI_Init(&(&EXTI_InitStructureEXTI_InitStructure););31.31.GPIO端口的复用功能AFIOFAFIO(alternate-function I/O)AFIO(alternate-function I/O),GPIOGPIO除了用作普通的除了用作普通的输入输出输入输出(主功能主功能),还可以作为片上外设的
30、复用输入输出,还可以作为片上外设的复用输入输出,如串口,如串口,ADCADC,这些就是复用功能。,这些就是复用功能。FGPIOGPIO还有重映射功能:重映射功能是指把原来属于还有重映射功能:重映射功能是指把原来属于A A引脚引脚的默认复用功能,转移到了的默认复用功能,转移到了B B引脚进行使用(当然引脚进行使用(当然B B引脚具引脚具有这个重映射功能)。有这个重映射功能)。F当把当把GPIOGPIO用作用作EXTIEXTI外部中断外部中断 或使用重映射功能的时候,或使用重映射功能的时候,必须开启必须开启AFIOAFIO时钟。时钟。F代码的第代码的第1414行,开启了行,开启了AFIOAFIO的
31、时钟。的时钟。NVIC初始化配置FEXTI_PE5_Config()EXTI_PE5_Config()调用了调用了NVIC_ConfigurationNVIC_Configuration()()函数来配置函数来配置NVICNVIC控制器。控制器。8.static void 8.static void NVIC_ConfigurationNVIC_Configuration(void)(void)9.9.10.10.NVIC_InitTypeDefNVIC_InitTypeDef NVIC_InitStructureNVIC_InitStructure;12./12./*Configure on
32、e bit for preemption priority Configure one bit for preemption priority*/13.13.NVIC_PriorityGroupConfigNVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);(NVIC_PriorityGroup_1);15./15./*配置配置PA|B|C|D|E5PA|B|C|D|E5为中断源为中断源 */16.16.NVIC_InitStructure.NVIC_IRQChannelNVIC_InitStructure.NVIC_IRQChannel=EXTI9_
33、5_IRQn;=EXTI9_5_IRQn;17.17.NVIC_InitStructure.NVIC_NVIC_InitStructure.NVIC_IRQChannelPreemptionPriorityIRQChannelPreemptionPriority=0;=0;18.18.NVIC_InitStructure.NVIC_IRQChannelSubPriorityNVIC_InitStructure.NVIC_IRQChannelSubPriority=0;=0;19.19.NVIC_InitStructure.NVIC_IRQChannelCmdNVIC_InitStructure
34、.NVIC_IRQChannelCmd=ENABLE;=ENABLE;20.20.NVIC_InitNVIC_Init(&(&NVIC_InitStructureNVIC_InitStructure););/向寄存器写入参数21.21.把NVIC中断优先级分组设置为第1组要配置的为EXTI第59线的中断向量抢占优先级和响应优先级,设为最高编写中断服务函数 FPE5PE5连接到内部的连接到内部的EXTI5EXTI5,GPIOGPIO配置为上拉输入,工作在下配置为上拉输入,工作在下降沿中断。在外围电路上我们将降沿中断。在外围电路上我们将PE5PE5接到了接到了key1key1上。上。FPE5PE5
35、始终为高,当按键按下时始终为高,当按键按下时,下降沿跳变下降沿跳变,EXTI5,EXTI5会捕捉到会捕捉到这一跳变,并产生相应的中断,中断服务程序在这一跳变,并产生相应的中断,中断服务程序在stm32f10 x_it.cstm32f10 x_it.c中实现,专门用来存放中断服务函数。中实现,专门用来存放中断服务函数。F中断服务函数的名字必须要跟启动文件中断服务函数的名字必须要跟启动文件startup_stm32f10 x_hd.sstartup_stm32f10 x_hd.s中的中断向量表定义一致:中的中断向量表定义一致:DCD EXTI9_5_IRQHandler DCD EXTI9_5_I
36、RQHandler;EXTI Line 9.5;EXTI Line 9.5 EXTI9EXTI5EXTI9EXTI5中断向量的服务函数名中断向量的服务函数名F在在stm32f10 x_it.cstm32f10 x_it.c中加入中加入EXTI9_5_IRQHandler()EXTI9_5_IRQHandler()函数;函数;EXTI9_5_IRQHandler()EXTI9_5_IRQHandler()函数函数/*I/O I/O线中断,中断线为线中断,中断线为PE5 PE5*/void EXTI9_5_IRQHandler(void)void EXTI9_5_IRQHandler(void)i
37、f(EXTI_GetITStatus(EXTI_Line5)!=RESET)if(EXTI_GetITStatus(EXTI_Line5)!=RESET)/确保是否产生了确保是否产生了EXTI LineEXTI Line中断中断 /LED1/LED1 取反取反 GPIO_WriteBit(GPIOC,GPIO_Pin_3,GPIO_WriteBit(GPIOC,GPIO_Pin_3,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOC,(BitAction)(1-GPIO_ReadOutputDataBit(GPIOC,GPIO_Pin_3);GPIO_Pin_
38、3);/清除中断标志位清除中断标志位 EXTI_ClearITPendingBit(EXTI_Line5);EXTI_ClearITPendingBit(EXTI_Line5);实验现象F将野火将野火STM32STM32开发板供电开发板供电(DC5V)(DC5V),插上,插上JLINKJLINK,将编译好的,将编译好的程序下载到开发板,程序下载到开发板,LED1LED1亮,按下按键时亮,按下按键时LED1LED1灭,再按下灭,再按下按键时按键时LED1LED1亮,如此循环。亮,如此循环。9.2 9.2 课下任务课下任务F阅读阅读P161-172P161-172F阅读阅读Cortex-M3 Cortex-M3 权威指南,第权威指南,第7 7、8 8、9 9章章F阅读野火资料:阅读野火资料:P124-141P124-141F1 1、NVICNVIC嵌套向量中断控制器嵌套向量中断控制器F2 2、中断向量表、中断向量表F3 3、EXTIEXTI外部中断外部中断谢谢观看!2020