• 51单片机中断函数讲解及外部中断举例



    前言

    没有中断,程序就一直在主函数运行,实时性比较差,为了提高实时性,引入中断


    一、中断是什么?

    函数从主函数开始运行,被打断,进入中断服务函数,然后返回主函数

    1.只有一个中断

    在这里插入图片描述

    2. 什么东西可以中断?

    在这里插入图片描述

    3. 有两个中断?中断嵌套

    在这里插入图片描述

    4. 是否支持更多中断嵌套?

    AT89S51最多支持2个中断嵌套

    5. 中断响应过程?

    在这里插入图片描述

    在这里插入图片描述

    6. 中断服务函数

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

    7.寄存器

    在这里插入图片描述
    在这里插入图片描述
    // 低电平触发的时候,如果一直是低电平(按键一直按下),就一直触发中断函数,注意,不变高电平就一直中断
    //下降沿触发,按键按下一次,只触发一次

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    给1使能 ,0不使能(开关断开,无法触发中断)

    在这里插入图片描述

    二、外部中断实现

    1.中断配置

    • 1.1 确定有哪个引脚?
      因为只有两个外部中断, P3.2 外部中断0;P3.3外部中断1;
    • 1.2 使用什么触发方式?
      低电平,下降沿
    • 1.3 开启分开关
    • 1.4 开启总开关
    • 1.5 中断优先级
      高级或者低级
      PX0=1; 高级
      PX0=0;低级 默认就状态
    
    
    
    
    • 1
    • 2
    • 3

    2.参考程序

    代码如下(示例):

       #include 
       
       sbit led=P1^0;
       
       bit exit0_flag=1;
       
       void delay(unsigned int ms)
       {
    		unsigned int i,j;
    		for(i=0;i<ms;i++){
    			for(j=0;j<100;j++);
    		}
       }
       
       
       void ext0_init()
       {
       
    		IT0=0;//低电平
    		EX0=1;//外部中断0的分开关
    		EA=1;//总开关
    		PX0=0;// 低优先级
       }
       
       void main()
       {
    		unsigned char i;
    	   //中断初始化
    		ext0_init();
    		while(1)
    		{
    			if(exit0_flag){
    			
    				exit0_flag=0;
    				for(i=0;i<10;i++){
    					led=0;
    					delay(1000);
    					led=1;
    					delay(1000);
    				}
    
    			}
    			
    		}
       
       
       }
       
       //函数类型  函数名(形式参数表)interrupt n  using n 
    
       
       void  ext0() interrupt 0
       {  
    		// 点亮灯
    		//扫描按键
    		// 不建议逗留太久
    	   exit0_flag=1;
    	   
       }
       
    
    • 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

    3. 实验1

    验证 主函数和中断函数执行的过程,
    先主函数led=0;
    触发中断led=1;
    在返回主函数 led=0;

       #include 
       
       sbit led=P1^0;
       
       bit exit0_flag=1;
       
       void delay(unsigned int ms)
       {
    		unsigned int i,j;
    		for(i=0;i<ms;i++){
    			for(j=0;j<100;j++);
    		}
       }
       
       
       void ext0_init()
       {
       
    		IT0=0;//低电平
    		EX0=1;//外部中断0的分开关
    		EA=1;//总开关
    		PX0=0;// 低优先级
       }
       
       void main()
       {
    		unsigned char i;
    	   //中断初始化
    		ext0_init();
    		while(1)
    		{
    //			if(exit0_flag){
    //			
    //				exit0_flag=0;
    //				for(i=0;i<10;i++){
    //					led=0;
    //					delay(1000);
    //					led=1;
    //					delay(1000);
    //				}
    
    //			}
    			
    			led=0;
    			
    		}
       
       
       }
       
       //函数类型  函数名(形式参数表)interrupt n  using n 
    
       
       void  ext0() interrupt 0
       {  
    		// 点亮灯
    		//扫描按键
    		// 不建议逗留太久
    	   exit0_flag=1;
    	   led=1;
    	   delay(1000);
    	   
       }
       
    
    • 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

    4.实验2

    一般不在中断里面延时,太浪费资源了,放标志位,工程一般不放延时,实验为了看效果,会加延时。

    
       #include 
       
       sbit led=P1^0;
       
       bit exit0_flag=1;
       
       void delay(unsigned int ms)
       {
    		unsigned int i,j;
    		for(i=0;i<ms;i++){
    			for(j=0;j<100;j++);
    		}
       }
       
       
       void ext0_init()
       {
       
    		IT0=0;//低电平
    		EX0=1;//外部中断0的分开关
    		EA=1;//总开关
    		PX0=0;// 低优先级
       }
       
       void main()
       {
    		unsigned char i;
    	   //中断初始化
    		ext0_init();
    		while(1)
    		{
    			if(exit0_flag){
    			
    				exit0_flag=0;
    				for(i=0;i<10;i++){
    					led=0;
    					delay(1000);
    					led=1;
    					delay(1000);
    				}
    
    			}
    			
    			//led=0;
    			
    		}
       
       
       }
       
       //函数类型  函数名(形式参数表)interrupt n  using n 
    
       
       void  ext0() interrupt 0
       {  
    		// 点亮灯
    		//扫描按键
    		// 不建议逗留太久
    	   exit0_flag=1;
    //	   led=1;
    //	   delay(1000);
    	   
       }
       
    
    
    • 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

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

    总结

    1. 外部中断0,1分别触发中断,进入中断服务函数,函数里面点灯
    2. 实现外部中断0和中断1,同级中断触发
    3. 实现外部中断0和中断1,实现不同级中断触发,并实现中断嵌套
  • 相关阅读:
    ETL是什么
    [第一个 C# 程序]-C# 程序可以运行在任何一台可以打游戏的 Windows 机器上
    国产 Web 组态软件 TopStack V5.0 发布
    一张图搞定CSS选择器的优先级
    C++学习Day07之动态联编和静态联编
    AutoCAD Electrical 2022—项目中新建、添加、删除图纸
    javaweb学生竞赛管理系统
    使用IntelliJ Idea必备的插件!
    指针拔尖1——(看完包会,不会来打我)
    Java设计模式之迭代器模式
  • 原文地址:https://blog.csdn.net/ganhui13000/article/details/134118365