打印
[STM32F1]

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

[复制链接]
510|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
硬件如下:

1.中断的基本知识点
STM32F103ZET6有112个基本的GPIO口都可以用来做外部中断的中断输入口。
STM32F103 的中断控制器支持 19 个外部中断/事件请求,具体如下:
线 0~15:对应外部 IO 口的输入中断。
线 16:连接到 PVD 输出。
线 17:连接到 RTC 闹钟事件。
线 18:连接到 USB 唤醒事件。
STM32 供 IO 口使用的中断线只有 16 个,要分配给112个IO口,分配关系如下:

2.编写代码
2.1时钟使能,AFIO时钟使能,GPIO初始化
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE, ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);        //开启AFIO 时钟        
        GPIO_InitTypeDef  GPIO_InitStructure;
        
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //设置为下拉输入
        GPIO_Init(GPIOA, &GPIO_InitStructure);

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

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

//外部中断2服务程序
void EXTI2_IRQHandler(void)
{
        delay_ms(10);//消抖        
        if(PE2==0)                  
        {                                 
                LED1=~LED1;        
        }
        EXTI_ClearITPendingBit(EXTI_Line2);  //清除LINE2上的中断标志位  
}

//外部中断3服务程序
void EXTI3_IRQHandler(void)
{
        delay_ms(10);//消抖        
        if(PE3==0)                  
        {                                 
                LED0=~LED0;        
        }
        EXTI_ClearITPendingBit(EXTI_Line3);  
}

//外部中断4服务程序
void EXTI4_IRQHandler(void)
{
        delay_ms(10);//消抖        
        if(PE4==0)                  
        {                                 
                LED1=~LED1;        
                LED0=~LED0;
        }
        EXTI_ClearITPendingBit(EXTI_Line4);   
}
2.5主函数
 int main(void)
{                 
        delay_init();                     //延时函数初始化         
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
         LED_Init();                                  //初始化与LED连接的硬件接口
        EXTIX_Init();                         //外部中断初始化
        LED0=0;                                        //点亮LED0
        LED1=0;
        while(1)
        {
               
        }
}
实验现象: 初始化LED0,LED1均点亮; 按下KEY0,LED0,LED1翻转 按下KEY1,LED0翻转 按下KEY2,LED1翻转 按下KEY_UP,LED0,LED1都熄灭

使用特权

评论回复
沙发
richard345| | 2021-4-22 15:19 | 只看该作者
请问我用外部中断捕获输入脉冲的上升沿时, 为什么会有丢失的现象 。脉冲信号大概是155ms的样子

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

227

主题

578

帖子

6

粉丝