《嵌入式系统设计(STM32)第4讲ppt课件.ppt》由会员分享,可在线阅读,更多相关《嵌入式系统设计(STM32)第4讲ppt课件.ppt(56页珍藏版)》请在三一办公上搜索。
1、第4讲 中断,实验三 独立按键控制,实验目的:掌握独立按键的工作原理及按键控制程序的编写方法。实验内容:PA口的四个按键,任意键闭合,4个LED灯呈现不同的显示状态。,实验四 按键中断实验,实验目的:掌握STM32中断系统的工作原理,掌握利用函数库编写中断初始化程序与中断服务程序的方法。实验内容:(1)选4个独立按键中任意一个作为外部中断输入,4个LED正常以流水灯点亮,按键闭合后,4个灯同时循环亮灭4次,重新回到流水灯状态。(2)中断嵌套实验。主循环是流水灯,按键1中断,4个灯同时循环亮灭10次;按键2可以在中断按键1的程序,1、3和2、4灯交替点亮5次。,实验五 键盘识别与数码显示,实验目
2、的:掌握矩阵键盘的按键识别原理,以及数码管显示的方法。实验内容:将矩阵键盘上的按键编号显示在数码管上。(1)只用1位显示。(2)每按键一次,显示向左移一位,最多显示6位。接口电路参见光盘资料,主要内容,4.1 基本概念4.2 中断源 4.3 中断优先级4.4 STM32中断寄存器4.5 STM32中断库函数4.6 中断编程举例4.7 练习题,4.1 基本概念,中断是指由于内部或者外部事件使CPU暂停当前程序,转去执行中断服务程序的一种工作机制。中断系统由中断源、中断控制、中断响应几部分组成。 中断源:中断请求的来源。中断控制:中断的允许/禁止,中断优先级与优先级嵌套。中断响应:保护断点,转去执
3、行中断服务程序。,返回,4.2 中断源,ARM cortex_m3内核支持256个中断(16个内核+240外部)和可编程256级中断优先级的设置,与其相关的中断控制和中断优先级控制寄存器(NVIC、SYSTICK等)也都属于cortex_m3内核的部分。STM32采用了cortex_m3内核,但STM32并没有使用cortex_m3内核全部的东西(如内存保护单元MPU等),因此它的NVIC是cortex_m3内核的NVIC的子集。 STM32目前支持的中断共为84个(16个内核+68个外部),和16级(使用了4位中断优先级控制)可编程中断优先级的设置。,异常和中断的概念,中断:该请求信号来自C
4、M3内核的外面,来自各种片上外设和外扩的外设。异常:是因CM3内核的活动产生的,即执行指令或访问存储器时产生。CM3有15个异常,类型号为115,没有编号为0的异常。挂起:一个发生的异常不能被立即响应,就称它为挂起。,中断的特点,对于互联型产品,外部中断/事件控制器由20个产生事件/中断请求的边沿检测器组成,对于其它产品,则有19个能产生事件/中断请求的边沿检测器。每个输入线可以独立地配置输入类型(脉冲或挂起)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。每个输入线都可以独立地被屏蔽。挂起寄存器保持着状态线的中断请求。,外部中断(EXTI),外部中断/事件控制器(EXTI)有19个中断请
5、求边沿检测器。每个中断/事件都有独立的触发和屏蔽 每个中断线都有专用的状态位 EXTI0-EXTI15:连到IO端口,每个EXTIj对应GPIOx的引脚j。通过软件配置,设定中断来自哪个引脚。EXTI16:PVD(programmable voltage detector)输出EXTI17:RTC( real-time clock)闹钟事件EXTI18:USB唤醒事件EXTI19:连接到以太网唤醒事件(只适用于互联型产品),硬件中断选择通过下面的过程来配置19个线路做为中断源: 配置19个中断线的屏蔽位(EXTI_IMR) 配置所选中断线的触发选择位(EXTI_RTSR和EXTI_FTSR);
6、 配置对应到外部中断控制器(EXTI)的NVIC中断通道的使能和屏蔽位,使得19个中断线中的请求可以被正确地响应。,外部中断/事件控制器框图,要产生中断,必须先配置好并使能中断线。根据需要的边沿检测设置2个触发寄存器,同时在中断屏蔽寄存器的相应位写1允许中断请求。当外部中断线上发生了期待的边沿时,将产生一个中断请求,对应的挂起位也随之被置1。在挂起寄存器的对应位写1,可以清除它,也可以通过改变边沿检测的极性清除。 如果需要产生事件,必须先配置好并使能事件线。根据需要的边沿检测通过设置2个触发寄存器,同时在事件屏蔽寄存器的相应位写1允许事件请求。当事件线上发生了需要的边沿时,将产生一个事件请求脉
7、冲,对应的挂起位不被置1。 通过在软件中断/事件寄存器写1,也可以通过软件产生中断/事件请求。,112通用I/O端口以下图的方式连接到16个外部中断/事件线上:,EXTICR: 外部中断线路0-15配置寄存器,有4个32位的外部中断线路配置寄存器,高16位保留,低16位用来定义外部中断线路。,EXTICR: 外部中断线路0-15配置寄存器,EXTIx3:0:EXTIx配置(x = 0 3) (EXTIx configuration) 这些位可由软件读写,用于选择EXTIx外部中断的输入源。0000:PAx引脚0001:PBx引脚0010:PCx引脚0011:PDx引脚 0100:PEx引脚01
8、01:PFx引脚0110:PGx引脚,配置中断线路函数GPIO_EXTILineConfig,功能描述:选择GPIO管脚用作外部中断线路函数原形: void GPIO_EXTILineConfig(u8 GPIO_PortSource, u8 GPIO_PinSource) 输入参数1: GPIO_PortSource - 选择用作外部中断线源的GPIO端口输入参数2: GPIO_PinSource - 待设置的外部中断线路例:/* Selects PB.8 as EXTI Line 8 */ GPIO_EXTILineConfig(GPIO_PortSource_GPIOB, GPIO_Pi
9、nSource8);,外部中断的触发方式,上升沿、下降沿、上升沿/下降沿EXTI_Trigger_Falling: 设置输入线路下降沿为中断请求 EXTI_Trigger_Rising: 设置输入线路上升沿为中断请求 EXTI_Trigger_Rising_Falling: 设置输入线路双边触发中断请求 EXTI_Mode_Event :设置EXTI线路为事件EXTI_Mode_Interrupt:设置EXTI线路为中断请求EXTI_LineCmd:用来定义选中线路的新状态。它可以被设为ENABLE或者DISABLE。,中断初始化函数EXTI_Init,例:/* Enables externa
10、l lines 12 and 14 interrupt generation on falling edge */ EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line = EXTI_Line12 | EXTI_Line14; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;
11、EXTI_Init(,返回,4.3 中断优先级,中断优先级分组:STM32有5种优先级管理方式,在一个系统中,选用其中一种。通过设置32位寄存器AIRC的10:8位,指定组别。优先级分组:第0组:16个从优先级第1组:2个抢占优先级,8个从优先级第2组:4个抢占优先级,4个从优先级第3组:8个抢占优先级,2个从优先级第4组:16个抢占优先级,优先级控制说明,具有较高抢占优先级的中断(数字小的)可以实现中断嵌套。从优先级不管高低,只能排队。在抢占优先级相同时,先响应从优先级高的中断。抢占优先级和从优先级都相同时,根据它们在中断表中的排位顺序决定,序号小的先被处理。,例: /* Configure
12、 the Priority Grouping with 1 bit */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);,4.4 STM32中断寄存器,EXTI_IMR:中断屏蔽寄存器 0:屏蔽来自线x上的中断请求; 1:开放来自线x上的中断请求。EXTI_EMR:事件屏蔽寄存器 0:屏蔽来自线x上的事件请求; 1:开放来自线x上的事件请求。 EXTI_RTSR:上升沿触发选择寄存器 1:允许输入线x上的上升沿触发(中断和事件) ;0:禁止。EXTI_FTSR:下降沿触发选择寄存器 1:允许输入线x上的下降沿触发(中断和事件) ;0:禁止。EXT
13、I_SWIER:软件中断事件寄存器 当某位为0时,写1将设置EXTI_PR中相应的挂起位。如果在EXTI_IMR和EXTI_EMR中允许产生该中断,则此时将产生一个中断。 注:通过清除EXTI_PR的对应位(写入1),可以清除该位为0。 EXTI_PR:挂起寄存器 当在外部中断线上发生了选择的边沿事件,该位被置1。在该位中写入1可以清除它,也可以通过改变边沿检测的极性清除。,返回,EXTI库函数,EXTI_DeInit: 将外设EXTI寄存器重设为缺省值EXTI_Init: 根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器。EXTI_StructInit: 把EXTI_I
14、nitStruct中的每一个参数按缺省值填入。EXTI_GenerateSWInterrupt:产生一个软件中断。EXTI_GetFlagStatus:检查指定的EXTI线路标志位设置与否。EXTI_ClearFlag:清除EXTI线路挂起标志位。EXTI_GetITStatus: 检查指定的EXTI线路触发请求发生与否。EXTI_ClearITPendingBit: 清除EXTI线路挂起位,函数EXTI_Init,功能描述: 根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器。函数原形: void EXTI_Init(EXTI_InitTypeDef* EXTI_Init
15、Struct) 输入参数: EXTI_InitStruct-指向结构EXTI_InitTypeDef的指针。,EXTI_InitTypeDef定义于文件“stm32f10 x_exti.h”: typedef struct u32 EXTI_Line; EXTIMode_TypeDef EXTI_Mode;EXTIrigger_TypeDef EXTI_Trigger;FunctionalState EXTI_LineCmd; EXTI_InitTypeDef;,EXTI_Line:EXTI_Line0 - EXTI_Line18,其中之一。EXTI_Mode: EXTI_Mode_Event
16、 或者 EXTI_Mode_Interrupt EXTI_Trigger : EXTI_Trigger_Falling 或者 EXTI_Trigger_Rising 或者 EXTI_Trigger_Rising_Falling EXTI_LineCmd :ENABLE或者DISABLE,例: /* Enables external lines 12 and 14 interrupt generation on falling edge */ EXTI_InitTypeDef EXTI_InitStructure;EXTI_InitStructure.EXTI_Line = EXTI_Line1
17、2 | EXTI_Line14; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(,函数EXTI_GetFlagStatus,功能描述:检查指定的EXTI线路标志位设置与否函数原形: FlagStatus EXTI_GetFlagStatus(u32 EXTI_Line) 输入参数: EXTI_Line-待检查的EXTI线路标志位。
18、返回值: EXTI_Line的新状态(SET或者RESET)例: /* Get the status of EXTI line 8 */ FlagStatus EXTIStatus; EXTIStatus = EXTI_GetFlagStatus(EXTI_Line8);,固态函数库的编码规则,布尔型typedef enum FALSE = 0, TRUE = !FALSE bool;,标志位状态类型typedef enum RESET = 0, SET = !RESET FlagStatus;,错误状态类型typedef enum ERROR = 0, SUCCESS = !ERROR Er
19、rorStatus;,功能状态类型 typedef enum DISABLE = 0, ENABLE= !DISABLE FunctionalState;,固态函数库定义了24个变量类型,它们的类型和大小是固定的。,typedef signed long s32; typedef signed short s16; typedef signed char s8; typedef signed long const sc32; /* Read Only */ typedef signed short const sc16; /* Read Only */ typedef signed char
20、const sc8; /* Read Only */ typedef volatile signed long vs32; typedef volatile signed short vs16; typedef volatile signed char vs8; typedef volatile signed long const vsc32; /* Read Only */ typedef volatile signed short const vsc16; /* Read Only */ typedef volatile signed char const vsc8; /* Read On
21、ly */,typedef unsigned long u32; typedef unsigned short u16; typedef unsigned char u8; typedef unsigned long const uc32; /* Read Only */ typedef unsigned short const uc16; /* Read Only */ typedef unsigned char const uc8; /* Read Only */ typedef volatile unsigned long vu32; typedef volatile unsigned
22、short vu16; typedef volatile unsigned char vu8; typedef volatile unsigned long const vuc32; /* Read Only */ typedef volatile unsigned short const vuc16; /* Read Only */ typedef volatile unsigned char const vuc8; /* Read Only */,函数EXTI_ClearFlag,功能描述:清除EXTI线路挂起标志位。函数原形:void EXTI_ClearFlag(u32 EXTI_Li
23、ne) 输入参数 :EXTI_Line-待清除标志位的EXTI线路例: /* Clear the EXTI line 2 pending flag */ EXTI_ClearFlag(EXTI_Line2);,函数EXTI_GetITStatus,功能描述:检查指定的EXTI线路触发请求发生与否。 (检查中断请求,函数EXTI_ClearITPendingBit,功能描述:清除EXTI线路挂起位函数原形: void EXTI_ClearITPendingBit(u32 EXTI_Line) 例: /* Clears the EXTI line 2 interrupt pending bit *
24、/ EXTI_ClearITpendingBit(EXTI_Line2);,NVIC库函数,NVIC_DeInit :将外设NVIC寄存器重设为缺省值NVIC_PriorityGroupConfig: 设置优先级分组NVIC_Init:根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器。NVIC_SetVectorTable:设置向量表的位置和偏移,函数NVIC_PriorityGroupConfig,功能:用来设置优先级分组(先占优先级和从优先级) 函数原形: void NVIC_PriorityGroupConfig(u32 NVIC_PriorityGroup) 例:
25、 /* Configure the Priority Grouping with 1 bit */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);,NVIC_PriorityGroup 描述,函数 NVIC_Init,功能描述:根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器。函数原形: void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) 输入参数: NVIC_InitStruct-指向结构NVIC_InitTypeDef的指针。,NVIC_InitTypeDef struct
26、ure,NVIC_InitTypeDef定义于文件“stm32f10 x_nvic.h”: typedef struct u8 NVIC_IRQChannel; u8 NVIC_IRQChannelPreemptionPriority; u8 NVIC_IRQChannelSubPriority; FunctionalState NVIC_IRQChannelCmd; NVIC_InitTypeDef; NVIC_IRQChannelCmd:指定了在成员NVIC_IRQChannel中定义的IRQ通道被使能还是失能,NVIC_IRQChannel值,EXTI0_IRQChannel: 外部中断
27、线0中断EXTI1_IRQChannel: 外部中断线1中断EXTI2_IRQChannel: 外部中断线2中断EXTI3_IRQChannel: 外部中断线3中断EXTI4_IRQChannel: 外部中断线4中断EXTI9_5_IRQChannel: 外部中断线9-5中断EXTI15_10_IRQChannel: 外部中断线15-10中断TIM2_IRQChannel: TIM2全局中断TIM3_IRQChannel: TIM3全局中断TIM4_IRQChannel: TIM4全局中断,例: NVIC_InitTypeDef NVIC_InitStructure; /* Configure
28、 the Priority Grouping with 1 bit */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); /* Enable TIM3 global interrupt with Preemption Priority 0 and Sub Priority as 2 */ NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IR
29、QChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure(,函数NVIC_StructInit,功能描述:把NVIC_InitStruct中的每一个参数按缺省值填入。 成员 缺省值 NVIC_IRQChannel 0 x0 NVIC_IRQChannelPreemptionPriority 0 NVIC_IRQChannelSubPriority 0 NVIC_IRQChannelCmd DISABLE例: NVIC_InitTypeDef NVIC_InitStruc
30、ture; NVIC_StructInit(,返回,4.6 中断编程举例,定义变量声明函数主程序配置时钟配置中断优先级配置GPIO配置EXTI主循环4个LED循环点亮中断服务函数1,2灯和3,4灯交替点亮5次,#include stm32f10 x_lib.h ErrorStatus HSEStartUpStatus;extern vu32 TimingDelay;u8 ReadValue1,ReadValue2,ReadValue3,ReadValue4;void RCC_Configuration(void);void GPIO_Configuration(void);void NVIC_
31、Configuration(void);void EXTI_Configuration(void);extern void Delay(vu32 nTime);,int main() RCC_Configuration();/* 配置系统时钟 */ NVIC_Configuration(); /* 配置中断优先级 */ GPIO_Configuration();/* IO口初始化 */EXTI_Configuration(); /* 配置外部中断 */ while(1) GPIOC-ODR = 0 xfffffffe; /* PC0=0 - 点亮D2 */ Delay(8000000);GPI
32、OC-ODR = 0 xfffffffd;/* PC1=0 - 点亮D3 */Delay(8000000);GPIOC-ODR = 0 xfffffffb; /* PC2=0 - 点亮D4 */Delay(8000000);GPIOC-ODR = 0 xfffffff7; /* PC3=0 - 点亮D5 */Delay(8000000); ,void RCC_Configuration() /系统时钟配置,略。 /使能外设时钟RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOA| RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFI
33、O,ENABLE);void Delay(vu32 nCount) /* 延时 */ for(; nCount != 0; nCount-);,void EXTI_Configuration()GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource3);EXTI_InitTypeDef EXTI_InitStructure;EXTI_InitStructure.EXTI_Line = EXTI_Line3;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructu
34、re.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(,void NVIC_Configuration()NVIC_InitTypeDef NVIC_InitStructure; /* Set the Vector Table base location at 0 x20000000 */ /设置向量表的位置和偏移 #ifdef VECT_TAB_RAM NVIC_SetVectorTable(NVIC_VectTab_RAM, 0 x0); #else /* VECT
35、_TAB_FLASH Set the Vector Table base location at 0 x08000000*/ NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0 x0); #endif /* Configure one bit for preemption priority */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPree
36、mptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(,void GPIO_Configuration() /* IO口初始化 */ GPIO_InitTypeDef GPIO_InitStructure; /* PA0PA3口配置为输入 */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pi
37、n_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOA, ,中断服务程序,void EXTI3_IRQHandler(void) int i=0;if(EXTI_GetITStatus(EXTI_Line3) != RESET) EXTI_ClearITPendingBit(EXTI_Line3);for(i=0;iODR = 0 xfffffff0; Delay(0 x400000);GPIOC-ODR = 0 xff
38、ffffff; Delay(0 x400000);,返回,练习题四,中断是指()中断系统包括()、()、()。STM32有()个中断源,其中()个异常,()中断。外部中断EXTI有()个。GPIO引脚都可以作为中断输入端,映射到内部()中断通道。EXIT0对应的GPIO引脚是()、()、()、()、()。中断请求的触发方式有()、()、()。STM32中断优先级包括()优先级和()优先级。只有()优先级高,才可以实现中断嵌套。中断嵌套是指()。STM32有()组优先级控制方式,一个系统中只能选用其中一组。当抢占优先级和副优先级都相同时,按照()决定响应顺序。中断服务程序全部保存在stm32f1
39、0 x_it.c文件中,中断服务程序(子函数)名为( ),函数是空的,可在其中编写代码。中断服务函数也可以放在main.c中。,13. GPIOA.0作为中断请求输入端,下降沿触发。完成下列中断初始化配置程序。void EXTI_Configuration() GPIO_EXTILineConfig((),());EXTI_InitTypeDef EXTI_InitStructure;EXTI_InitStructure.EXTI_Line = ();EXTI_InitStructure.EXTI_Mode = ();EXTI_InitStructure.EXTI_Trigger = ();E
40、XTI_InitStructure.EXTI_LineCmd =();EXTI_Init(,14. 设置GPIOA.0和GPIOA.1上拉输入。void GPIO_Configuration( ) GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = ( ); GPIO_InitStructure.GPIO_Mode = ( ); GPIO_Init(GPIOA, ,15. 配置外部中断EXIT0抢占优先级为2级,副优先级为3级。void NVIC_Configuration() NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_( )); NVIC_InitStructure.NVIC_IRQChannel = EXTI()_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =(); NVIC_InitStructure.NVIC_IRQChannelSubPriority = ( ); NVIC_InitStructure.NVIC_IRQChannelCmd =( ); NVIC_Init(,返回,