• STM32外部中断


    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


    前言

    提示:这里可以添加本文要记录的大概内容:

    例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


    提示:以下是本篇文章正文内容,下面案例可供参考

    一、STM32的外部中断特性?

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    二、使用步骤

    0. 开启时钟,用一个外设就要开启一个外设的时钟

    在这里插入图片描述
    在这里插入图片描述

    1.配置GPIO

    PC5
    首先:
    1.外部中断是输入,按照按键输入来配置就可以了

    GPIO_InitStruct.GPIO_Pin=  GPIO_Pin_5;
    GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;	  //KEY   因为按键按下是0,所以松开应该是1 以此使用上拉
    
    GPIO_Init(GPIOC, &GPIO_InitStruct);   //&x     PC5
    
    • 1
    • 2
    • 3
    • 4
    • 5

    然后
    2.如何将引脚跟外部中断线连起来,要跟外部中断5,EXTI5
    在这里插入图片描述

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource5);    //pc5-EXTI5
    
    • 1

    2.配置中断

    3.外部中断配置,边沿检测,中断使能,事件、
    在这里插入图片描述

    在这里插入图片描述

    //2.中断配置
    EXTI_InitStruct.EXTI_Line= EXTI_Line5;  //  EXTI_Linex
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    EXTI_InitStruct.EXTI_Mode= EXTI_Mode_Interrupt;
    EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
    
    EXTI_Init( &EXTI_InitStruct);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3.中断管理

    4.中断管理

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    
    NVIC_InitStruct.NVIC_IRQChannel =  EXTI9_5_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelCmd  =  ENABLE;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority= 0; //0-3
    NVIC_InitStruct.NVIC_IRQChannelSubPriority  = 0;    // 0-3
    
    NVIC_Init(&NVIC_InitStruct);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);再加中断不用加分组整个32就用一个分组
    
    NVIC_InitStruct.NVIC_IRQChannel =  EXTI0_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelCmd  =  ENABLE;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority= 1; //0-3
    NVIC_InitStruct.NVIC_IRQChannelSubPriority  = 0;    // 0-3
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    1.抢占优先级和响应优先级一样时,看中断向量表,谁在前面就先执行谁
    2.中断1:抢占优先级0,响应是1。中断2:抢占优先级1,响应是1。

    • 两个中断同时来。执行中断1(0是最高优先级)。
    • 中断2在运行,中断1后来? 挂起中断2,执行中断1,看抢占优先级(响应优先级不用看),高抢占优先级可以打断正在执行的低抢占优先级。

    响应优先级有什么用?
    3. 中断1:抢占优先级0响应是1。中断2:抢占优先级0响应是0

    • 如果同时来,中断2,抢占一样时,看响应。
    • 不是同时来, 中断2在执行,这是中断1来?执行中断2.为什么?能不能抢断看抢占优先级

    4.中断函数

    5.中断函数

    在这里插入图片描述

    void EXTI9_5_IRQHandler()
    {
            if(EXTI_GetITStatus(EXTI_Line5)==SET)   //判断是否是外部中断5
    		{
    		
    		     EXTI_ClearITPendingBit(EXTI_Line5) ; //清楚外部中断5的标准,
    		
    		}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    5.如何写代码

    代码如下(示例):

    
    #include "stm32f10x.h"
    //全局
    
     GPIO_InitTypeDef GPIO_InitStruct;
     NVIC_InitTypeDef NVIC_InitStruct;
     EXTI_InitTypeDef EXTI_InitStruct;
     
     int x;
     
    
    int main()
    {
     
    // 3.中断管理	
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    	
    	NVIC_InitStruct.NVIC_IRQChannel =  EXTI9_5_IRQn;
    	NVIC_InitStruct.NVIC_IRQChannelCmd  =  ENABLE;
    	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority= 0; //0-3
    	NVIC_InitStruct.NVIC_IRQChannelSubPriority  = 0;    // 0-3
    	
    	NVIC_Init(&NVIC_InitStruct);
    
    	NVIC_InitStruct.NVIC_IRQChannel =  EXTI0_IRQn;
    	NVIC_InitStruct.NVIC_IRQChannelCmd  =  ENABLE;
    	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority= 1; //0-3
    	NVIC_InitStruct.NVIC_IRQChannelSubPriority  = 0;    // 0-3
    	
    	NVIC_Init(&NVIC_InitStruct);
    	
    	
    	
    /*
    key PC5
    LED PA8 	
    	
    */
    //局部	
    	// 库函数开启GPIO时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);
    	
    	GPIO_InitStruct.GPIO_Pin=  GPIO_Pin_8;
    	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
    	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;    //LED
    		
    	GPIO_Init(GPIOA, &GPIO_InitStruct);   //&x  PA8
    	
    	
    	
    	GPIO_InitStruct.GPIO_Pin=  GPIO_Pin_2|GPIO_Pin_3;
    	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
    	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;	
    	
    	GPIO_Init(GPIOB, &GPIO_InitStruct);   //&x 
    	
    
    	
    
    // 1.配置GPIO
    	GPIO_InitStruct.GPIO_Pin=  GPIO_Pin_5|GPIO_Pin_0;
    	GPIO_InitStruct.GPIO_Speed= GPIO_Speed_50MHz;
    	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;	  //KEY   因为按键按下是0,所以松开应该是1 以此使用上拉
    	
    	GPIO_Init(GPIOC, &GPIO_InitStruct);   //&x     PC5
    	
    	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource5);   
    	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource0);   //pc5-EXTI5
    
    	
    	//2.中断配置
    	EXTI_InitStruct.EXTI_Line= EXTI_Line5|EXTI_Line0;  //  EXTI_Linex
    	EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    	EXTI_InitStruct.EXTI_Mode= EXTI_Mode_Interrupt;
    	EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
    
    	EXTI_Init( &EXTI_InitStruct);
    	
    	
    
    	while(1)
    	{
    					
    		//if(GPIOC.5==0)
    		if(GPIO_ReadInputDataBit( GPIOC, GPIO_Pin_5))	   // 上拉 按键按下 0 反之1  
    		{
    		
    		     GPIO_SetBits(GPIOA, GPIO_Pin_0);         //灭
    		
    		}
    		else{
    		
    			 	GPIO_ResetBits(GPIOA, GPIO_Pin_0);         //按下亮
    		}	
    	
    	}
    }
    
    
    //4.中断函数 高优先级
    void EXTI9_5_IRQHandler()
    {
            if(EXTI_GetITStatus(EXTI_Line5)==SET)   //判断是否是外部中断5
    		{
    		
    		     EXTI_ClearITPendingBit(EXTI_Line5) ; //清楚外部中断5的标准,
    		
    		}
    
    }
    
    
    //4.中断函数  低优先级
    void EXTI0_IRQHandler()
    {
            if(EXTI_GetITStatus(EXTI_Line0)==SET)   //判断是否是外部中断5
    		{
    		
    		     EXTI_ClearITPendingBit(EXTI_Line0) ; //清楚外部中断5的标准,
    		
    		}
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124

    中断嵌套

    • 触发低优先级中断进入中断服务函数 void EXTI0_IRQHandler()
    • 触发高优先级中断,进入中断服务函数EXTI9_5_IRQHandler(),打断正在执行的低优先级中断函数,挂起?还没执行完?等
    • 等高优先级中断执行完毕,再回来执行
    • 最后返回主函数 main( ) while(1){}

    三、验证实验

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述

    2. 嵌套验证的想法

    000 主函数 灭
    001 最低
    010 中
    100 高

    显示效果

    1. 一开始 000
    2. 触发最低中断 001 用for循环(1000)加延时 001
    3. 触发中中断 010 用for循环(1000)加延时
    4. 触发高中断 100
    5. 自己回到 010
    6. 自己回到 001
    7. 自己回到 000

    举例子:
    //4.中断函数 低优先级
    void EXTI0_IRQHandler()
    {
    if(EXTI_GetITStatus(EXTI_Line0)==SET) //判断是否是外部中断5
    {

    	     EXTI_ClearITPendingBit(EXTI_Line0) ; //清楚外部中断5的标准,
    			for(i=0;i<1000;i++)   // i=100 
    			{
    						001;//一直给001
    					delay();//用自己写的软件延时,不要硬件延时,否则中断嵌套回不去
    			}
    	
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    }

    总结

    以上已经完成了,一个外部中断触发,思考如何完成三个按键的中断嵌套及验证。

    要求:
    三个按键,三个优先级,实现中断嵌套,用三个led灯显示效果
    注意:中断里面要用自己写的软件延时,不要用硬件延时,就是各种开发板给的资料中的硬件延时函数

  • 相关阅读:
    c++视觉--通道分离,合并处理,在分离的通道中的ROI感兴趣区域里添加logo图片
    MySQL 数据表操作
    基础生态学终结版复习题
    haskell 基本布局和组成元素
    代码随想录算法训练营第五十二天| LeetCode1035.不相交的线、583. 两个字符串的删除操作、72. 编辑距离
    AntDesignVue之a-table中key不唯一问题处理的多种方式
    JavaSE进阶、多线程
    关于seata启动时连接数据库异常,Mysql版本8.0
    [springboot源码分析]-Conditional
    VMware 中 Centos7 安装 Hyperledge Fabric v2.4.4 测试网络
  • 原文地址:https://blog.csdn.net/ganhui13000/article/details/133876161