STM32基于固件库学习笔记(2)外部中断

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_43993734/article/details/101222798

按键KEY中断方式控制LED

中断固件库 stm32f10x_exti.h 和 stm32f10x_exti.c

STM32 的每个 IO 都可以作为外部中断的中断输入口,这点也是 STM32 的强大之处。STM32F103 的中断控制器支持 19 个外部中断事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F103 的19 个外部中断为:

  • 线 0~15:对应外部 IO 口的输入中断。
  • 线 16:连接到 PVD 输出。
  • 线 17:连接到 RTC 闹钟事件。
  • 线 18:连接到 USB 唤醒事件。

GPIO 的管教 GPIOx.0~GPIOx.15(x=A,B,C,D,E,F,G)分别对应中断线 0-15(GPIO 和中断线的映射关系图) GPIO 和中断线的映射关系图

使用 IO 口外部中断的一般步骤:

1)初始化 IO 口为输入。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO,ENABLE);
//这里PGIO不只是作为普通输入输出、还要作为中断,需挂载RCC_APB2Periph_AFIO
//配置key 
  GPIO_InitTypeDef GPIO_InitTypeDef_PE4 ;
  GPIO_InitTypeDef_PE4 .GPIO_Pin = GPIO_Pin_4;//PE4 
  GPIO_InitTypeDef_PE4 .GPIO_Mode = GPIO_Mode_IPU;//上拉输入 
  GPIO_Init(GPIOE,&GPIO_InitTypeDef_PE4 )

2)开启 IO 口复用时钟,设置 IO 口与中断线的映射关系。

  void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
  /*
     GPIO_PortSource 为GPIO_PortSourceGPIO(A-G) 
     GPIO_PinSource   为GPIO_PinSource(0-15)
     具体那个端口怎么配置得看上图(GPIO 和中断线的映射关系图):
      比如是PA5    1. GPIO_PortSource为GPIO_PortSourceGPIOA   
                  2. GPIO_PinSource为GPIO_PinSource5
   */

3)初始化线上中断,设置触发条件等。

  //外部i/o中断配置
  EXTI_InitTypeDef EXTI_ITDef;
  //该函数将 GPIO 端口与中断线映射起来
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
  EXTI_ITDef.EXTI_Line = EXTI_Line4;
  EXTI_ITDef.EXTI_Mode = EXTI_Mode_Interrupt;//设置 EXTI 线路为中断请求
  EXTI_ITDef.EXTI_Trigger=EXTI_Trigger_Falling;//设置输入线路下降沿为中断请求
  EXTI_ITDef.EXTI_LineCmd = ENABLE;//定义选中线路的新状态
  EXTI_Init(&EXTI_ITDef);
  

4)配置中断分组(NVIC),并使能中断。

 //中断管理NVIC
  NVIC_InitTypeDef  NVIC_ITDef;
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 
  NVIC_ITDef.NVIC_IRQChannel = EXTI4_IRQn;//使能按键外部中断通道
  NVIC_ITDef.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2
  NVIC_ITDef.NVIC_IRQChannelSubPriority = 0x00;//子优先级 2
  NVIC_ITDef.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
  NVIC_Init(&NVIC_ITDef);

5)编写中断服务函数。

//常用的中断服务函数格式为:
void EXTI2_IRQHandler(void)
 {
    if(EXTI_GetITStatus(EXTI_Line3)!=RESET)//判断某个线上的中断是否发生
    {
       //中断逻辑…
       EXTI_ClearITPendingBit(EXTI_Line3); //清除 LINE 上的中断标志位
   }
 }

KEY(PE4)中断方式控制LED(PB5)代码

#include "stm32f10x.h"
void LED_Ioinit(void)
{
  //挂载PE5到时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); 
  GPIO_InitTypeDef GPIO_ITYPD;
  GPIO_ITYPD.GPIO_Pin=GPIO_Pin_5;//端口
  GPIO_ITYPD.GPIO_Mode=GPIO_Mode_Out_PP;//模式
  GPIO_ITYPD.GPIO_Speed=GPIO_Speed_2MHz;//速度 
  GPIO_Init(GPIOE,&GPIO_ITYPD);//设置PB5

  GPIO_SetBits(GPIOE,GPIO_Pin_5); //BSRR  1
//GPIO_ResetBits(GPIOE,GPIO_Pin_5); //BRR  0
}
void EXTI_Init_k0(void)
{
  //外部i/o中断配置
  EXTI_InitTypeDef EXTI_ITDef;
  //该函数将 GPIO 端口与中断线映射起来
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
  EXTI_ITDef.EXTI_Line = EXTI_Line4;
  EXTI_ITDef.EXTI_Mode = EXTI_Mode_Interrupt;//设置 EXTI 线路为中断请求
  EXTI_ITDef.EXTI_Trigger=EXTI_Trigger_Falling;//设置输入线路下降沿为中断请求
  EXTI_ITDef.EXTI_LineCmd = ENABLE;//定义选中线路的新状态
  EXTI_Init(&EXTI_ITDef);
  
  //中断管理NVIC
  NVIC_InitTypeDef NVIC_ITDef;
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 
  NVIC_ITDef.NVIC_IRQChannel = EXTI4_IRQn;//使能按键外部中断通道
  NVIC_ITDef.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2
  NVIC_ITDef.NVIC_IRQChannelSubPriority = 0x00;//子优先级 2
  NVIC_ITDef.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
  NVIC_Init(&NVIC_ITDef);
}
void delay_ms(u16 time)
{    
   u16 i = 0;  
   while(time--)
   {
      i = 12000;  
      while(i--);    
   }
}
void delay_us(u16 time)
{    
   u16 i = 0;  
   while(time--)
   {
      i=10;  
      while(i--);    
   }
}
void KEY_Init(void)
{
  //配置PE时钟         //配置复用时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO,ENABLE);
   //配置key
  GPIO_InitTypeDef GPIO_ITYPD1;
  GPIO_ITYPD1.GPIO_Pin = GPIO_Pin_4;
  GPIO_ITYPD1.GPIO_Mode = GPIO_Mode_IPU;//上拉输入 
  GPIO_Init(GPIOE,&GPIO_ITYPD1);
  
}
//外部中断 4 的服务函数,负责 KEY 按键的中断检测;
void EXTI4_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line4)!=RESET)//判断某个线上的中断是否发生
   {
     delay_ms(15);       
     if(!(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)))//0X00
     {
       if(GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_5))//0X01
       {
         GPIO_ResetBits(GPIOE,GPIO_Pin_5); //BRR  0
       }else 
       {
         GPIO_SetBits(GPIOE,GPIO_Pin_5);  //BSRR  1       
       }
     }    
    EXTI_ClearITPendingBit(EXTI_Line4);
   }
}
int main(void)
{
  while(1);  
}

相关文档

STM32F10x_StdPeriph_Lib_V3.5.0(官方固件库)
链接:STM32固件库使用手册的中文翻译版 提取码:4lkx

猜你喜欢

转载自blog.csdn.net/weixin_43993734/article/details/101222798