51单片机嵌入式开发:7、 STC89C52RC 外部中断INT0和INT1 操作

news2024/7/30 0:51:41

STC89C52RC 外部中断INT0和INT1 操作

  • 1 外部中断
    • 1.1 外部中断
    • 1.2 中断介绍
  • 2 STC89C52外部中断
    • 2.1 外部中断引脚
    • 2.2 外部中断寄存器说明
  • 3 STC89C52外部中断演示
    • 3.1 电平触发外部中断
    • 3.2 边沿触发外部中断
    • 3.3 Protues仿真
  • 4 外部中断总结


1 外部中断

1.1 外部中断

单片机外部中断是指由外部设备或事件触发的中断信号,它可以打断单片机正在执行的程序,转而执行中断服务程序来处理特定的外部事件。外部中断是单片机与外部世界进行交互的重要方式之一,可以用于处理各种外部输入、事件或信号,如按键输入、传感器触发、通信接收等。
外部中断的处理过程通常涉及以下几个关键步骤:

  1. 配置中断触发条件:单片机需要通过相应的寄存器或配置寄存器设置外部中断的触发条件,如上升沿触发、下降沿触发、边沿触发或电平触发等。这些触发条件决定了何时触发外部中断。
  2. 使能中断:在需要使用外部中断时,单片机需要使能相应的中断源,以便在触发条件满足时产生中断请求信号。
  3. 编写中断服务程序(ISR):中断服务程序是用于处理中断事件的函数,它会在中断触发时被自动调用。在中断服务程序中,可以编写处理外部中断事件的代码,如读取外部输入、处理传感器数据、发送响应信号等。
  4. 中断向量表:单片机通常使用中断向量表来管理不同的中断源和相应的中断服务程序。中断向量表是一个包含各个中断服务程序地址的表格,当中断触发时,单片机会自动跳转到相应的中断服务程序执行。
    在具体的单片机平台和开发环境中,外部中断的配置和处理方法可能会有所不同。不同的单片机可能会提供不同的寄存器和库函数来支持外部中断功能。因此,您需要参考所使用单片机的器件手册和开发环境的文档,以了解如何正确配置和处理外部中断。

1.2 中断介绍

TC89C52是一款常用的单片机型号,它基于8051内核,并具有一些扩展的功能和特性。以下是关于STC89C52中断的介绍:

  1. 中断源:STC89C52支持多种中断源,包括外部中断、定时器中断、串口中断和其他特定硬件中断。具体的中断源数量和类型取决于单片机的具体型号和配置。
  2. 中断向量表:STC89C52使用中断向量表来管理中断服务例程。中断向量表是一组特定的内存地址,每个地址对应一个中断源的中断服务例程入口点。当中断触发时,单片机会根据中断源的标识符查找相应的中断向量表地址,并跳转到对应的中断服务例程。
  3. 中断优先级:STC89C52支持中断优先级的设置,以决定各个中断源的触发顺序和优先级。具有更高优先级的中断源将在较低优先级的中断源之前得到处理。中断优先级可以通过设置特定的寄存器来实现,通常是通过IP(Interrupt Priority)寄存器来配置。
  4. 中断控制和使能:STC89C52提供了相关的寄存器用于控制和使能中断。例如,EA(全局中断使能)位用于启用或禁用所有中断,INT0、INT1等位用于控制特定外部中断的使能,定时器相关寄存器用于配置定时器中断等。
  5. 中断服务例程(ISR):对于每个中断源,需要编写相应的中断服务例程来处理中断事件。中断服务例程应位于中断向量表所指定的地址处,它们负责执行与中断相关的任务和操作。在中断服务例程中,可以执行特定的代码、读取和处理相关寄存器、更新状态等。
  6. 中断返回:在STC89C52中,中断服务例程的返回是通过执行中断返回指令(RETI)来实现的。RETI指令会将程序的执行流程返回到中断触发的地方,并继续执行主程序的下一条指令。
    中断寄存器介绍:

在这里插入图片描述

示例中断服务函数写法:void Timer2_isr(void) interrupt 5 using 1
5:代表中断向量号 (详见中断查询次序,timer2是第六个所以为5)
1:就是指定在执行函数时切换为使用第1组

