STM32F103mini教程学习总结与心得(三)---->中断

STM32F103mini教程学习总结与心得(三)---->中断http://blog.csdn.net/qq_19598969/article/details/76167436

1. NVIC中断优先级分组

(1)CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。
(2)STM32并没有使用CM3内核的全部东西,而是只用了它的一部分。
(3)STM32有84个中断,包括16个内核中断和68个可屏蔽中断,具有16级可编程的中断优先级。
(4)STM32F103系列上面,又只有60个可屏蔽中断(在107系列才有68个)


2.中断管理方法:对STM32中断进行分组,组0~4。对每个中断设置一个抢占优先级和一个响应优先级值。


3.抢占优先级 & 响应优先级区别(数字越小,优先级越高):

(1)高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。
(2)抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
(3)抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
(4)如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;


4.特别说明:一般情况,系统代码执行过程中,只设置一次中断优先级分组,设置好分组之后一般不会再改变分组。


5.中断优先级分组函数【在misc.c+core_m3.h文件中有说明】: void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);

6.中断设置相关寄存器 :

__IO uint8_t IP[240]; //中断优先级控制的寄存器组---->Interrupt Priority Registers

=================================>>>STM32F10x系列一共60个可屏蔽中断,使用IP[59]~IP[0]
__IO uint32_t ISER[8]; //中断使能寄存器组----->32位寄存器,ISER[0]的bit0~bit31分别对应中断0~31。ISER[1]的bit0~27对应中断32~59


__IO uint32_t ICER[8]; //中断失能寄存器组----->用来失能中断
__IO uint32_t ISPR[8]; //中断挂起寄存器组----->用来挂起中断
__IO uint32_t ICPR[8]; //中断解挂寄存器组----->用来解挂中断
__IO uint32_t IABR[8]; //中断激活标志位寄存器组----->如果对应位为1,说明该中断正在执行。


static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn);
static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn);
static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)

static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)

7.中断参数初始化函数

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);


typedef struct
{
uint8_t NVIC_IRQChannel; //设置中断通道
uint8_t NVIC_IRQChannelPreemptionPriority;//设置响应优先级
uint8_t NVIC_IRQChannelSubPriority; //设置抢占优先级
FunctionalState NVIC_IRQChannelCmd; //使能/使能
} NVIC_InitTypeDef;
例:
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 抢占优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 子优先级位2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据上面指定的参数初始化NVIC寄存器


8.中断优先级设置步骤

①系统运行后先设置中断优先级分组。调用函数:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
整个系统执行过程中,只设置一次中断分组
②针对每个中断,设置对应的抢占优先级和响应优先级:
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
③ 如果需要挂起/解挂,查看中断当前激活状态,分别调用相关函数即可。


9.中断实验步骤

(1)STM32的每个IO都可以作为外部中断输入。
(2)STM32的中断控制器支持19个外部中断/事件请求
线0~15:对应外部IO口的输入中断
线16:连接到PVD输出。
线17:连接到RTC闹钟事件。
线18:连接到USB唤醒事件。

(3)每个外部中断线可以独立的配置触发方式(上升沿,下降沿或者双边沿触发),触发/屏蔽,专用的状态位。
(4)STM32供IO使用的中断线只有16个,但是STM32F10x系列的IO口多达上百个,STM32F103ZET6(112),STM32F103RCT6(51)

(5)外部中断通用IO映射:GPIOx.0映射到EXTI0
[在AFIO_EXTICR1寄存器配置]GPIOx.1映射到EXTI1

     GPIOx.15映射到EXTI15

注意:同一时间,同一中断线上,只能有一个IO映射到该中断线上。例如,GPIOA.0接到了EXTI0上的时候,   GPIOB.0就不能接入EXTI0。

(6)对于每个中断线,可以设置相应的触发方式(上升沿触发,下降沿触发,边沿触发)以及使能。

(7)对于STM32F1,有16个中断线,但只有7个中断服务函数------->>IO口外部中断在中断向量表中只分配了7个中断向量,也就是只能使用7个中断服务函数======>①外部中断线0-4分配5个中断向量,均有各自的服务函数②外部中断线5~9分配一个中断向量,共用一个服务函数③外部中断线10~15分配一个中断向量,共用一个中断服务函数。

说明:开启了线5和线6的中断,那么只要中断触发,那么5-9中断服务函数就会被调用。

(8)中断服务函数列表:EXTI0_IRQHandler 
 EXTI1_IRQHandler
 EXTI2_IRQHandler 
 EXTI3_IRQHandler 
 EXTI4_IRQHandler 
 EXTI9_5_IRQHandler 
 EXTI15_10_IRQHandler 

