32学习之中断 外部中断 按键控制流水灯不同速度

GPIO引脚复用和映射:IO口通过一个复用器连接到内置外设和模块;复用器一次只允许一个外设的复用功能(AF)连接到对应的IO口。这样可以确保共用同一个IO引脚的外设之间不会发生冲突;每个IO引脚都有一个复用器

端口复用为复用功能配置过程:

  ①GPIO端口时钟使能。

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);

   ②复用外设时钟使能。

     比如你要将端口PA9,PA10复用为串口,所以要使能串口时钟。

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

  ③端口模式配置为复用功能。 GPIO_Init()函数。

   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能

 ④配置GPIOx_AFRL或者GPIOx_AFRH寄存器,将IO连接到所需的AFx。

 

IO口作为复用功能时查表寻找对应功能

NVIC中断优先级分组

中断管理方法:首先分组,设置抢占优先级,响应优先级

抢占优先级 & 响应优先级区别:

1.高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。

2.抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。

3.抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。

4.如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;

中断分组在程序中只设置一次!!!

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

中断优先级设置步骤

系统运行后先设置中断优先级分组。调用函数:

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);

 整个系统执行过程中,只设置一次中断分组。

②针对每个中断,设置对应的抢占优先级和响应优先级:

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);

③ 如果需要挂起/解挂,查看中断当前激活状态,分别调用相关函数即可。

外部中断

STM32F4的每个IO都可以作为外部中断输入。

每个外部中断线可以独立的配置触发方式(上升沿,下降沿或者双边沿触发),触发/屏蔽,专用的状态位。

中断服务函数列表:

EXTI0_IRQHandler           

EXTI1_IRQHandler

EXTI2_IRQHandler           

EXTI3_IRQHandler           

EXTI4_IRQHandler           

EXTI9_5_IRQHandler         

EXTI15_10_IRQHandler  

外部中断常用库函数

void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex);

   //设置IO口与中断线的映射关系

void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);

 //初始化中断线:触发方式等

ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);

//判断中断线中断状态,是否发生

void EXTI_ClearITPendingBit(uint32_t EXTI_Line);

//清除中断线上的中断标志位

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟

//这个函数非常重要,在使用外部中断的时候一定要先使能SYSCFG时钟

外部中断的一般配置步骤:

1使能SYSCFG时钟:  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

2初始化IO口为输入 GPIO_Init();

3设置IO口与中断线的映射关系 void SYSCFG_EXTILineConfig();

4初始化线上中断,设置触发条件等 EXTI_Init();

5配置中断分组(NVIC),并使能中断 NVIC_Init();

6编写中断服务函数。EXTIx_IRQHandler();

7清除中断标志位EXTI_ClearITPendingBit();

利用外部中断,我写了一个按键控制流水灯速度的程序:

#include"delay.h"

#include"led.h"

#include"key.h"

#include"exit.h"

#include"sys.h"

#include"fmq.h"

 

 

 

void EXITX_Init(void)

{

 NVIC_InitTypeDef  NVIC_InitStructure;

 EXTI_InitTypeDef EXTI_InitStructure;

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG ,ENABLE);

 KEY_Init();

 SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource2);

 SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE,EXTI_PinSource3);

 EXTI_InitStructure.EXTI_Line=EXTI_Line2|EXTI_Line3;

   EXTI_InitStructure.EXTI_LineCmd=ENABLE;

 EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;

 EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;

 EXTI_Init(&EXTI_InitStructure);

 NVIC_InitStructure.NVIC_IRQChannel=EXTI2_IRQn;

 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;

 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;

 NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;

 NVIC_Init(&NVIC_InitStructure);

 

 NVIC_InitStructure.NVIC_IRQChannel=EXTI3_IRQn;

 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;

 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;

 NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;

 NVIC_Init(&NVIC_InitStructure);

}

 

 

void EXTI2_IRQHandler(void)

{

   delay_ms(10);

 if(KEY0==0)

 {

 while(1)

 {

     GPIO_SetBits(GPIOF,GPIO_Pin_9);

   delay_ms(500);

   GPIO_ResetBits(GPIOF,GPIO_Pin_9);

   delay_ms(500);

   GPIO_SetBits(GPIOF,GPIO_Pin_10);

   delay_ms(500);

   GPIO_ResetBits(GPIOF,GPIO_Pin_10);

   delay_ms(500);

 }

 }

  EXTI_ClearITPendingBit(EXTI_Line2);

}

 

void EXTI3_IRQHandler(void)

{

   delay_ms(10);

 if(KEY1==0)

 {

  while(1)

{

    GPIO_SetBits(GPIOF,GPIO_Pin_9);

  delay_ms(20);

  GPIO_ResetBits(GPIOF,GPIO_Pin_9);

  delay_ms(20);

  GPIO_SetBits(GPIOF,GPIO_Pin_10);

  delay_ms(20);

  GPIO_ResetBits(GPIOF,GPIO_Pin_10);

  delay_ms(20);

}

 }

  EXTI_ClearITPendingBit(EXTI_Line2);

}

 

 

你可能感兴趣的:(32学习之中断 外部中断 按键控制流水灯不同速度)