根据以下分析,我们建议不要使用using,避免操作不当对程序运行造成影响。

以下是网上总结的:原文链接:http://www.51hei.com/mcu/766.html
using关键字的作用就是指定某个函数在执行时切换寄存器组的:
51中有四个寄存器组,每个组有R0-R7这8个寄存器,用于CPU的数据处理,一般主函数main()默认使用第0组,因为PSW寄存器的初始值的第3、4位是00嘛,即默认指定了第0组。using 0就是指定在执行函数时切换为使用第0组,不加using关键字的话,一般都默认使用第0组,但这样的话在调用其他函数(包括中断服务函数)的时候,就会加入一些压栈指令以保护原来的R0-R7寄存器的(这样的话,程序执行会效率会低一点,因为会产生很多个指令是用来压栈出栈的),照这样说,只是加了using 0,使用的也是第0组又不是其它的组,程序就不应该有问题了吧,但是就是因为加了using 0,编译了一次,才发现在定时器中断函数t0()的入口中并没有发现把R0-R7的代码压入栈呀,就是说没有保护好R7呀,那当然就是在执行完之后回来R7不能回复原来的值啦,接下来的事情。。。。我就不说啦,这就是问题的根源,去掉using 0就可以了,编译器就自动帮你将R0-R7压栈,手动加了using 0,就是让编译器以为之前用的并不是第0组,而现在执行这个中断函数时就切换到第0组,而省去了将R0-R7这8个寄存器压入栈的指令了,这样虽然看起来是快了,然而对于这个程序来说却是致命的问题!!!因为根本没有保护好R0-R7,而没有保护R7并不是我预期发生的!!!这不是编译器的问题,是自己没有了解好、用好using的问题啊!还有,其实也可以在编译器选项里有选项来硬性规定编译器统一不直接使用寄存器而是使用间接寻址的办法来改变循环变量分配的地址的,或者使用
#pragma NOAREGS
定义函数
#pragma AREGS
来规定某个函数的是这样子。
当然,这样的规定和使用using本身并不冲突,只是使用了这个关键字后就可能会间接地产生一系列的问题,让人郁闷了这么久,其实本来如果有详细地看整个程序的反汇编代码,或许当时就会发现发现少了那段压栈指令了,而不是说推断为编译器分配空间的问题了。。。。。。。。希望我的这次教训对各位有所帮助!!!
另外,using的用法,其实就是手动指定函数使用的寄存器组,用得不好,如果在中断里还有调用其它函数,用得不好会出现函数传递出错的,不信可以反汇编看看,建议如果对这个关键字用法和C51的结构及汇编不熟的话,请还是让C51编译器帮你好了,不要胡乱使用,因为会比较容易出错的,要切记哦!!!其实用using关键到底对在编译后会造成什么影响,建议自己亲自去查看汇编程序。。。

2 STC89C52外部中断

2.1 外部中断引脚

中断 AT89S52 有 6 个中断源:两个外部中断(INT0 和 INT1),三个定时中断(定时器 0、1、 2)和一个串行中断。这些中断如图 10 所示 每个中断源都可以通过置位或清除特殊寄存器 IE 中的相关中断允许控制位分别使得中 断源有效或无效。IE 还包括一个中断允许总控制位 EA,它能一次禁止所有中断。 如表 5 所示,IE.6 位是不可用的。对于 AT89S52,IE.5 位也是不能用的。用户软件不应 给这些位写 1。它们为 AT89 系列新产品预留。 定时器 2 可以被寄存器 T2CON 中的 TF2 和 EXF2 的或逻辑触发。程序进入中断服务后, 这些标志位都可以由硬件清 0。实际上,中断服务程序必须判定是否是 TF2 或 EXF2 激 活中断,标志位也必须由软件清 0。 定时器 0 和定时器 1 标志位 TF0 和 TF1 在计数溢出的那个周期的 S5P2 被置位。它们的 值一直到下一个周期被电路捕捉下来。然而,定时器 2 的标志位 TF2 在计数溢出的那 个周期的 S2P2 被置位,在同一个周期被电路捕捉下来。