(9)外部中断常用库函数:

①void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
//设置IO口与中断线的映射关系

exp: GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);

②void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
//初始化中断线:触发方式等

③ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
//判断中断线中断状态,是否发生

④void EXTI_ClearITPendingBit(uint32_t EXTI_Line);------->>手动清零
//清除中断线上的中断标志位


⑤EXTI_Init函数:void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);

typedef struct
{
uint32_t EXTI_Line; //指定要配置的中断线 
EXTIMode_TypeDef EXTI_Mode; //模式:事件 OR中断
EXTITrigger_TypeDef EXTI_Trigger;//触发方式:上升沿/下降沿/双沿触发
FunctionalState EXTI_LineCmd; //使能 OR失能
}EXTI_InitTypeDef;

例:

EXTI_InitStructure.EXTI_Line=EXTI_Line2; 
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; 
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);


(10)外部中断的一般配置步骤:
①初始化IO口为输入。
GPIO_Init();
② 开启IO口复用时钟。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);----->重要
设置IO口与中断线的映射关系。
void GPIO_EXTILineConfig();
初始化线上中断,设置触发条件等。
EXTI_Init();
配置中断分组(NVIC),并使能中断。
NVIC_Init();
⑥ 编写中断服务函数。
EXTIx_IRQHandler();
清除中断标志位
EXTI_ClearITPendingBit();


EXIT.c文件内容

[cpp]  view plain  copy
  1. #include "exit.h"  
  2. #include "key.h"  
  3. #include "LED.h"  
  4. #include "delay.h"  
  5. #include "usart.h"  
  6. #include "stm32f10x.h"  
  7.   
  8. void EXIT_init(void)  
  9. {  
  10.     EXTI_InitTypeDef EXTI_InitStruct;  
  11.     NVIC_InitTypeDef NVIC_InitStruct;  
  12.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);  
  13.       
  14.     //设置IO口与中断线的映射关系  
  15.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);//PC5  
  16.       
  17.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15);//PA15  
  18.       
  19.     //初始化线上中断,设置触发条件等  
  20.     //PC5--KEY0  
  21.     EXTI_InitStruct.EXTI_Line = EXTI_Line5;  
  22.     EXTI_InitStruct.EXTI_LineCmd = ENABLE;  
  23.     EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;//外部中断触发  
  24.     EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;  
  25.     EXTI_Init(&EXTI_InitStruct);  
  26.       
  27.     //PA15--KEY1  
  28.     EXTI_InitStruct.EXTI_Line = EXTI_Line15;  
  29.     EXTI_InitStruct.EXTI_LineCmd = ENABLE;  
  30.     EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;//外部中断触发  
  31.     EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;  
  32.     EXTI_Init(&EXTI_InitStruct);  
  33.       
  34.     //配置中断分组(NVIC),并使能中断  
  35.     //PC5  
  36.     NVIC_InitStruct.NVIC_IRQChannel = EXTI9_5_IRQn;  
  37.     NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;  
  38.     NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;  
  39.     NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;  
  40.     NVIC_Init(&NVIC_InitStruct);  
  41.       
  42.     //PA15  
  43.     NVIC_InitStruct.NVIC_IRQChannel = EXTI15_10_IRQn;  
  44.     NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;  
  45.     NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;  
  46.     NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;  
  47.     NVIC_Init(&NVIC_InitStruct);  
  48.   
  49. }  
  50.   
  51. //PC5中断服务函数  
  52. void EXTI9_5_IRQHandler(void)  
  53. {  
  54.     delay_ms(20);  
  55.     if(KEY0 == 0)//按下key0,就切换led状态  
  56.     {  
  57.         LED0 = ~LED0;  
  58.         LED1 = ~LED1;  
  59.         printf("\r\n press Key0 change the led! \r\n");  
  60.     }  
  61.     EXTI_ClearITPendingBit(EXTI_Line5);  
  62. }  
  63.   
  64. //PA15中断服务函数  
  65. void EXTI15_10_IRQHandler(void)  
  66. {  
  67.     delay_ms(20);  
  68.     if(KEY1 == 0)//按下key1,就切换led0的状态  
  69.     {  
  70.         LED0 = ~LED0;  
  71.         //LED1 = ~LED1;  
  72.         printf("\r\n press key1 change the led! \r\n");  
  73.     }  
  74.     EXTI_ClearITPendingBit(EXTI_Line15);  
  75. }  

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值