zoukankan      html  css  js  c++  java
  • STM32外部中断(实现按键控制LED)

    引言

    “中断” 这个概念,指的是在单片机运行过程中,在指定条件发生时,停下当前所有工作,去执行中断处理函数内的内容。就像我们在教室上课时,突然地震了,不出意外的话我们都需要停下手中学习任务,去进行一系列的避险动作。

    这一节我们通过中断的方式,完成通过按键控制LED亮灭的操作。




    准备环节

    中断相关知识

    STM32的中断控制器支持19个外部中断/事件请求。这十九个外部中断为:

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

    配置使用时,需要先将IO口与相应中断线的映射关系建立,再对其进行使用。那映射关系是怎样的呢?

    GPIOx.0 ~ GPIOx.15(x = A,B,C,D,E,F,G)分别对应中断线0 ~ 15

    配置GPIO与中断线关系的函数是 void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)

    eg:GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource2);

    把GPIO作为EXTI外部中断时,需要打开AFIO时钟。

    APIO时钟何时需要打开,具体可以参考这篇文章:

    STM32的AFIO时钟什么时候需要开启

    嵌套向量中断控制器(NVIC)

    初始化完线上中断和中断条件等内容,还需要配置中断分组。配置中断分组之前,我们需要先确定如何进行分组。这里就需要用到NVIC。

    关于NVIC的具体内容可查看这篇博文:嵌套向量中断控制器(NVIC)详解




    编码环节

    步骤

    • 初始化IO口输入
    • 开启AFIO时钟
    • 设置IO口与中断线的映射关系
    • 初始化线上中断、设置触发条件等
    • 配置中断分组,并使能中断
    • 编写中断服务函数

    main.c(以下内容均省略头文件)

    int main(void){
    	delay_init();
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//设置NVIC终端分组2
    	LED_Init();
    	KEY_Init();
    	EXTIX_Init();	//外部中断初始化
    	LED1 = 0;
    }
    
    

    exti.h

    #ifndef __EXTI_H
    #define __EXIT_H	 
    #include "sys.h"
    
    void EXTIX_Init(void);	//外部中断初始化
    
    #endif
    

    exti.c

    void EXTIX_Init(void)
    {
    
    	EXTI_InitTypeDef EXTI_InitStructure;	//外部中断结构体初始化
    	NVIC_InitTypeDef NVIC_InitStructure;	//中断分组结构体初始化
    
    	KEY_Init();
    
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);	//开启AFIO时钟
    
    	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);	//映射IO口与中断线
    	
        //以下为配置中断线初始化
    	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;		//中断模式
    	EXTI_InitStructure.EXTI_LineCmd = ENABLE;				//使能中断线
    	EXTI_InitStructure.EXTI_Line = EXTI_Line0;				//中断线标号
    	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;	//触发方式
    
    	EXTI_Init(&EXTI_InitStructure);
    
    	//以下为中断优先级的配置
    	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);
    }
    
    void EXTI0_IRQHandler(void)		//中断服务函数
    {
    	delay_ms(10);			//软件去抖
    	if(WK_UP==1)
    	{				 
    		LED0 = !LED0;
    		LED1 = !LED1;
    	}
    	EXTI_ClearITPendingBit(EXTI_Line0);		//清除中断位
    }
    
    



    补充

    中断服务函数

    中断服务函数的名称是固定的,写错会导致无法中断。

    STM32的IO口外部中断函数只有六个。分别为:

    • EXTI0_IRQHandler
    • EXTI1_IRQHandler
    • EXTI2_IRQHandler
    • EXTI3_IRQHandler
    • EXTI4_IRQHandler
    • EXTI9_5_IRQHandler
    • EXTI15_10_IRQHandler

    中断线0 ~ 4各对应一个中断服务函数,中断线5 ~ 9共用 EXTI9_5_IRQHandler,中断线10 ~ 15共用 EXTI15_10_IRQHandler

    中断服务函数常规格式

    void EXTI3_IRQHandler(void)
    {
    	if(EXTI_GetITStatus(EXTI_Line3)!=RESET)		//判断中断线上的中断是否发生
    	{
    		//这里写需要执行的服务
    		EXTI_ClearITPendingBit(EXTI_Line3);		//清除中断标志位
    	}
    }
    
    
    我是这耀眼的瞬间,是划过天边的刹那火焰。
  • 相关阅读:
    课堂作业04 2017.10.27
    课程作业 03 动手动脑 2017.10.20
    课程作业 03 2017.10.20
    HDU 3974 Assign the task
    POJ 2155 Matrix
    POJ 2481 Cows
    HDU 3038 How Many Answers Are Wrong
    CS Academy Array Removal
    POJ_1330 Nearest Common Ancestors LCA
    CF Round 427 D. Palindromic characteristics
  • 原文地址:https://www.cnblogs.com/Rane/p/13601097.html
Copyright © 2011-2022 走看看