STC89C52外部中断引脚在P32和P33两个引脚,分别对应INT0和INT1
如图所示:
在这里插入图片描述

2.2 外部中断寄存器说明

(1)在 8051 单片机中,TCON(Timer Control)寄存器用于控制定时器/计数器的操作和中断。TCON 寄存器是一个 8 位寄存器,包含了定时器/计数器相关的控制位和中断标志位。下面是 TCON 寄存器的位分配:
apache
复制
Bit 7 6 5 4 3 2 1 0
TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
以下是各个位的功能解释:
• TF1 (Timer 1 Overflow Flag):定时器 1 溢出标志位。当定时器 1 溢出时,该位会置 1。需要手动清除该标志位以允许下一次溢出中断。
• TR1 (Timer 1 Run Control):定时器 1 运行控制位。设置为 1 时,定时器 1 开始运行;设置为 0 时,定时器 1 停止。
• TF0 (Timer 0 Overflow Flag):定时器 0 溢出标志位。当定时器 0 溢出时,该位会置 1。需要手动清除该标志位以允许下一次溢出中断。
• TR0 (Timer 0 Run Control):定时器 0 运行控制位。设置为 1 时,定时器 0 开始运行;设置为 0 时,定时器 0 停止。
• IE1 (External Interrupt 1 Enable):外部中断 1 使能位。设置为 1 时,允许外部中断 1 的触发;设置为 0 时,禁止外部中断 1。
• IT1 (External Interrupt 1 Type Control):外部中断 1 触发类型控制位。当 IT1 为 0 时,外部中断 1 通过电平触发;当 IT1 为 1 时,外部中断 1 通过边沿触发。
• IE0 (External Interrupt 0 Enable):外部中断 0 使能位。设置为 1 时,允许外部中断 0 的触发;设置为 0 时,禁止外部中断 0。
• IT0 (External Interrupt 0 Type Control):外部中断 0 触发类型控制位。当 IT0 为 0 时,外部中断 0 通过电平触发;当 IT0 为 1 时,外部中断 0 通过边沿触发。
通过配置 TCON 寄存器的位,可以实现以下功能:
• 控制定时器 1 和定时器 0 的启停操作。
• 选择外部中断 1 和外部中断 0 的触发类型(电平触发或边沿触发)。
• 允许或禁止外部中断 1 和外部中断 0 的触发。
需要注意的是,TCON 寄存器是特殊功能寄存器(SFR),对应的地址为 0x88。在程序中,可以使用特定的指令来读取和写入 TCON 寄存器的值,例如 MOV 指令。
总结起来,TCON 寄存器在 8051 单片机中用于控制定时器/计数器的操作和中断,以及外部中断的触发和使能。通过配置 TCON 寄存器的位,可以实现定时器/计数器的启停控制和中断的配置。

(2)根据触发源的逻辑框图可知,外部中断由低电平触发或者下降沿触发,如图所示
在这里插入图片描述

(3)中断使能控制位

在这里插入图片描述

3 STC89C52外部中断演示

工程整理,首先,我们将定时器看门狗使能都屏蔽掉,并将全局中断使能放到主程序中。然后新建中断的c和h文件添加到工程。

在这里插入图片描述

3.1 电平触发外部中断

工程中所有代码如下所示:

//main.c文件

#include "includes.h"



/*------------------------------------------------
                    延时子程序
------------------------------------------------*/
void delay(unsigned int cnt) 
{
 while(--cnt);
}

/*------------------------------------------------
                    主函数
------------------------------------------------*/
void main (void)
{
	EA=0;
	//初始化定时器0
	sys_timer0_init();
	//初始化定时器1
	sys_timer1_init();
	//初始化定时器2
	sys_timer2_init();
	
	sys_wdog_init();
	
	//外部中断初始化
	sys_exit_init();
	
	//8个指示灯的操作
	sys_led();
	sys_led_test();
	sys_led_test1();
	
	sys_ledtube_on1();
	sys_ledtube_on2();
	
	//主循环中添加其他需要一直工作的程序
	sys_keynum_ledon(sys_key_single());
	sys_keynum_ledon(sys_key_board());
	
	EA=1;
	
	P1=0x55;       //P1口初始值,预设指示灯状态,测试引脚
	while (1)
	{
		clr_wdg();
	}
}


