[STM32F1] STM32F103ZET6【标准库函数开发】---外部中断

[复制链接]
768|1
 楼主| 王小琪 发表于 2020-11-4 20:13 | 显示全部楼层 |阅读模式
硬件如下:
858125fa29a63a14d9.png
1.中断的基本知识点
STM32F103ZET6有112个基本的GPIO口都可以用来做外部中断的中断输入口。
STM32F103 的中断控制器支持 19 个外部中断/事件请求,具体如下:
线 0~15:对应外部 IO 口的输入中断。
线 16:连接到 PVD 输出。
线 17:连接到 RTC 闹钟事件。
线 18:连接到 USB 唤醒事件。
STM32 供 IO 口使用的中断线只有 16 个,要分配给112个IO口,分配关系如下:
286695fa29a4385d47.png
2.编写代码
2.1时钟使能,AFIO时钟使能,GPIO初始化
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE, ENABLE);
  2.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);        //开启AFIO 时钟        
  3.         GPIO_InitTypeDef  GPIO_InitStructure;
  4.         
  5.         GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;
  6.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //设置为下拉输入
  7.         GPIO_Init(GPIOA, &GPIO_InitStructure);

  8.         GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
  9.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //PE2 3 4设置成上拉输入
  10.         GPIO_Init(GPIOE, &GPIO_InitStructure);
2.2PA0,PE2,PE3,PE4与中断线映射起来
  1. GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0); //PA.0口与中断线EXTI0映射起来
  2.         //中断线初始化
  3.           EXTI_InitStructure.EXTI_Line=EXTI_Line0;
  4.         EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;        
  5.           EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//触发模式:上升沿
  6.         EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  7.           EXTI_Init(&EXTI_InitStructure);               
  8.         
  9. GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);
  10.                 //中断线初始化
  11.           EXTI_InitStructure.EXTI_Line=EXTI_Line2;//PE.2口与中断线EXTI2映射起来        
  12.           EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;        
  13.           EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//触发模式:下降沿
  14.           EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  15.           EXTI_Init(&EXTI_InitStructure);                 

  16. GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
  17.                 //中断线初始化
  18.           EXTI_InitStructure.EXTI_Line=EXTI_Line3;//PE.3口与中断线EXTI3映射起来        
  19.           EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;        
  20.           EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//触发模式:下降沿
  21.           EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  22.           EXTI_Init(&EXTI_InitStructure);        
  23.         
  24. GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
  25.                 //中断线初始化
  26.           EXTI_InitStructure.EXTI_Line=EXTI_Line4;//PE.4口与中断线EXTI4映射起来        
  27.           EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;        
  28.           EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//触发模式:下降沿
  29.           EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  30.           EXTI_Init(&EXTI_InitStructure);
2.3设置四个中断线的中断优先级
  1. NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;                        //使能按键外部中断通道
  2.           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;//抢占优先级2,
  3.           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;                //子优先级3
  4.           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                //使能外部中断通道
  5.           NVIC_Init(&NVIC_InitStructure);
  6.         
  7.         NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;                        //使能按键外部中断通道
  8.           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;//抢占优先级2,
  9.           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;                //子优先级2
  10.           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                //使能外部中断通道
  11.           NVIC_Init(&NVIC_InitStructure);
  12.         
  13.         NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;                        
  14.           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03; //抢占优先级3,
  15.           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;                //抢占优先级3,
  16.           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                
  17.           NVIC_Init(&NVIC_InitStructure);
  18.         
  19.         NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;                        
  20.           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;//抢占优先级3,
  21.           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;                //抢占优先级4,
  22.           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                
  23.           NVIC_Init(&NVIC_InitStructure);
2.4编写外部中断服务函数
  1. //外部中断0服务程序
  2. void EXTI0_IRQHandler(void)
  3. {
  4.         delay_ms(10);//消抖
  5.         if(PA0==1)                  //WK_UP按键
  6.         {                                 
  7.                 LED1=1;
  8.                 LED0=1;        
  9.         }
  10.         EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中断标志位  
  11. }

  12. //外部中断2服务程序
  13. void EXTI2_IRQHandler(void)
  14. {
  15.         delay_ms(10);//消抖        
  16.         if(PE2==0)                  
  17.         {                                 
  18.                 LED1=~LED1;        
  19.         }
  20.         EXTI_ClearITPendingBit(EXTI_Line2);  //清除LINE2上的中断标志位  
  21. }

  22. //外部中断3服务程序
  23. void EXTI3_IRQHandler(void)
  24. {
  25.         delay_ms(10);//消抖        
  26.         if(PE3==0)                  
  27.         {                                 
  28.                 LED0=~LED0;        
  29.         }
  30.         EXTI_ClearITPendingBit(EXTI_Line3);  
  31. }

  32. //外部中断4服务程序
  33. void EXTI4_IRQHandler(void)
  34. {
  35.         delay_ms(10);//消抖        
  36.         if(PE4==0)                  
  37.         {                                 
  38.                 LED1=~LED1;        
  39.                 LED0=~LED0;
  40.         }
  41.         EXTI_ClearITPendingBit(EXTI_Line4);   
  42. }
2.5主函数
  1. int main(void)
  2. {                 
  3.         delay_init();                     //延时函数初始化         
  4.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
  5.          LED_Init();                                  //初始化与LED连接的硬件接口
  6.         EXTIX_Init();                         //外部中断初始化
  7.         LED0=0;                                        //点亮LED0
  8.         LED1=0;
  9.         while(1)
  10.         {
  11.                
  12.         }
  13. }
实验现象: 初始化LED0,LED1均点亮; 按下KEY0,LED0,LED1翻转 按下KEY1,LED0翻转 按下KEY2,LED1翻转 按下KEY_UP,LED0,LED1都熄灭
richard345 发表于 2021-4-22 15:19 | 显示全部楼层
请问我用外部中断捕获输入脉冲的上升沿时, 为什么会有丢失的现象 。脉冲信号大概是155ms的样子
您需要登录后才可以回帖 登录 | 注册

本版积分规则

232

主题

585

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部