精华内容
下载资源
问答
  • 外部中断源2个 1.INT0 — 由P3.2端口控制引入,低水平或者下降沿引起。(下降沿就是给5V后给0V形成下降电压) 2.INT1 —由P3.3端口控制引入,低水平或者下降沿引起。 (这两个中断源标志与中断方式由特殊功能寄存器...

    1.解释
    计算机执行某一程序时,发生了紧急事件或者有特殊请求,CPU暂停某程序的执行,转而去处理上述事件,处理完毕后再重新执行原来被打断的程序。
    2.步骤
    中断请求>中断响应>中断处理>中断返回
    请添加图片描述
    3.51的中断源
    有五个中断源
    外部中断源2个
    1.INT0 — 由P3.2端口控制引入,低水平或者下降沿引起。(下降沿就是给5V后给0V形成下降电压)
    2.INT1 —由P3.3端口控制引入,低水平或者下降沿引起。
    (这两个中断源标志与中断方式由特殊功能寄存器TCON的低四位控制)
    内部中断源3个
    1.T0 —定时器/计数器0中断,由T0回0溢出引起。
    2.T1 —定时器/计数器1中断,由T1回0溢出引起。
    3.T1/RI —串行I/O口中断,串行端口完成一帧字符发送引起。
    (由TCON和SCON控制)
    4.51内部结构图
    请添加图片描述

    要运用那个中断就要打开对应的开关,首先EA(总开关)要打开,假设要打开外部中断0,就需要再控制IT0与EX0与PX0。
    5.如何使用中断
    (1.打开对应的中断开关)
    EA —总开关,EA打开CPU接受中断请求;EA关闭,CPU屏蔽任何中断请求。
    外部中断开关
    EX1 —EX1打开,外部中断1打开,反之。
    EX0 —EX0打开,外部中断0打开,反之。
    内部中断打开
    ET0打开,T0的溢出中断打开,反之。
    ET1 —ET1打开,T1的定时器/计数器溢出中断打开,反之。
    ET2 —ET2打开,T2的定时器/计数器溢出中断打开,反之。
    ES —ES打开,串行口一中断打开,反之。请添加图片描述
    也可以按上表,8位2进制赋予IE打开对应开关。
    (2.配置中断方式(触发对应中断的条件))
    外部中断方式控制
    IT0 —IT0为1,为下降沿触发方式。TT0为1,低电平触发方式。(控制在3.2脚)
    IT1 —IT1为1,为下降沿触发方式。TT1为1,低电平触发方式。(控制在3.3脚)
    内部中断方式控制
    TR1 —定时器1的运行控制位。
    TR0 —定时器0的运行控制位。
    TF0 —T0溢出中断标志,TO被允许开始计数时,从初值加一开始运算,当溢出时,硬件自动命TF0为1,引发T0中断,当执行完,硬件自动清0。
    TF1—T1溢出中断标志,T1被允许开始计数时,从初值加一开始运算,当溢出时,硬件自动命TF1为1,引发T1中断,当执行完,硬件自动清0。

    内部中断模式位
    请添加图片描述
    请添加图片描述
    想要打开内部中断0与1什么模式就命对应TMOD为什么值,如果我需要定时器0的定时功能,TMOD=0000 0001=0x01。如果需要定时器0计数,需要把C/T打开,就是TMOD=00000101=0x05。

    (3.触发优先级)
    当多个中断同时发生,按下面顺序
    注意:优先级高的中断可以打断优先级低的中断
    请添加图片描述
    (4.中断处理函数)
    请添加图片描述
    步骤总结
    1.打开对应的中断开关
    2.控制对应中断执行的条件
    3.写中断函数

    以下是各个中断的函数示例(4个)

    外部中断1函数实例(外部中断0同样是这样用)

    #include "reg52.h"			 
    sbit key1=P3^1;	    
    sbit flag = P3^3;
    void delay(unsigned int i)
    {
    	while(i--);	
    }
    void lnt1init()
    {
    	EA = 1;          //总开关打开
    	EX1 = 1;          //外部中断开关打开
    	IT1 = 1;          //触发方式(下降沿)
    }
    void int1() interrupt 2  //外部中断函数,interrupt后面的数字根据优先级那个图有个入口数字
    {
    	P2 = ~P2;       //由亮变无或由无变亮
    }
    void keypros()
    {
    	if(key1==0)		 //独立按键被按下
    	{	   
    		delay(100);
    		if(key1==0)	  //按键消抖
    		{
    			   flag = 1;//产生下降沿,就会进入到中断函数
    		       flag = 0;
    			  while(!key1);   //松手检测
    		} 
    	}		
    }
    
    void main()
    {	
    	lnt1init();
    	P2 = 0x00;    //先取全部亮
    	while(1)
    	{	
    		keypros(); 	
    	}		
    }
    

    内部中断0的软件中断(用作计时器)
    注意这里不是中断函数的使用,而是运用定时器0,故它的函数开关不需要打开

    #include "reg52.h"			 
    sbit LA=P2^2;
    sbit LB=P2^3;
    sbit LC=P2^4;
    sbit  key2 = P3^0; 
    unsigned char smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
    					0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
    void delay(unsigned int z)    
    {
    	unsigned int x,y;
    	for(x=z;x>0;x--)
    	   for(y=120;y>0;y--);
    }
    void timefrist()
    {
    	TR0 = 1;                 //打开定时器0开关
    	TMOD = 0x01;             //定义模式
    	TH0 = 0x4B;              //定义初始值后不断加1,每加1为1.085us,从到19453到65535共46085次,共50ms
    	TL0 = 0xfd;              //前面那个值为19453的16进制的前2位,这个为它的后2位。19453 = 4Bfd
    }
    unsigned char miao=0;        //秒
    unsigned char fen=0;         //分
    void DigDisplay()
    {
    	LA=1;LB=1;LC=1;        //位选,这里用的是转码器3个2进制可以控制8个七段码那个亮
    	P0 = smgduan[fen];     //段选,同样是动态规划的思想
    	delay(5);
    	
    	LA=0;LB=1;LC=1;       
    	P0 = smgduan[miao];
    	delay(5);
    }
    void main()
    {	
    	unsigned char text=0;
    	timefrist();
    	while(1)
    	{	
    		if(TF0==1)          //当定时器0溢出了,即经过50ms,TF0自动设置为1;
    		{
    			TF0 = 0;        //归0
    			TH0 = 0x4B;     //每次使用都要重新定义为50ms
    	        TL0 = 0xfd;  
    			text++;
    			if(text==20)   //当它进行了20次,20*50ms=1s
    			{
    				text =0;  //归0,之后继续加
    				miao++;   //秒加1
    			}
    			if(miao==10)  //秒为10的时候就可以进位了
    			{
    				miao = 0;  //归0
    				fen++;     //秒十位+1
    			}
    		}
        DigDisplay();	      //上面执行很快,所以一直都是动态显示	
    	}
    }
    

    内部中断定时器0与按键
    独立按键1可以实现数值+1,独立按键2实现数值-1
    解释:因为按键有个按键消抖与松手检测会影响动态显示。特别是松手检测,如果你不松手会一直停在那里,不松手就无法动态显示。所有我们用定时器0直接控制,当经过5ms就用一次显示函数,就算不松手也是有中断自动执行显示函数。

    #include "reg52.h"
    sbit LA=P2^2;
    sbit LB=P2^3;
    sbit LC=P2^4;
    sbit  key1 = P3^0;     //按键1
    sbit  key2 = P3^1;     //按键2
    unsigned char smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
    					0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
    void delay(unsigned int z)    
    {
    	unsigned int x,y;
    	for(x=z;x>0;x--)
    	   for(y=120;y>0;y--);
    }
    void timefrist()
    {
    	EA = 1;          //打开总开关
    	ET0 = 1;         //中断函数0的开关
    	TR0 = 1;         //打开定时器0开关
    	TMOD = 0x01;      //模式一,定时模式
    	TH0 = 0xED;       //这里改值了,到上限就5ms
    	TL0 = 0xFF;
    }
    unsigned char miao=0;
    void DigDisplay(unsigned char h)
    {
    	unsigned char a=h%10;                //个位
    	unsigned char b=h/10//十位
    	static unsigned char wei=0;         //静态变量,就是函数执行完也不会抹去这个变量的值,在次使用函数值可以用
    	switch(wei)                        //这里重新布局,我们这里不断交换显示,用一次函数就显示一个,当快速多显示就动态显示
    	{
    		case 0: LA=1;LB=1;LC=1;P0 = smgduan[b];break;      //wei值0与1不断交换,就动态显示
    		case 1:	LA=0;LB=1;LC=1;P0 = smgduan[a];break;  
    	}
    	wei++;                                            //用过之后++
    	if(wei==2)                                 //我们只要1与0不断交换,为2时就重新回0
    	{
    		wei = 0;
    	}
    }
    void timer0() interrupt 1
    {
    	 TH0 = 0xED;         //重新定义5ms初始值
    	 TL0 = 0xFF;
    	 DigDisplay(miao);   //显示,不断5ms显示就是动态显示
    }
    void main()
    {	
    	timefrist();
    	while(1)
    	{
    		if(key1==0)  //为0,按键被按下
    		{
    			delay(20);
    			if(key1==0)   //按键消抖
    			{
    				miao++;    //全局miao加1,显示就会加1了
    				while(!key1);   //松手检测
    			}
    		}
    		if(key2==0)          //同理
    		{
    			delay(5);
    			if(key2==0)
    			{
    				miao--;
    				while(!key2); 
    			}
    		}
       }
    }
    

    内部中断定时器与计数器同时使用
    内部中断0用作计数(就是3.4口有电压波动TH0与TL0的总值就会加1,由于TH0为后2位,加不到,后面就为TL0加一),内部中断1用作定时器
    思想:定时器1到时间就使LED电压反转(亮与不亮),然后该LED的与P3.4口连在一起,当LED灯不断闪烁,电压不断变化,3.4口就会感受电压波动自动使TL0加1,然后把TL0值传递显示,就可以观察TL0变化。

    #include "reg52.h"			 
    sbit LA=P2^2;
    sbit LB=P2^3;
    sbit LC=P2^4;
    sbit  key2 = P3^0; 
    sbit LED = P2^0;
    unsigned char code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
    					0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
    void delay(unsigned int z)    
    {
    	unsigned int x,y;
    	for(x=z;x>0;x--)
    	   for(y=120;y>0;y--);
    }
    void timefrist0()
    {
    	TR0 = 1;               //打开计数器1
    	TMOD |= 0x05;          //模式值为5
    	TH0 = 0;               //计数功能,设为0
    	TL0 = 0;
    }
    void timefrist1()
    {
    	EA = 1;          
    	TR1 = 1;           //中断1的开关
    	TMOD |= 0x10;      //0001 0000
    	TH1 = 0x4b;        //铁打的50ms
    	TL1 = 0xfd;
    }
    void DigDisplay(unsigned char miao)
    {
    	LA=1;LB=1;LC=1;        //8动态显示函数
    	P0 = smgduan[miao];
    	delay(5);
    	
    	LA=0;LB=1;LC=1;       //6
    	P0 = smgduan[miao/10];
    	delay(5);
    }
    void main()
    {	
    	unsigned char text=0;
    	timefrist0();    //中断0与1的初始定义
    	timefrist1();
    	LED = 0;
    	while(1)
    	{	
    		if(TF1 == 1)  //定时器0溢出,50ms过
    		{
    			TF1 = 0;
    			TH1 = 0x4b;
    	        TL1 = 0xfd;
    			text++;
    			if(text==10)  //经过 0.5s
    			{
    				text = 0;
    				LED = ~LED;   //变化一次,形成电压给P3.4
    			}
    		}
        DigDisplay(TL0);    //上面动作很快,动态显示一直在执行
    	}
    }
    
    展开全文
  • 按键 K1 用于触发外部中断 1 main.c /** * Interrupt Registers Definition */ sfr IE = 0xA8; /* Interrupt Enable Register */ /** * Interrupt Registers Bits Definition */ /** IE */ #define GLOBAL_IE_...

    STC8H 外部中断 1 结构图

    在这里插入图片描述

    上升沿或下降沿触发外部中断 1

    工程结构

    在这里插入图片描述

    原理图

    在这里插入图片描述

    源代码

    main.c 文件:

    sfr TCON    = 0x88;
    sfr P1      = 0x90; /* Port 1 Register */
    sfr P1M1    = 0x91; /* Port 1 Configuration Register 1 */
    sfr P1M0    = 0x92; /* Port 1 Configuration Register 0 */
    sfr IE      = 0xA8;
    sfr P3M1    = 0xB1; /* Port 3 Configuration Register 1 */
    sfr P3M0    = 0xB2; /* Port 3 Configuration Register 0 */
    
    
    /** TCON Register Bits Definition */
    #define INT1_TCON_IT1   (0x04)
    
    /** P1M1 Register Bit Definition */
    #define P12M1   (0x04) /* P1.2 Mode Selection Bit 1 */
    /** P1M0 Register Bit Definition */
    #define P12M0   (0x04) /* P1.2 Mode Selection Bit 0 */
    
    /** IE Register Bits Definition */
    #define IE_EA           (0x80)
    #define INT1_IE_EX1     (0x04)
    
    /** P3M1 Register Bit Definition */
    #define P33M1   (0x08) /* P3.3 Mode Selection Bit 1 */
    /** P3M0 Register Bit Definition */
    #define P33M0   (0x08) /* P3.3 Mode Selection Bit 0 */
    
    
    #define setRegisterBit(r, b)    r |= b
    #define clearRegisterBit(r, b)  r &= ~b
    
    
    #define enableInterrupts()      setRegisterBit(IE, IE_EA)
    #define disableInterrupts()     clearRegisterBit(IE, IE_EA)
    
    
    sbit LED = P1^2; /* LED Control Bit. 0: On, 1: Off */
    
    
    /**
     * External Interrupt 1
     */
    void main() {
        /**
         * External Interrupt 1 Initialization
         */
        clearRegisterBit(TCON, INT1_TCON_IT1); // 上升沿或下降沿触发外部中断 1
        setRegisterBit(IE, INT1_IE_EX1); // 允许外部中断 1 请求中断
        
        /**
         * IO Initialization
         */
        // 将 LED 的控制引脚设置为推挽输出
        clearRegisterBit(P1M1, P12M1);
        setRegisterBit(P1M0, P12M0);
        // 将外部中断 1 所在的输入引脚设置为准双向口
        clearRegisterBit(P3M1, P33M1);
        clearRegisterBit(P3M0, P33M0);
        
        LED = 1; // LED Off
        
        /**
         * 
         */
        enableInterrupts();
        
        /**
         * Do nothing...
         */
        while(1) {}
    }
    
    void externalInterrupt0InterruptService() interrupt 2 {
        LED = !LED;
    }
    

    STC-ISP 下载选项

    在这里插入图片描述

    测试

    编译工程之后,将程序下载到单片机。然后使用示波器分别测量 LED 的控制引脚(黄色信号波形)和外部中断的输入引脚(天蓝色信号波形)。

    • 第一次按下按键 K1,此时产生一个下降沿触发外部中断 1;进入外部中断程序之后,LED 的控制引脚被反转(见下图第一个红色箭头);
    • 松开按键,此时产生一个上降沿,再次触发外部中断 1;进入外部中断程序之后,LED 的控制引脚再次被反转(见下图第二个红色箭头)。

    在这里插入图片描述

    模块化

    将所有的东西的写在一个文件中,是非常不好的习惯。为了方便代码维护,应当是根据单片机的外设,合理地将其划分、模块化。

    工程结构

    在这里插入图片描述

    源文件

    新建 stc8h1k08.h 文件,在其中声明寄存器,以及其他:

    个人观点:由于历史原因,8051 内核单片机的寄存器分布极其混乱。因此,在声明寄存器时,我是根据寄存器地址来排列的。

    #ifndef __STC8H1K08_H
    #define __STC8H1K08_H
    
    
    sfr TCON    = 0x88;
    sfr P1      = 0x90; /* Port 1 Register */
    sfr P1M1    = 0x91; /* Port 1 Configuration Register 1 */
    sfr P1M0    = 0x92; /* Port 1 Configuration Register 0 */
    sfr IE      = 0xA8;
    sfr P3M1    = 0xB1; /* Port 3 Configuration Register 1 */
    sfr P3M0    = 0xB2; /* Port 3 Configuration Register 0 */
    
    
    /** TCON Register Bits Definition */
    #define INT1_TCON_IT1   (0x04)
    
    /** P1M1 Register Bit Definition */
    #define P12M1   (0x04) /* P1.2 Mode Selection Bit 1 */
    /** P1M0 Register Bit Definition */
    #define P12M0   (0x04) /* P1.2 Mode Selection Bit 0 */
    
    /** IE Register Bits Definition */
    #define IE_EA           (0x80)
    #define INT1_IE_EX1     (0x04)
    
    /** P3M1 Register Bit Definition */
    #define P33M1   (0x08) /* P3.3 Mode Selection Bit 1 */
    /** P3M0 Register Bit Definition */
    #define P33M0   (0x08) /* P3.3 Mode Selection Bit 0 */
    
    
    typedef enum {
        false = 0,
        true = !false
    } boolean;
    
    
    #define setRegisterBit(r, b)    r |= b
    #define clearRegisterBit(r, b)  r &= ~b
    
    
    #define enableInterrupts()      setRegisterBit(IE, IE_EA)
    #define disableInterrupts()     clearRegisterBit(IE, IE_EA)
    
    
    #endif
    

    新建 int1.h 文件,用于管理外部中断 1。在其中声明一些常量,并使用宏定义封装对外部中断 1 的部分操作:

    注:对于不常用的操作,我习惯使用宏定义封装。当然,也可以使用方法封装。

    #ifndef __STC8H1K08_INT_1_H
    #define __STC8H1K08_INT_1_H
    
    
    #include "stc8h1k08.h"
    
    
    typedef enum {
        EXTERNAL_INTERRUPT_1_SENSITIVITY_FALL           = (uint8_t)0x00,
        EXTERNAL_INTERRUPT_1_SENSITIVITY_RISE_AND_FALL  = (uint8_t)0x01
    } ExternalInterrupt1Sensitivity;
    
    
    #define int1SetSensitivity(sensitivity) {                       \
        if(sensitivity == EXTERNAL_INTERRUPT_1_SENSITIVITY_FALL) {  \
            setRegisterBit(TCON, INT1_TCON_IT1);                    \
        } else {                                                    \
            clearRegisterBit(TCON, INT1_TCON_IT1);                  \
        }                                                           \
    }
    
    #define int1EnableInterrupt(enable) {       \
        if(enable == false) {                   \
            clearRegisterBit(IE, INT1_IE_EX1);  \
        } else {                                \
            setRegisterBit(IE, INT1_IE_EX1);    \
        }                                       \
    }
    
    
    #endif
    

    新建 int1.c 文件,这里面没什么的,只是一条包含头文件的语句:

    注:因为没有使用方法封装对外部中断 1 的操作,所以,该文件是非必须的。

    #include "int1.h"
    

    新建 config.h 配置文件,其内容如下:

    #ifndef __CONFIG_H
    #define __CONFIG_H
    
    
    #include "stc8h1k08.h"
    
    #include "int1.h"
    
    
    sbit LED = P1^2; /* LED Control Bit. 0: On, 1: Off */
    
    
    #endif
    

    修改 main.c 文件:

    #include "config.h"
    
    
    /**
     * External Interrupt 1
     */
    void main() {
        /**
         * External Interrupt 1 Initialization
         */
        int1SetSensitivity(EXTERNAL_INTERRUPT_1_SENSITIVITY_RISE_AND_FALL); // 上升沿或下降沿均可触发外部中断 1
        int1EnableInterrupt(true); // 允许外部中断 1 请求中断
        
        /**
         * IO Initialization
         */
        // 将 LED 的控制引脚设置为推挽输出
        clearRegisterBit(P1M1, P12M1);
        setRegisterBit(P1M0, P12M0);
        // 将外部中断 1 所在的输入引脚设置为准双向口
        clearRegisterBit(P3M1, P33M1);
        clearRegisterBit(P3M0, P33M0);
        
        LED = 1; // LED Off
        
        /**
         * 
         */
        enableInterrupts();
        
        /**
         * Do nothing...
         */
        while(1) {}
    }
    
    void int1InterruptService() interrupt 2 {
        LED = !LED;
    }
    

    参考

    宏晶科技 STC micro - STC8H 系列单片机技术参考手册

    展开全文
  • 51单片机 外部中断1触发蜂鸣器+Proteus仿真 相关篇《51单片机 外部中断0触发蜂鸣器+Proteus仿真》 Proteus仿真 为了体现仿真观看效果,在蜂鸣器旁边并了一组led,触发的时候,导通NPN三极管。 自己添加蜂鸣器...

    51单片机 外部中断1触发蜂鸣器+Proteus仿真


    为了体现仿真观看效果,在蜂鸣器旁边并了一组led,触发的时候,导通NPN三极管。

    • 自己添加蜂鸣器注意选择有源蜂鸣器,设置修改蜂鸣器属性,将电压改为5V驱动。

    在这里插入图片描述

    实例代码

    /**************************************************************************************
    实验现象:下载程序后,操作K4按键使buzzer状态取反
    
    		   1,单片机-->buzzer&交通灯模块
    		   		P20-->D1
    		   2,单片机-->独立按键模块
    		   		P33-->K4	
    	
    注意事项:																				
    
      
    *************************************
    展开全文
  • 按键 K1 用于触发外部中断 0 main.c /** * Interrupt Registers Definition */ sfr IE = 0xA8; /* Interrupt Enable Register */ /** * Interrupt Registers Bits Definition */ /** IE */ #define GLOBAL_IE_...

    STC8H 外部中断 0 结构图

    在这里插入图片描述

    下降沿触发外部中断 0

    工程结构

    在这里插入图片描述

    原理图

    在这里插入图片描述

    源代码

    main.c 文件:

    sfr TCON    = 0x88;
    sfr P1      = 0x90; /* Port 1 Register */
    sfr P1M1    = 0x91; /* Port 1 Configuration Register 1 */
    sfr P1M0    = 0x92; /* Port 1 Configuration Register 0 */
    sfr IE      = 0xA8;
    sfr P3M1    = 0xB1; /* Port 3 Configuration Register 1 */
    sfr P3M0    = 0xB2; /* Port 3 Configuration Register 0 */
    
    
    /** TCON Register Bits Definition */
    #define INT0_TCON_IT0   (0x01)
    
    /** P1M1 Register Bit Definition */
    #define P12M1   (0x04) /* P1.2 - Mode Selection Bit 1 */
    /** P1M0 Register Bit Definition */
    #define P12M0   (0x04) /* P1.2 - Mode Selection Bit 0 */
    
    /** IE Register Bits Definition */
    #define IE_EA           (0x80)
    #define INT0_IE_EX0     (0x01)
    
    /** P3M1 Register Bit Definition */
    #define P32M1   (0x04) /* P3.2 - Mode Selection Bit 1 */
    /** P3M0 Register Bit Definition */
    #define P32M0   (0x04) /* P3.2 - Mode Selection Bit 0 */
    
    
    #define setRegisterBit(r, b)    r |= b
    #define clearRegisterBit(r, b)  r &= ~b
    
    
    #define enableInterrupts()      setRegisterBit(IE, IE_EA)
    #define disableInterrupts()     clearRegisterBit(IE, IE_EA)
    
    
    sbit LED = P1^2; /* LED Control Bit. 0: On, 1: Off */
    
    
    /**
     * External Interrupt 0
     */
    void main() {
        /**
         * External Interrupt 0 Initialization
         */
        setRegisterBit(TCON, INT0_TCON_IT0); // 下降沿触发外部中断 0
        setRegisterBit(IE, INT0_IE_EX0); // 允许外部中断 0 请求中断
        
        /**
         * IO Initialization
         */
        // 将 LED 的控制引脚设置为推挽输出
        clearRegisterBit(P1M1, P12M1);
        setRegisterBit(P1M0, P12M0);
        // 将外部中断 0 所在的输入引脚设置为准双向口
        clearRegisterBit(P3M1, P32M1);
        clearRegisterBit(P3M0, P32M0);
        
        LED = 0; // LED On
        
        /**
         * 
         */
        enableInterrupts();
        
        /**
         * Do nothing...
         */
        while(1) {}
    }
    
    void externalInterrupt0InterruptService() interrupt 0 {
        LED = !LED;
    }
    

    STC-ISP 下载选项

    在这里插入图片描述

    测试

    编译工程之后,将程序下载到单片机。然后使用示波器分别测量 LED 的控制引脚(黄色信号波形)和外部中断的输入引脚(天蓝色信号波形)。

    • 第一次按下按键 K1,此时产生一个下降沿触发外部中断 0;进入外部中断程序之后,LED 的控制引脚被反转(见下图第一个红色箭头);
    • 松开按键,此时产生一个上升沿信号,但并没有触发外部中断 0,所以 LED 的控制引脚并没有被反转(见下图第二个红色箭头);
    • 第二次按下按键,此时产生一个下降沿,再次触发外部中断 0;进入外部中断程序之后,LED 的控制引脚再次被反转(见下图第三个红色箭头)。

    在这里插入图片描述

    模块化

    将所有的东西的写在一个文件中,是非常不好的习惯。为了方便代码维护,应当是根据单片机的外设,合理地将其划分、模块化。

    工程结构

    在这里插入图片描述

    源文件

    新建 stc8h1k08.h 文件,在其中声明寄存器,以及其他:

    个人观点:由于历史原因,8051 内核单片机的寄存器分布极其混乱。因此,在声明寄存器时,我是根据寄存器地址来排列的。

    #ifndef __STC8H1K08_H
    #define __STC8H1K08_H
    
    
    sfr TCON    = 0x88;
    sfr P1      = 0x90; /* Port 1 Register */
    sfr P1M1    = 0x91; /* Port 1 Configuration Register 1 */
    sfr P1M0    = 0x92; /* Port 1 Configuration Register 0 */
    sfr IE      = 0xA8;
    sfr P3M1    = 0xB1; /* Port 3 Configuration Register 1 */
    sfr P3M0    = 0xB2; /* Port 3 Configuration Register 0 */
    
    
    /** TCON Register Bits Definition */
    #define INT0_TCON_IT0   (0x01)
    
    /** P1M1 Register Bit Definition */
    #define P12M1   (0x04) /* P1.2 - Mode Selection Bit 1 */
    /** P1M0 Register Bit Definition */
    #define P12M0   (0x04) /* P1.2 - Mode Selection Bit 0 */
    
    /** IE Register Bits Definition */
    #define IE_EA           (0x80)
    #define INT0_IE_EX0     (0x01)
    
    /** P3M1 Register Bit Definition */
    #define P32M1   (0x04) /* P3.2 - Mode Selection Bit 1 */
    /** P3M0 Register Bit Definition */
    #define P32M0   (0x04) /* P3.2 - Mode Selection Bit 0 */
    
    
    typedef enum {
        false = 0,
        true = !false
    } boolean;
    
    
    #define setRegisterBit(r, b)    r |= b
    #define clearRegisterBit(r, b)  r &= ~b
    
    
    #define enableInterrupts()      setRegisterBit(IE, IE_EA)
    #define disableInterrupts()     clearRegisterBit(IE, IE_EA)
    
    
    #endif
    

    新建 int0.h 文件,用于管理外部中断 0。在其中声明一些常量,并使用宏定义封装对外部中断 0 的部分操作:

    注:对于不常用的操作,我习惯使用宏定义封装。当然,也可以使用方法封装。

    #ifndef __STC8H1K08_INT_0_H
    #define __STC8H1K08_INT_0_H
    
    
    #include "stc8h1k08.h"
    
    
    typedef enum {
        EXTERNAL_INTERRUPT_0_SENSITIVITY_FALL           = (uint8_t)0x00,
        EXTERNAL_INTERRUPT_0_SENSITIVITY_RISE_AND_FALL  = (uint8_t)0x01
    } ExternalInterrupt0Sensitivity;
    
    
    #define int0SetSensitivity(sensitivity) {                       \
        if(sensitivity == EXTERNAL_INTERRUPT_0_SENSITIVITY_FALL) {  \
            setRegisterBit(TCON, INT0_TCON_IT0);                    \
        } else {                                                    \
            clearRegisterBit(TCON, INT0_TCON_IT0);                  \
        }                                                           \
    }
    
    #define int0EnableInterrupt(enable) {       \
        if(enable == false) {                   \
            clearRegisterBit(IE, INT0_IE_EX0);  \
        } else {                                \
            setRegisterBit(IE, INT0_IE_EX0);    \
        }                                       \
    }
    
    
    #endif
    

    新建 int0.c 文件,这里面没什么的,只是一条包含头文件的语句:

    注:因为没有使用方法封装对外部中断 0 的操作,所以,该文件是非必须的。

    #include "int0.h"
    

    新建 config.h 配置文件,其内容如下:

    #ifndef __CONFIG_H
    #define __CONFIG_H
    
    
    #include "stc8h1k08.h"
    
    #include "int0.h"
    
    
    sbit LED = P1^2; /* LED Control Bit. 0: On, 1: Off */
    
    
    #endif
    

    修改 main.c 文件:

    #include "config.h"
    
    
    /**
     * External Interrupt 0
     */
    void main() {
        /**
         * External Interrupt 0 Initialization
         */
        int0SetSensitivity(EXTERNAL_INTERRUPT_0_SENSITIVITY_FALL); // 下降沿触发外部中断 0
    //    int0SetSensitivity(EXTERNAL_INTERRUPT_0_SENSITIVITY_RISE_AND_FALL); // 上升沿或下降沿均可触发外部中断 0
        int0EnableInterrupt(true); // 允许外部中断 0 请求中断
        
        /**
         * IO Initialization
         */
        // 将 LED 的控制引脚设置为推挽输出
        clearRegisterBit(P1M1, P12M1);
        setRegisterBit(P1M0, P12M0);
        // 将外部中断 0 所在的输入引脚设置为准双向口
        clearRegisterBit(P3M1, P32M1);
        clearRegisterBit(P3M0, P32M0);
        
        LED = 0; // LED On
        
        /**
         * 
         */
        enableInterrupts();
        
        /**
         * Do nothing...
         */
        while(1) {}
    }
    
    void int0InterruptService() interrupt 0 {
        LED = !LED;
    }
    

    参考

    宏晶科技 STC micro - STC8H 系列单片机技术参考手册

    展开全文
  • 外部中断在不同的Arduino型号上位置也不同,只有外部中断发生在以下端口,Arduino才能捕获到,以下例举了常见的几种型号的外部中断引脚标号。 型号 int.0 int.1 int.2 int.3 int.4 int.5 UNO\...
  • 目录中断定义中断引脚中断模式中断函数(1)attachInterrupt(interrupt, function,mode)detachInterrupt(interrupt)实验:外部中断实现开关电源 中断定义 程序运行过程中时常需要监控一些事件的发生,如对某一传感器的...
  • 实验板子:tiny210(芯片:s5pv210)实验目的:通过外部中断操作两个按键实现对LED灯的亮灭控制步骤:①初始化GPIO端口,使GPIO为外部中断状态;(寄存器:GPxxCON)例:②配置外部中断触发模式,上升沿触发,下降沿触发...
  • 文章目录STC8H 外部中断 4 结构图下降沿触发外部中断 4工程结构原理图源代码STC-ISP 下载选项模块化工程结构源文件参考 STC8H 外部中断 4 结构图 下降沿触发外部中断 4 工程结构 原理图 源代码 main.c 文件: sfr...
  • 文章目录STC8H 外部中断 2 结构图下降沿触发外部中断 2工程结构原理图源代码STC-ISP 下载选项模块化工程结构源文件参考 STC8H 外部中断 2 结构图 下降沿触发外部中断 2 工程结构 原理图 源代码 main.c 文件: sfr...
  • 中断优先级寄存器IPPS——串行口中断优先级控制位PT1——定时器/计数器1中断优先级控制位PX1——外部中断1中断优先级控制位PT0——定时器/计数器0中断优先级控制位PX0——外部中断0中断优先级控制
  • 51单片机有两个外部中断,两个定时器/计数器,两个外部中断分别是int0,int1。定时器/计数器分别是t0,t1,还有一个串口中断TI/RI,加起来有五个中断。它们在硬件上的排列顺序是INT0,T0,INT1,T1,TI/RI,这5个...
  • 外部中断

    2021-06-19 17:20:19
    课程名称: 单片机原理与接口技术 实验项目名称:中断系统 实验时间: ...1、51单片机的P0口连接数码管的字段, P2口连接数码管的位段,K1独立按键连接外部中断0的请求信号输入引脚P3.2,要求中断一次计
  • 6.STC15W408AS单片机外部中断

    千次阅读 2021-07-15 09:29:24
    STC15W408AS单片机有4个外部中断,它们分别是:外部中断0(INT0)、外部中断1(INT1)、外部中断2(INT2)、外部中断3(INT3)。 外部中断0(INT0)和外部中断1(INT1)触发有两种触发方式,上升沿或下降沿均可触发方式 和仅...
  • 3:中断系统 将外部中断0和外部中断1均配置为下降沿触发,但外部中断1的优先级最高,外部中断0的优先级最低。 EXTI.c #include #include "intrins.h" #include "stdint.h" #include "EXTI.h" //定义LED管脚 sbit D1 ...
  • 51单片机学习——8.1外部中断0和1

    千次阅读 2021-02-13 08:49:54
    外部中断1:(P3.3)可由IT1(TCON.2)选择其为低电平有效还是下降沿有效。当CPU检测到P3.3引脚上出现有效的中断信号时,中断标志IE1(TCON.3)置1,向CPU申请中断。 编程原理(外部中断0) 首先我们对中断允许控制寄存器...
  • STM32外部中断

    2021-05-22 21:58:11
    外部中断概述 外部中断是单片机实时地处理外部事件的一种内部机制。当某种外部事件发生时,单片机的中断系统将迫使CPU暂停正在执行的程序,转而去进行中断事件的处理;中断处理完毕后.又返回被中断的程序处,继续...
  • ESP32外部中断

    2021-11-21 17:43:22
    文章目录前言一、外部中断概念二、配置外部中断1.编写中断服务函数2.配置中断总结 前言 提示:以下是本篇文章正文内容 一、外部中断概念 外部中断是单片机实时地处理外部事件的一种内部机制 当外部事件发生后,...
  • 51单片机外部中断0实例详解

    千次阅读 2021-05-22 03:49:54
    151单片机的中断源51单片机共有5个中断源,分别为:外部中断0定时器0中断外部中断1定时器1中断串口中断每一个中断都对应一个中断向量,中断向量表如下所示:2什么是中断事件当中断发生时单片机将正在执行的程序暂时...
  • 在前面九篇博文中,我们认识到了一些基于IO口输入与输出的基础电子器件使用: 8051单片机实战分析(以STC89C52RC为例) | 01 - 点亮一个LED 8051单片机实战分析(以STC89C52RC为例) | 02 - LED延时约5s闪烁 8051...
  • NUC980 外部中断使用

    2021-10-25 20:34:13
    进入内核菜单,打开GPIO外部中断选项 修改drivers/gpio/nuc980-gpio.c文件,打开外部中断2 PE10使能。 编译uImage后下载到开发板,改变PE10电平能发现不断的进入了中断函数。 在内核初始化过程中也能看到...
  • 51单片机——外部中断

    千次阅读 2021-04-16 12:35:06
    一、外部中断 1.1 中断 关于中断的概念在上一篇博客中已经提到了。(传送门:51单片机入门教程(5)——定时器中断) 中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并...
  • 外部中断执行流程

    2021-10-22 18:45:44
    1、设备向中断请求芯片发出中断请求 2、中断请求芯片根据优先级排序选择响应优先级较高的中断 3、根据响应的中断引脚在其内部存储器取与引脚对应位置的中断号并提交给CPU 4、保存断点,CPU根据中断号在RAM中的中断向...
  • 外部中断 以下是假期对51单片机课程内容做的一些小结 中断的基本概念 中断: CPU与外设并行工作,当外设数据准备好或者有某种突发事件发生时,向CPU提出请求,CPU暂停正在进行的工作,转而为该外设服务(或者是处理...
  • ESP32外部中断原理&实战 阅读建议:   有一定Cortex-m架构知识基础。 外部中断原理 外部中断实战 首先配置GPIO   ESP-IDF提供了一个结构体方便对其进行初始化,结构体如下: typedef struct { uint64_t ...
  • #include <STC8.h> #define uchar unsigned char #define uint unsigned int /****************************************** ...函数说明:STC8外部中断1初始化 *******************************
  • 外部中断 外部中断一般是由计算机外设发出的中断请指求,如:键盘中断、打印机中断、定时器中断等。外部中断一般指io高低电平来触发并响应io中断函数 定时器中断 定时器中断是指计数器在晶振的...1:先说外部中断 ...
  • 13 . 外部中断实验

    2021-05-13 10:50:46
    1. 外部中断介绍 EXTI 简介 STM32F10x 外部中断/事件控制器(EXTI)包含多达20 个用于产生事件/中断请求的边沿检测器。EXTI 的每根输入线都可单独进行配置,以选择类型(中断或事件)和相应的触发事件(上升沿触发、...
  • 51单片机--外部中断1控制led亮灭

    千次阅读 2021-09-11 14:58:44
    #include "reg51.h" typedef unsigned int u16;...sbit led1=P2^1; /******************************************************************************* * 函 数 名 : delay * 函数功能 : 延时函数,i=1时,
  • 设置中断优先级寄存器,当有外部中断0请求中断时,中断程序执行发光二极管程序,在此过程中,外部中断1也有中断请求,外部中断0的中断程序将被中断去执行外部中断1的中断程序(数码管加1显示程序)。 #include<...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 194,040
精华内容 77,616
关键字:

外部中断1怎么使用