//c51_gpio.c文件

#include "includes.h"


void sys_led(void)
{
	P1 = 0xFF;		//P1口全部为高电平,对应的LED灯全灭掉,ff换算成二进制是 1111 1111
	P1 = 0x00;		//P1口全部为低电平,对应的LED灯全亮起,ff换算成二进制是 0000 0000
	

}


/********************************************************
函数名称:sys_led_test
函数功能:IO口高低电平测试
入口参数:
出口参数:
修    改:
内    容:
********************************************************/
void sys_led_test(void)
{	
	bit tmp = 0;//中间变量用于获取io口状态
	//控制4个引脚输出
	P10 = 1;
	P11 = 0;
	P12 = 0;
	P13 = 1;
	
	//用另外四个IO口获取状态并测试(指示灯显示)
	tmp = P10;
	P14 = tmp;
	
	tmp = P11;
	P15 = tmp;
	
	tmp = P12;
	P16 = tmp;
	
	tmp = P13;
	P17 = tmp;
	
	
}

/********************************************************
函数名称:sys_led_test
函数功能:led流水灯
入口参数:
出口参数:
修    改:
内    容:
********************************************************/
void sys_led_test1(void)
{
//	delay(30000);//延时程序
	P1<<=1;      //左移一位 该语句等效于 P1=P1<<1
	P1|=0x01;    //最后一位补1,该语句等效于 P1=P1|0x01 符号"|"表示"或"
	if(P1==0xFF) //检测是否移到最左端?"=="表示检测符号2端的值是否相等
	{ 
//		delay(30000);
		P1=0xfe; //重新赋值
	}
}



//c51_ledtube.c文件

#include "includes.h"

// 显示段码值01234567,可对应原理图查看显示不同图形对应的引脚高点电平配置状态
unsigned char const EL[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,\
		                  	 0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F



/********************************************************
函数名称:sys_ledtube_on1
函数功能:点亮一个数码管全为亮起来
入口参数:
出口参数:
修    改:
内    容:
********************************************************/
void sys_ledtube_on1(void)
{
	//根据原理图,将P0口全部输出高电平,P2选择0号数码管
	P0=0xFF;//取显示数据,段码
	P2=0;  	//取位码
}

/********************************************************
函数名称:sys_ledtube_on2
函数功能:显示一组数据
入口参数:
出口参数:
修    改:
内    容:
********************************************************/
static unsigned char ledtube_cnt = 0;
void sys_ledtube_on2(void)
{
	ledtube_cnt++;
	if(ledtube_cnt>7)
	{
		ledtube_cnt = 0;
	}
	P0 = 0x00;				//防止切换数码管瞬间有虚影出现
	P2 = 0x00;
	P0 = EL[ledtube_cnt];	//取显示数据,段码
	P2 = ledtube_cnt;  		//取位码
	
	//根据人眼适应虚影缓冲时间为50ms左右
	//我们调整delay在500以下可以看到明显的看起来是一串数据一起显示
	delay(100); 			
}


/********************************************************
函数名称:sys_keynum_ledon
函数功能:显示按键数值
入口参数:按键数值
出口参数:
修    改:
内    容:
********************************************************/
void sys_keynum_ledon(unsigned char num)
{
	//根据原理图,将P0口全部输出高电平,P2选择0号数码管
	P0=EL[num];//取显示数据,段码
	P2=0;  	//取位码
}



//c51_key.c文件

#include "includes.h"

bit key1=0;   //定义按键位置
bit key2=0;
bit key3=0;
bit key4=0;


/********************************************************
函数名称:sys_key_single
函数功能:按键检测,带有消抖策略
入口参数:
出口参数:按键数值
修    改:
内    容:
********************************************************/
static unsigned char key1_history = 0;//缓存上一次按键的结果
unsigned char sys_key_single(void)
{
	key1=P30;   //定义按键位置
	key2=P31;
	key3=P32;
	key4=P33;

	if(!key1)  //按下相应的按键,数码管显示相应的码值
	{
		delay(1000);
		if(!key1)
		{
			key1_history = 1;
			return 1;
		}
		else
		{
			return key1_history;
		}
	}
	else if(!key2)
	{
		delay(1000);
		if(!key2)
		{
			key1_history = 2;
			return 2;
		}
		else
		{
			return key1_history;
		}
	}
	else if(!key3)
	{
		delay(1000);
		if(!key3)
		{
			key1_history = 3;
			return 3;
		}
		else
		{
			return key1_history;
		}
	}
	else if(!key4)
	{
		delay(1000);
		if(!key4)
		{
			key1_history = 4;
			return 4;
		}
		else
		{
			return key1_history;
		}
	}
	else
	{
		return key1_history;
	}
	
}

unsigned char sys_key_board(void)
{
	unsigned char key = 0x00;
	unsigned char num = 0x00;
	key=keyscan();  //调用键盘扫描
	if(key == 0xFF)
	{
		num = key1_history;
	}
	else
	{
		switch(key)
		{
			case 0xee:num = 0x0;break;//0按下相应的键显示相对应的码值
			case 0xde:num = 0x1;break;//1 按下相应的键显示相对应的码值 
			case 0xbe:num = 0x2;break;//2
			case 0x7e:num = 0x3;break;//3
			case 0xed:num = 0x4;break;//4
			case 0xdd:num = 0x5;break;//5
			case 0xbd:num = 0x6;break;//6
			case 0x7d:num = 0x7;break;//7
			case 0xeb:num = 0x8;break;//8
			case 0xdb:num = 0x9;break;//9
			case 0xbb:num = 0xA;break;//a
			case 0x7b:num = 0xB;break;//b
			case 0xe7:num = 0xC;break;//c
			case 0xd7:num = 0xD;break;//d
			case 0xb7:num = 0xE;break;//e
			case 0x77:num = 0xF;break;//f
			default:num = key1_history; break;
		}
		
		key1_history = num;
	}
	return num;
}


/*------------------------------------------------
              键盘扫描程序
------------------------------------------------*/
unsigned char keyscan(void)  //键盘扫描函数,使用行列反转扫描法
{
	unsigned char cord_h,cord_l;//行列值中间变量
	P3=0x0f;            //行线输出全为0
	cord_h=P3&0x0f;     //读入列线值
	if(cord_h!=0x0f)    //先检测有无按键按下
	{
		delay(100);        //去抖
		if(cord_h!=0x0f)
		{
			cord_h=P3&0x0f;  //读入列线值
			P3=cord_h|0xf0;  //输出当前列线值
			cord_l=P3&0xf0;  //读入行线值
			return(cord_h+cord_l);//键盘最后组合码值
		}
	}
	return(0xff);     //返回该值
}

//c51_timer.c文件

#include "includes.h"




/*------------------------------------------------
                    定时器初始化子程序
------------------------------------------------*/
void sys_timer0_init(void)
{
	TMOD |= 0x01;	  //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响		     
	TH0=0x00;	      //给定初值,这里使用定时器最大值从0开始计数一直到65535溢出
	TL0=0x00;
	//EA=1;            //总中断打开 等最后一个中断打开
	//ET0=1;           //定时器中断打开
	TR0=1;           //定时器开关打开
}

/*------------------------------------------------
                    定时器初始化子程序
------------------------------------------------*/
void sys_timer1_init(void)
{
	TMOD |= 0x20;	  //使用模式2,	     
	TH1=0x05;	      //给定初值,这里使用定时器最大值从5开始计数一直到255溢出
	TL1=0x00;
	//EA=1;            //总中断打开
	//ET1=1;           //定时器中断打开
	TR1=1;           //定时器开关打开
}


/*------------------------------------------------
                    定时器初始化子程序
------------------------------------------------*/
void sys_timer2_init(void)
{
  RCAP2H = 0/256;//
  RCAP2L = 0/256;
  //ET2=1;                     //打开定时器中断
  //EA=1;                      //打开总中断
  TR2=1;                     //打开定时器开关
}




void sys_wdog_init(void)
{ 
	//WDT_CONTR = 0x35;
}

void clr_wdg(void)
{
	//WDT_CONTR = 0x35;
}


/*------------------------------------------------
                 定时器中断子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1
{
	TH0=0x00;		  //重新赋值
	TL0=0x00;

	//sys_led_test1(); //流水灯操作
}


/*------------------------------------------------
                 定时器中断子程序
------------------------------------------------*/
void Timer1_isr(void) interrupt 3
{

	//sys_led_test1(); //流水灯操作
	
}	




/*------------------------------------------------
                 定时器中断子程序
------------------------------------------------*/
void Timer2_isr(void) interrupt 5//定时器2中断
{
    TF2=0;
    //sys_led_test1(); //流水灯操作
}

//c51_exit.c文件


#include "includes.h"




void sys_exit_init(void)
{
	
	EX0=1;         //外部中断0开
	IT0=0;         //电平触发
	//IT0=1;         //边沿触发
	
	EX1=1;         //外部中断1开
	IT1=0;         //电平触发
	//IT1=1;         //边沿触发,IT1=0表示电平触发
}


/*------------------------------------------------
                 外部中断程序
------------------------------------------------*/
void Exit0_isr(void) interrupt 0
{
	//在此处可以添加去抖动程序,防止按键抖动造成错误
	P1=~P1;         
}

/*------------------------------------------------
                 外部中断程序
------------------------------------------------*/
void Exit1_isr(void) interrupt 2
{
	//在此处可以添加去抖动程序,防止按键抖动造成错误
	P1=~P1;
}



//c51_ledtube.h文件

#ifndef __C51_LEDTUBE_H__
#define __C51_LEDTUBE_H__


extern unsigned char const EL[];

extern void sys_ledtube_on1(void);
extern void sys_ledtube_on2(void);

extern void sys_keynum_ledon(unsigned char num);


#endif

//includes.h文件

#ifndef __INCLUDES_H__
#define __INCLUDES_H__

//#include<reg52.h> 

//包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include "STC89C5xRC_RDP.h"

//应用层头文件
#include "c51_gpio.h"
#include "c51_ledtube.h"
#include "c51_key.h"
#include "c51_timer.h"
#include "c51_exit.h"


extern void delay(unsigned int cnt);


#endif


//c51_gpio.h文件

#ifndef __C51_GPIO_H__
#define __C51_GPIO_H__

extern void sys_led(void);
extern void sys_led_test(void);
extern void sys_led_test1(void);

#endif

//c51_key.h文件



#ifndef __C51_KEY_H__
#define __C51_KEY_H__


extern bit key1;   //定义按键位置
extern bit key2;
extern bit key3;
extern bit key4;


extern unsigned char sys_key_single(void);

extern unsigned char sys_key_board(void);
extern unsigned char keyscan(void);  //键盘扫描函数,使用行列反转扫描法

#endif


//c51_timer.h文件



#ifndef __C51_TIMER_H__
#define __C51_TIMER_H__





extern void sys_timer0_init(void);
extern void Timer0_isr(void);
extern void sys_timer1_init(void);
extern void Timer1_isr(void);
extern void sys_timer2_init(void);
extern void Timer2_isr(void);

extern void sys_wdog_init(void);
extern void clr_wdg(void);

#endif

 
//c51_exit.h文件



#ifndef __C51_EXIT_H__
#define __C51_EXIT_H__

extern void sys_exit_init(void);
extern void Exit0_isr(void);
extern void Exit1_isr(void);



#endif

3.2 边沿触发外部中断

更改//c51_exit.c文件中代码

void sys_exit_init(void)
{
	
	EX0=1;         //外部中断0开
	//IT0=0;         //电平触发
	IT0=1;         //边沿触发
	
	EX1=1;         //外部中断1开
	//IT1=0;         //电平触发
	IT1=1;         //边沿触发,IT1=0表示电平触发
}

3.3 Protues仿真

增加了选择开关,用于模仿外部电平信号的变化,SW45用于兼容此引脚用作其他功能时断开。

在这里插入图片描述


4 外部中断总结

单片机外部中断具有广泛的应用用途,常见的包括:

  1. 按键输入:外部中断可用于处理按键输入。通过配置外部中断触发条件为按键的下降沿或上升沿,当用户按下或释放按键时触发中断,可以及时响应按键操作并执行相应的处理逻辑。
  2. 传感器触发:许多传感器(如光敏传感器、温度传感器、加速度传感器等)可以通过外部中断与单片机连接。当传感器检测到特定事件或条件变化时,触发外部中断,单片机可以及时采集传感器数据并进行相应的处理。
  3. 通信接收:外部中断可用于处理串口通信或其他通信接口的数据接收。当单片机接收到外部设备发送的数据时,触发中断以及时处理接收到的数据,例如解析命令或响应数据等。
  4. 定时器溢出:单片机的定时器通常具有溢出中断功能。通过配置定时器溢出中断,可以实现定时任务的执行,例如定时采集数据、定时发送信号等。
  5. 外部事件触发:除了按键和传感器触发外,外部中断还可以处理其他外部事件,如外部信号的变化、外部设备的状态改变等。通过配置相应的触发条件和中断服务程序,可以进行灵活的外部事件处理。
    通过合理应用外部中断,可以提高单片机系统的实时性和响应能力,实现与外部设备或事件的高效交互。具体使用方式和应用场景取决于单片机型号、外部设备的特性以及系统需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1917012.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LLM+Agent技术

&#x1f4a1; Agent可以理解为某种能自主理解、规划决策、执行复杂任务的智能体。Agent 是让 LLM 具备目标实现的能力&#xff0c;并通过自我激励循环来实现这个目标。它可以是并行的&#xff08;同时使用多个提示&#xff0c;试图解决同一个目标&#xff09;和单向的&#xf…

告别中央服务器:Syncthing实现点对点文件同步

介绍 Syncthing 是一款开源的文件同步工具&#xff0c;可让您在多个设备之间同步文件。 它适用于 Mac OS X、Windows、Linux、FreeBSD、Solaris、OpenBSD等系统。 可以通过浏览器访问来配置和监控该应用程序。 Syncthing 具有以下特点: 1、点对点同步 2、无需中央服务器 …

如何从 Windows 照片库恢复删除的照片

数据丢失的主要原因之一是人为错误。更糟糕的是&#xff0c;回收站中没有备份&#xff0c;也没有已删除的文件。在这种情况下&#xff0c;数据恢复或专门的 Windows 图片恢复工具可以帮您恢复已删除的图片。 考虑到这一点&#xff0c;我们将讨论从 Windows 10 上的图库中恢复已…

基于Intel Chainer 和姿势检测的动作识别(人体、面部、手部关键点识别动作识别)

项目概述 目标 开发一个能够实时或近实时识别特定动作的系统&#xff0c;如运动姿势、表情变化或手势控制。实现对人体关键点的精确追踪&#xff0c;以便于分析和理解人的动态行为。 技术栈 Intel硬件&#xff1a;可能使用Intel的高性能计算平台&#xff0c;如Xeon处理器或…

【大数据技术】换新电脑了,如何快速迁移MySQL到新电脑上(含程序+数据),这样既快速又高效,省去了“各种安装+各种配置+各种迁移数据”带来的麻烦和时间

【大数据技术】换新电脑了&#xff0c;如何快速迁移MySQL到新电脑上(含程序数据 背景步骤总结 背景 很久没有写博文了哦&#xff0c;最近我换了新的笔记本,于是需要在新笔记本电脑上搭建MySQL环境&#xff0c;因为我原电脑上是安装的MySQL解压版&#xff0c;故我想偷偷懒&…

基于Android平台开发,购物商城

1. 项目功能思维导图 2. 项目涉及到的技术点 使用SQLite数据库实现数据存储使用CountDownTimer实现启动页倒计时使用SharedPreferences实现记住密码登录使用BottomNavigationView实现底部导航栏使用ActivityFragment实现底部导航栏页面之间切换使用RecyclerViewadapter实现商品…

Java 中的 switch 语句:类型支持与限制

Java 中的 switch 语句&#xff1a;类型支持与限制 1、switch 语句支持的数据类型2、switch 语句不支持的数据类型3、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在 Java 中&#xff0c;switch 语句是一种用于多分支选择的控制结构…

vscode单独设置项目的字符集

vscode有个默认的字符集&#xff0c;直接修改这里的话将会修改整个vscode工具的字符集。如果不同的项目使用不同的字符集&#xff0c;就不能修改这个默认的设置了。而是需要针对每个项目进行修改。 修改方法&#xff1a; 使用shiftctrlp进入settings的菜单页面&#xff0c;点击…

ARM体系结构及接口技术介绍(一)相关概念 寄存器

文章目录 一、ARM相关概念1. 机器码&#xff1a;计算机可以识别的0和1组成的特殊的编码2. 汇编指令&#xff1a;编译器可以将每条汇编指令编译生成特定的计算机可以识别的机器码3. 汇编指令集&#xff1a;很多具有不同功能的汇编指令的集合4. 架构&#xff1a;基于不同的汇编指…

resistronic焊接机RMF10 RE120安装SSK10说明操作

resistronic焊接机RMF10 RE120安装SSK10说明操作

新开发的软件老被系统拦截有什么办法解决吗?

一套新开发的软件要想在windows操作系统畅通无阻&#xff0c;那就需要使用代码签名证书&#xff0c;只要是对软件进行实名从而证明软件发布者身份&#xff0c;确保该软件是一个合法有效的主体开发的&#xff0c;也是让这个软件开发者承担相应的责任。 特别主要如果要获得即时性…

【AI前沿】深度学习:技术、发展与前沿应用

文章目录 一、深度学习的背景与发展1.1 背景1.2 早期发展1.3 突破性进展1.4 近年发展 二、深度学习的基本概念2.1 神经网络2.2 多层感知器&#xff08;MLP&#xff09;2.3 卷积神经网络&#xff08;CNN&#xff09;2.4 循环神经网络&#xff08;RNN&#xff09;2.5 生成对抗网络…

【结构型模式-代理模式】

概述 由于某些原因需要给某对象提供一个代理以控制该对象的访问。这时&#xff0c;访问对象不适合或者不能直接引用目标对象&#xff0c;代理对象作为访问对象与目标对象之间的中介。 Java中的代理按照代理类生成时机不同又分为静态代理和动态代理。静态代理代理类在编译期就生…

Linux--网络设置

目录 一、测试网络连接 1、查看网络接口信息 1.1 ifconfig 命令---查看网络接口信息 1.1.1 ifconfig 网卡 #单独查看某个网卡 1.1.2 ifconfig -a #显示所有活动及非活动的连接 二、修改网络配置文件 三、设置网络接口参数 3.1 启用、禁用网络接口配置 3.2 hostn…

数据库数据恢复—SQL Server数据库由于存放空间不足报错的数据恢复案例

SQL Server数据库数据恢复环境&#xff1a; 某品牌服务器存储中有两组raid5磁盘阵列。操作系统层面跑着SQL Server数据库&#xff0c;SQL Server数据库存放在D盘分区中。 SQL Server数据库故障&#xff1a; 存放SQL Server数据库的D盘分区容量不足&#xff0c;管理员在E盘中生…

Python爬虫速成之路(1):获取网页源代码

hello hello~ &#xff0c;这里是绝命Coding——老白~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#xff1a;绝命Coding-CSDN博客 &a…

LLM-阿里云 DashVector + ModelScope 多模态向量化实时文本搜图实战总结

文章目录 前言步骤图片数据Embedding入库文本检索 完整代码 前言 本文使用阿里云的向量检索服务&#xff08;DashVector&#xff09;&#xff0c;结合 ONE-PEACE多模态模型&#xff0c;构建实时的“文本搜图片”的多模态检索能力。整体流程如下&#xff1a; 多模态数据Embedd…

【python】QWidget父子关系,控件显示优先级原理剖析与应用实战演练

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

变位齿轮的齿高好像不变

通过这个软件的计算&#xff0c;变位尺寸的大小径都会同时变化&#xff0c;从而整个齿高好像没有变化。 下面百度答案

中国AI已遥遥领先

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 种种迹象表明&#xff0c;中国的AI产业是仅次于美国的存在&#xff0c;中国的AI已经遥遥领先&#xff0c;其他国家。 根据中国信息通信研究院发布的报告称&#xff1a; 根据中国信息通信研究院近日发布的《全球…