基于51单片机的电子琴程序设计实现功能设计一个带显示按键

1、设计一个电子琴,利用所给键盘的8个按键,发出8个不同的音调,并在LED数码管上显示相应的音调。8个按键分别代表8个音符,分别连接到P3口的8个接口,共阳极数码管接到P2口,发声模块接到P1.4口。

设计一款显​​示按键序列号的电子键盘,要求如下:

1、设计一个电子键盘,利用给定键盘的8个键发出8种不同的音调,并在LED数码管上显示相应的音调。

2、要求按下按钮发出声音,延时一段时间后松开停止; 如果在前一个按键发声时按下另一个键,前一个按键的声音将停止,后一个按键的声音将开始。

3. 控制按钮简单。

电路设计

如图所示:

电子键盘有8个按钮,每个按钮代表8个音符,分别连接到P3口的8个接口。 共阳极数码管连接到P2端口,声音模块连接到P1.4端口。

编程

我们可以利用单片机的定时器/计数器T0来产生不同频率的方波信号。 每个按钮对应不同的定时器预设值和不同的提示音。

先说一下定时器中断的理解:CPU执行一个机器周期时,最后会自动检查中断是否打开,即每隔几微秒检查一次中断是否打开。 当我们的按钮按下时,TR0置1,中断打开,CPU检测到,调用我们的中断服务程序,并给定时器的高低8位分配一个时间预设值。 时间预设值到达定时器结束。 扬声器没有接收到电压的一段时间。 当定时时间到时,调用CPL P1.4将扬声器接口反转,即给扬声器接口分配高电平。 在中断服务程序中重新分配高八位和低八位。 由于按钮仍然按下并且中断仍然打开,因此重新安装中断服务程序并继续计时。 在此期间,扬声器接口有电压。 定时器结束后,反转,扬声器接口给低电平。 由于CPU执行指令的速度非常快,因此在预设值期间会产生高电平节拍,在定时期间会产生低电平节拍。 这是频率,因为我们定义每个按钮的预设值不同,节拍不同,频率不同,电压的占空比不同,所以可以通过PWM来调节蜂鸣器,所以不同的音调被生产。

定义一个按键扫描函数,在主程序中不断调用按键扫描函数来检测是否有按键被按下。 8个按钮对应8种情况,每种情况有7种按下第二个键的情况。 通过将所有高电平分配给P3端口,当按下按钮时,接口将变为低电平。 当检测到接口为低电平时,循环判断自身接口是否变为高电平。 如果一直按下该键,则一直为低电平,并处于循环状态。 循环过程中,判断是否有其他接口变为低电平。 如果有其他接口变为低电平,则重新分配定时器的高八位和第八位,从而达到同时按下第二位的目的。 当按下该键时,会发出第二个按键的提示音; 如果松开按键,则跳出循环,并调用延迟1s的函数,实现延迟播放功能。 然后关闭中断。 一旦中断设置为0,中断就结束。 扬声器接口将不再倒置,也不会产生频率。 不过,此时的扬声器接口可能处于高电平。 调用延迟函数后,扬声器接口必须设置为0。 ,关闭声音。

实际焊接情况如下:

C语言编程

#include//包含头文件
#define uint unsigned int
#define uchar unsigned char//宏定义
//喇叭引脚定义
sbit speaker=P1^4;
//按钮引脚定义
sbit key1 = P3^0; 																
sbit key2 = P3^1;
sbit key3 = P3^2;
sbit key4 = P3^3;
sbit key5 = P3^4;
sbit key6 = P3^5;
sbit key7 = P3^6;
sbit key8 = P3^7;
//声明两个无符号字符型变量,用于定时器初值的赋值
uchar a;
uchar b;
//延时函数(用于按键松开后延时播放音调)
void delay(uint temp)
{
	uint i, j;
	for (i = 0; i <= temp; i++)
		for (j = 0; j <= 120; j++);
}
void check_key()
{
	P3=0xff;//先赋给P3组口高电平
	switch(P3)//当有按键按下,P3口的状态就会改变
	{
		case 0xfe:  //11111110,第一次扫描到按键1
			P2 = 0xfc;   //11111100    数字1
			a = 0xfb;   //高八位赋时间预设值 
			b = 0xe9;   //低八位赋时间预设值
			EA = 1;     //开中断
			//发声按下的第二个按键(按下第一个按键的后同时按第二个键,发声第二个键的音调)
			//每个case里面循环判断自己的按键是否松开,如果一直被按着,则判断其他7个按键是否按下并改变中断的预初始值。
			while (key1==0)
			{
				//先按1的同时再按下2
				if(key2==0)
				{
					P2 = 0xa2;
					a = 0xfc;
				    b = 0x5c;
				}
				//先按1的同时再按下3
				if (key3 == 0)
				{
					P2 = 0xb0;
					a = 0xfc;
					b = 0xc1;
				}
				//先按1的同时再按下4
				if (key4 == 0)
				{
					P2 = 0x9c;
					a = 0xfc;
					b = 0xef;
				}
				//先按1的同时再按下5
				if (key5 == 0)
				{
					P2 = 0x91;
					a = 0xfd;
					b = 0x45;
				}
				//先按1的同时再按下6
				if (key6 == 0)
				{
					P2 = 0x81;
					a = 0xfd;
					b = 0x92;
				}
				//先按1的同时再按下7
				if (key7 == 0)
				{
					P2 = 0xf8;
					a = 0xfd;
					b = 0xd0;
				}
				//先按1的同时再按下8
				if (key8 == 0)
				{
					P2 = 0x80;
					a = 0xfd;
					b = 0xee;
				}
			}
			//当按键1松开
			P2= 0xff; //数码管不显示
			delay(800);//延时一段时间
			EA = 0; //关中断
			speaker = 0; //关声音
			break;//当第一个按键按下,P3口状态就是11111110,也就是0xfe,就执行后面的P2口点亮对应的LED,并给定时器赋初值,打开中断系统总开关
		
		case 0xfd:     //11111101,当按下按键2
			P2=0xa2;   //10100010 ,数码管显示数字2
			a=0xfc;
			b=0x5c;
			EA=1;
			while (key2 == 0)
			{
				//先按2的同时再按下1
				if(key1 == 0)
				{
					P2 = 0xfc;
					a = 0xfb;
					b = 0xe9;
				}
				//先按2的同时再按下3
				if (key3 == 0)
				{
					P2 = 0xb0;
					a = 0xfc;
					b = 0xc1;
				}
				//先按2的同时再按下4
				if (key4 == 0)
				{
					P2 = 0x9c;
					a = 0xfc;
					b = 0xef;
				}
				//先按2的同时再按下5
				if (key5 == 0)
				{
					P2 = 0x91;
					a = 0xfd;
					b = 0x45;
				}
				//先按2的同时再按下6
				if (key6 == 0)
				{
					P2 = 0x81;
					a = 0xfd;
					b = 0x92;
				}
				//先按2的同时再按下7
				if (key7 == 0)
				{
					P2 = 0xf8;
					a = 0xfd;
					b = 0xd0;
				}
				//先按2的同时再按下8
				if (key8 == 0)
				{
					P2 = 0x80;
					a = 0xfd;
					b = 0xee;
				}
			}
			//当按键2松开
			P2 = 0xff; //数码管不显示
			delay(800);//延时一段时间
			EA = 0; //关中断
			speaker = 0; //关声音
			break;
		
		case 0xfb:   //11111011
			P2=0xb0;  //10110000  数字3
			a=0xfc;
			b=0xc1;
			EA=1;
			while (key3 == 0)
			{
				//先按3的同时再按下1
				if(key1 == 0)
				{
					P2 = 0xfc;
					a = 0xfb;
					b = 0xe9;
				}
				//先按3的同时再按下2
				if(key2 == 0)
				{
					P2 = 0xa2;
					a = 0xfc;
					b = 0x5c;
				}
				//先按3的同时再按下4
				if (key4 == 0)
				{
					P2 = 0x9c;
					a = 0xfc;
					b = 0xef;
				}
				//先按3的同时再按下5
				if (key5 == 0)
				{
					P2 = 0x91;
					a = 0xfd;
					b = 0x45;
				}
				//先按3的同时再按下6
				if (key6 == 0)
				{
					P2 = 0x81;
					a = 0xfd;
					b = 0x92;
				}
				//先按3的同时再按下7
				if (key7 == 0)
				{
					P2 = 0xf8;
					a = 0xfd;
					b = 0xd0;
				}
				//先按3的同时再按下8
				if (key8 == 0)
				{
					P2 = 0x80;
					a = 0xfd;
					b = 0xee;
				}
			}
			//当按键3松开
			P2 = 0xff; //数码管不显示
			delay(800);//延时一段时间
			EA = 0; //关中断
			speaker = 0; //关声音
			break;//同上
	
		case 0xf7:  //11110111
			P2=0x9c;  //10011100  数字4
			a=0xfc;
			b=0xef;
			EA=1;
			while (key4 == 0)
			{
				//先按4的同时再按下1
				if(key1 == 0)
				{
					P2 = 0xfc;
					a = 0xfb;
					b = 0xe9;
				}
				//先按4的同时再按下2
				if(key2 == 0)
				{
					P2 = 0xa2;
					a = 0xfc;
					b = 0x5c;
				}
				//先按4的同时再按下3
				if (key3 == 0)
				{
					P2 = 0xb0;
					a = 0xfc;
					b = 0xc1;
				}
				//先按4的同时再按下5
				if (key5 == 0)
				{
					P2 = 0x91;
					a = 0xfd;
					b = 0x45;
				}
				//先按4的同时再按下6
				if (key6 == 0)
				{
					P2 = 0x81;
					a = 0xfd;
					b = 0x92;
				}
				//先按4的同时再按下7
				if (key7 == 0)
				{
					P2 = 0xf8;
					a = 0xfd;
					b = 0xd0;
				}
				//先按4的同时再按下8
				if (key8 == 0)
				{
					P2 = 0x80;
					a = 0xfd;
					b = 0xee;
				}
			}
			//当按键4松开
			P2 = 0xff; //数码管不显示
			delay(800);//延时一段时间
			EA = 0; //关中断
			speaker = 0; //关声音
			break;
	
		case 0xef:   //11101111,当按下按键5
			P2=0x91;  //10010001 ,数码管显示数字5
			a=0xfd;
			b=0x45;
			EA=1;
			while (key5 == 0)
			{
				//先按5的同时再按下1
				if(key1 == 0)
				{
					P2 = 0xfc;
					a = 0xfb;
					b = 0xe9;
				}
				//先按5的同时再按下2
				if(key2 == 0)
				{
					P2 = 0xa2;
					a = 0xfc;
					b = 0x5c;
				}
				//先按5的同时再按下3
				if (key3 == 0)
				{
					P2 = 0xb0;
					a = 0xfc;
					b = 0xc1;
				}
				//先按5的同时再按下4
				if (key4 == 0)
				{
					P2 = 0x9c;
					a = 0xfc;
					b = 0xef;
				}
				//先按5的同时再按下6
				if (key6 == 0)
				{
					P2 = 0x81;
					a = 0xfd;
					b = 0x92;
				}
				//先按5的同时再按下7
				if (key7 == 0)
				{
					P2 = 0xf8;
					a = 0xfd;
					b = 0xd0;
				}
				//先按5的同时再按下8
				if (key8 == 0)
				{
					P2 = 0x80;
					a = 0xfd;
					b = 0xee;
				}
			}
			//当按键5松开
			P2 = 0xff; //数码管不显示
			delay(800);//延时一段时间
			EA = 0; //关中断
			speaker = 0; //关声音
			break;//P2组为发光二极管组
		case 0xdf:   //11011111,当按下按键6
			P2=0x81;  //10000001  ,数码管显示数字6
			a=0xfd;
			b=0x92;
			EA=1;
			while (key6 == 0)
			{
				//先按6的同时再按下1
				if(key1 == 0)
				{
					P2 = 0xfc;
					a = 0xfb;
					b = 0xe9;
				}
				//先按6的同时再按下2
				if(key2 == 0)
				{
					P2 = 0xa2;
					a = 0xfc;
					b = 0x5c;
				}
				//先按6的同时再按下3
				if (key3 == 0)
				{
					P2 = 0xb0;
					a = 0xfc;
					b = 0xc1;
				}
				//先按6的同时再按下4
				if (key4 == 0)
				{
					P2 = 0x9c;
					a = 0xfc;
					b = 0xef;
				}
				//先按6的同时再按下5
				if (key5 == 0)
				{
					P2 = 0x91;
					a = 0xfd;
					b = 0x45;
				}
				//先按6的同时再按下7
				if (key7 == 0)
				{
					P2 = 0xf8;
					a = 0xfd;
					b = 0xd0;
				}
				//先按6的同时再按下8
				if (key8 == 0)
				{
					P2 = 0x80;
					a = 0xfd;
					b = 0xee;
				}
			}
			//当按键6松开
			P2 = 0xff; //数码管不显示
			delay(800);//延时一段时间
			EA = 0; //关中断
			speaker = 0; //关声音
			break;//注意:EA不能改为TR0
	
		case 0xbf:  //10111111,当按下按钮7
			P2=0xf8;   //11111000 ,数码管显示数字7
			a=0xfd;
			b=0xd0;
			EA=1;
			while (key7 == 0)
			{
				//先按7的同时再按下1
				if(key1 == 0)
				{
					P2 = 0xfc;
					a = 0xfb;
					b = 0xe9;
				}
				//先按7的同时再按下2
				if(key2 == 0)
				{
					P2 = 0xa2;
					a = 0xfc;
					b = 0x5c;
				}
				//先按7的同时再按下3
				if (key3 == 0)
				{
					P2 = 0xb0;
					a = 0xfc;
					b = 0xc1;
				}
				//先按7的同时再按下4
				if (key4 == 0)
				{
					P2 = 0x9c;
					a = 0xfc;
					b = 0xef;
				}
				//先按7的同时再按下5
				if (key5 == 0)
				{
					P2 = 0x91;
					a = 0xfd;
					b = 0x45;
				}
				//先按7的同时再按下6
				if (key6 == 0)
				{
					P2 = 0x81;
					a = 0xfd;
					b = 0x92;
				}
				//先按7的同时再按下8
				if (key8 == 0)
				{
					P2 = 0x80;
					a = 0xfd;
					b = 0xee;
				}
			}
			//当按键7松开
			P2 = 0xff; //数码管不显示
			delay(800);//延时一段时间
			EA = 0; //关中断
			speaker = 0; //关声音
			break;
	
		case 0x7f:  //11111111,当按下按钮8
			P2=0x80;  //10000000, 数码管显示数字8
			a=0xfd;
			b=0xee;
			EA=1;
			while (key8 == 0)
			{
				//先按8的同时再按下1
				if(key1 == 0)
				{
					P2 = 0xfc;
					a = 0xfb;
					b = 0xe9;
				}
				//先按8的同时再按下2
				if(key2 == 0)
				{
					P2 = 0xa2;
					a = 0xfc;
					b = 0x5c;
				}
				//先按8的同时再按下3
				if (key3 == 0)
				{
					P2 = 0xb0;
					a = 0xfc;
					b = 0xc1;
				}
				//先按8的同时再按下4
				if (key4 == 0)
				{
					P2 = 0x9c;
					a = 0xfc;
					b = 0xef;
				}
				//先按8的同时再按下5
				if (key5 == 0)
				{
					P2 = 0x91;
					a = 0xfd;
					b = 0x45;
				}
				//先按8的同时再按下6
				if (key6 == 0)
				{
					P2 = 0x81;
					a = 0xfd;
					b = 0x92;
				}
				//先按8的同时再按下7
				if (key7 == 0)
				{
					P2 = 0xf8;
					a = 0xfd;
					b = 0xd0;
				}
			}
			//当按键8松开
			P2 = 0xff; //数码管不显示
			delay(800);//延时一段时间
			EA = 0; //关中断
			speaker = 0; //关声音
			break;
	
		//当什么都没按下
		default:
			EA=0;
			speaker=0;
			P2=0xff;//当P3口为其他状态时(包括无按键按下和多按键按下)关闭声音输出和LED
	}
}
//中断初始化函数
void init()
{
	TMOD=0x01;//定时器工作方式1
	TH0=a;//定时器0初值的高八位
	TL0=b;//定时器0初值的低八位
	ET0=1;//允许中断
	TR0=1;//打开定时器
	EA=0;
}
//主函数
void main()
{
	init();
	while(1)//进入循环
	{
		check_key();//扫描按键
	}
}
//中断服务程序
void time0() interrupt 1//定时器工作函数
{
	TH0=a;//定时器高八位赋初值
	TL0=b;//定时器低八位赋初值
	speaker=~speaker;//喇叭引脚取反
}

汇编编程


	        ORG    0000H
	        AJMP   INIT	  ;初始化程序
	        ORG    00BH
	        AJMP   INQP	  ;中断程序
	        ORG    0030H
;初始化
INIT:		MOV     TMOD,#01H	;设置定时器工作方式1
            SETB    ET0			 
  			SETB    TR0
			CLR     EA
;主程序
LOOP:	    LCALL   CHECK		 ;调用按键扫描程序
			SJMP  	 LOOP		 ;循环
;按键检查函数
CHECK:      MOV      P3,#0FFH
            ;如果按键被按下,则跳转到相应的CASE
			JNB      P3.0,CASE1
			JNB      P3.1,CASE2
			JNB      P3.2,CASE3
			JNB      P3.3,CASE4
			JNB      P3.4,CASE5
			JNB      P3.5,CASE6
			JNB      P3.6,CASE7
			JNB      P3.7,CASE8
			LJMP     None
			RET
;由于JNB指令只能跳转到-128~128B之间,所以用CASE的程序LJMP过渡到KEY来执行
CASE1:      LJMP	KEY1
			RET
CASE2:      LJMP	KEY2
            RET
CASE3:      LJMP	KEY3
            RET
CASE4:      LJMP	KEY4
            RET
CASE5:      LJMP	KEY5
            RET
CASE6:      LJMP	KEY6
            RET
CASE7:      LJMP	KEY7
            RET
CASE8:      LJMP	KEY8
            RET
;扫描到按键1被按下
KEY1:      MOV     P2,#0FCH	     ;数码管显示数字1
		   MOV     R0,#0FBH		 ;定时器高八位赋值	
		   MOV     R1,#0E9H		 ;定时器低八位赋值
		   SETB    EA			 ;打开中断,播放声音
		   ;函数名First表示第一个按键被按下,后面的数字是是否有其他按键被按下
		   First1:	  JB      P3.0,Disable1     ;判断当前按键是否松开,如果松开跳转到DISABLE1函数(延时和关中断)
					  ;在第一个按键被按下的情况下判断其他按键是否被按下
					  ;判断第二个按键是否被按下	   
					  JB      P3.1,First3	;如果没有被按下则跳到判断下一个按键的函数
					  MOV     P2,#0A2H		;如果第二个按键被按下,数码管显示数字2
					  MOV     R0,#0FCH		;中断预设值赋值
					  MOV     R1,#05CH		;之后循序执行到SJMP First1,再次不断循环自己判断
					  ;判断第三个按键是否被按下
		   First3:	  JB      P3.2,First4	;如果没有被按下则跳到判断下一个按键的函数
					  MOV     P2,#0B0H		;如果第3个按键被按下,数码管显示数字3
					  MOV     R0,#0FCH		;中断预设值赋值
					  MOV     R1,#0C1H		;之后循序执行到SJMP CASE1,再次不断循环自己判断
					  ;判断第四个按键是否被按下
		   First4:     JB      P3.3,First5	;与上面一样
					  MOV     P2,#09CH		
					  MOV     R0,#0FCH		
					  MOV     R1,#0EFH		
					  ;判断第五个按键是否被按下
		   First5:    JB      P3.4,First6
					  MOV     P2,#091H
					  MOV     R0,#0FDH
					  MOV     R1,#045H
					  ;判断第六个按键是否被按下
		   First6:    JB      P3.5,First7
					  MOV     P2,#081H
				 	  MOV     R0,#0FDH
					  MOV     R1,#092H
					  ;判断第七个按键是否被按下
		   First7:    JB      P3.6,First8
					  MOV     P2,#0F8H
					  MOV     R0,#0FDH
					  MOV     R1,#0D0H
					  ;判断第八个按键是否被按下
		   First8:    JB      P3.7,First1	;如果第8个键也没有被按下,则跳转到First1循环重新执行
					  MOV     P2,#080H
					  MOV     R0,#0FDH
				      MOV     R1,#0EEH
		   ;循环扫描自己的按键
		   SJMP     First1
		   ;JB指令只能跳转到-128~123B直接,所以用DISABLE1过渡到DISABLE来延时声音与清除
		   Disable1:     LJMP    Disable	   ;按键松开,调用关闭声音和中断和延时
		   RET
;扫描到按键2被按下
KEY2:			     MOV     P2,#0A2H	 ;数码管显示数字2
			         MOV     R0,#0FCH	 ;定时器高八位赋值
			         MOV     R1,#05CH	 ;定时器低八位赋值
			         SETB    EA			 ;打开中断,播放声音
					 Second2:     JB      P3.1,Disable2	;判断当前按键是否松开,如果松开跳转到Disable2函数(延时和关中断)
					 ;在第二个按键被按下的情况下判断其他按键是否被按下
					 ;判断第1个按键是否被按下	
					 JB      P3.0,Second3
					 MOV     P2,#0FCH
					 MOV     R0,#0FBH
					 MOV     R1,#0E9H
					 ;判断第3个按键是否被按下
		Second3:     JB      P3.2,Second4
					 MOV     P2,#0B0H
					 MOV     R0,#0FCH
					 MOV     R1,#0C1H
					 ;判断第4个按键是否被按下
	    Second4:     JB      P3.3,Second5
					 MOV     P2,#09CH
					 MOV     R0,#0FCH
					 MOV     R1,#0EFH
					 ;判断第5个按键是否被按下
		Second5:     JB      P3.4,Second6
					 MOV     P2,#091H
					 MOV     R0,#0FDH
					 MOV     R1,#045H
					 ;判断第6个按键是否被按下
		Second6:     JB      P3.5,Second7
					 MOV     P2,#081H
					 MOV     R0,#0FDH
					 MOV     R1,#092H
					 ;判断第7个按键是否被按下
		Second7:     JB      P3.6,Second8
					 MOV     P2,#0F8H
					 MOV     R0,#0FDH
					 MOV     R1,#0D0H
					 ;判断第8个按键是否被按下
		Second8:	 JB      P3.7,Second2	 ;如果第8个键也没有被按下,则跳转到Second2循环重新执行
					 MOV     P2,#080H
					 MOV     R0,#0FDH
					 MOV     R1,#0EEH
		;跳转到Second2循环重新执行
		SJMP    Second2
		Disable2:		 LJMP    Disable
		RET
;扫描到按键3被按下
KEY3:			    MOV     P2,#0B0H	;数码管显示数字3
					MOV     R0,#0FCH		;定时器高八位赋值
					MOV     R1,#0C1H		;定时器低八位赋值
					SETB    EA			;打开中断,播放声音
					Third3:     JB      P3.2,Disable3
					;在第三个按键被按下的情况下判断其他按键是否被按下
					;判断第1个按键是否被按下
					JB      P3.0,Third2
					MOV     P2,#0FCH
					MOV     R0,#0FBH
					MOV     R1,#0E9H
					;判断第2个按键是否被按下
		Third2:     JB      P3.1,Third4
					MOV     P2,#0A2H
					MOV     R0,#0FCH
					MOV     R1,#05CH
					;判断第4个按键是否被按下
		Third4:     JB      P3.3,Third5
					MOV     P2,#09CH
					MOV     R0,#0FCH
					MOV     R1,#0EFH
					;判断第5个按键是否被按下
		Third5:     JB      P3.4,Third6
					MOV     P2,#091H
					MOV     R0,#0FDH
					MOV     R1,#045H
					;判断第6个按键是否被按下
		Third6:     JB      P3.5,Third7
					MOV     P2,#081H
					MOV     R0,#0FDH
					MOV     R1,#092H
					;判断第7个按键是否被按下
		Third7:		JB      P3.6,Third8
					MOV     P2,#0F8H
					MOV     R0,#0FDH
					MOV     R1,#0D0H
					;判断第8个按键是否被按下
		Third8:		JB      P3.7,Third3		 ;如果第8个键也没有被按下,则跳转到Third3循环重新执行
					MOV     P2,#080H
					MOV     R0,#0FDH
					MOV     R1,#0EEH
		;跳转到Third3循环重新执行
		SJMP    Third3
		Disable3:		LJMP    Disable
		RET
;扫描到按键4被按下
KEY4:				     MOV     P2,#09CH
					     MOV     R0,#0FCH
					     MOV     R1,#0EFH
					     SETB    EA
			 Forth4:	 JB      P3.3,Disable4
						 ;在第4个按键被按下的情况下判断其他按键是否被按下
					     ;判断第1个按键是否被按下
						 JB      P3.0,Forth2
						 MOV     P2,#0FCH
						 MOV     R0,#0FBH
						 MOV     R1,#0E9H
						 ;判断第2个按键是否被按下
			 Forth2:	 JB      P3.1,Forth3
						 MOV     P2,#0A2H
						 MOV     R0,#0FCH
						 MOV     R1,#05CH
						 ;判断第3个按键是否被按下
			 Forth3:	 JB      P3.2,Forth5
						 MOV     P2,#0B0H
						 MOV     R0,#0FCH
						 MOV     R1,#0C1H
						 ;判断第5个按键是否被按下
			 Forth5:	 JB      P3.4,Forth6
						 MOV     P2,#091H
						 MOV     R0,#0FDH
						 MOV     R1,#045H
						 ;判断第6个按键是否被按下
             Forth6:	 JB      P3.5,Forth7
						 MOV     P2,#081H
						 MOV     R0,#0FDH
						 MOV     R1,#092H
						 ;判断第7个按键是否被按下
			 Forth7:	 JB      P3.6,Forth8
						 MOV     P2,#0F8H
						 MOV     R0,#0FDH
						 MOV     R1,#0D0H
						 ;判断第8个按键是否被按下
             Forth8:	 JB      P3.7,Forth4	   ;如果第8个键也没有被按下,则跳转到Forth4循环重新执行
						 MOV     P2,#080H
						 MOV     R0,#0FDH
						 MOV     R1,#0EEH
			 SJMP    Forth4
			 Disable4:	 LJMP    Disable
			 RET
;扫描到按键5被按下
KEY5:			 		 MOV     P2,#091H
						 MOV     R0,#0FDH
						 MOV     R1,#045H
						 SETB    EA
			 Fifth5:	 JB      P3.4,Disable5
						 ;在第5个按键被按下的情况下判断其他按键是否被按下
					     ;判断第1个按键是否被按下
						 JB      P3.0,Fifth2
						 MOV     P2,#0FCH
						 MOV     R0,#0FBH
						 MOV     R1,#0E9H
						 ;判断第2个按键是否被按下
			 Fifth2:	 JB      P3.1,Fifth3
						 MOV     P2,#0A2H
						 MOV     R0,#0FCH
						 MOV     R1,#05CH
						 ;判断第3个按键是否被按下
             Fifth3:	 JB      P3.2,Fifth4
						 MOV     P2,#0B0H
						 MOV     R0,#0FCH
						 MOV     R1,#0C1H
						 ;判断第4个按键是否被按下
			 Fifth4:	 JB      P3.3,Fifth6
						 MOV     P2,#09CH
						 MOV     R0,#0FCH
						 MOV     R1,#0EFH
						 ;判断第6个按键是否被按下
			 Fifth6:	 JB      P3.5,Fifth7
						 MOV     P2,#081H
						 MOV     R0,#0FDH
						 MOV     R1,#092H
						 ;判断第7个按键是否被按下
			 Fifth7:	 JB      P3.6,Fifth8
						 MOV     P2,#0F8H
						 MOV     R0,#0FDH
						 MOV     R1,#0D0H
						 ;判断第8个按键是否被按下
			 Fifth8:	 JB      P3.7,Fifth5
						 MOV     P2,#080H
						 MOV     R0,#0FDH
						 MOV     R1,#0EEH
						 
			 SJMP    Fifth5
			 Disable5:	 LJMP    Disable
			 RET
;扫描到按键6被按下
KEY6:		           MOV     P2,#081H
					   MOV     R0,#0FDH
					   MOV     R1,#092H
					   SETB    EA
			 Sixth6:   JB      P3.5,Disable6
					   ;在第6个按键被按下的情况下判断其他按键是否被按下
					   ;判断第1个按键是否被按下
					   JB      P3.0,Sixth2
                       MOV     P2,#0FCH
					   MOV     R0,#0FBH
					   MOV     R1,#0E9H
					   ;判断第2个按键是否被按下
			 Sixth2:   JB      P3.1,Sixth3
					   MOV     P2,#0A2H
					   MOV     R0,#0FCH
					   MOV     R1,#05CH
					   ;判断第3个按键是否被按下
			 Sixth3:   JB      P3.2,Sixth4
					   MOV     P2,#0B0H
					   MOV     R0,#0FCH
					   MOV     R1,#0C1H
					   ;判断第4个按键是否被按下
			 Sixth4:   JB      P3.3,Sixth5
					   MOV     P2,#09CH
					   MOV     R0,#0FCH
					   MOV     R1,#0EFH
					   ;判断第5个按键是否被按下
			 Sixth5:   JB      P3.4,Sixth7
					   MOV     P2,#091H
					   MOV     R0,#0FDH
					   MOV     R1,#045H
					   ;判断第7个按键是否被按下
			 Sixth7:   JB      P3.6,Sixth8
					   MOV     P2,#0F8H
					   MOV     R0,#0FDH
					   MOV     R1,#0D0H
					   ;判断第8个按键是否被按下
			 Sixth8:   JB      P3.7,Sixth6
					   MOV     P2,#080H
					   MOV     R0,#0FDH
					   MOV     R1,#0EEH
			 SJMP    Sixth6
			 Disable6:   LJMP    Disable
			 RET
;扫描到按键7被按下
KEY7:			 		MOV     P2,#0F8H
						MOV     R0,#0FDH
						MOV     R1,#0D0H
						SETB    EA
						Seventh7:	JB      P3.6,Disable7
						;在第7个按键被按下的情况下判断其他按键是否被按下
					    ;判断第1个按键是否被按下
						JB      P3.0,Seventh2
						MOV     P2,#0FCH
						MOV     R0,#0FBH
						MOV     R1,#0E9H
						;判断第2个按键是否被按下
			 Seventh2:	JB      P3.1,Seventh3
						MOV     P2,#0A2H
						MOV     R0,#0FCH
						MOV     R1,#05CH
						;判断第3个按键是否被按下
			 Seventh3:	JB      P3.2,Seventh4
						MOV     P2,#0B0H
						MOV     R0,#0FCH
						MOV     R1,#0C1H
						;判断第4个按键是否被按下
			 Seventh4:	JB      P3.3,Seventh5
						MOV     P2,#09CH
						MOV     R0,#0FCH
						MOV     R1,#0EFH
						;判断第5个按键是否被按下
			 Seventh5:	JB      P3.4,Seventh6
						MOV     P2,#091H
						MOV     R0,#0FDH
						MOV     R1,#045H
						;判断第6个按键是否被按下
			 Seventh6:	JB      P3.5,Seventh8
						MOV     P2,#081H
						MOV     R0,#0FDH
						MOV     R1,#092H
						;判断第8个按键是否被按下
			 Seventh8:	JB      P3.7,Seventh7
						MOV     P2,#080H
						MOV     R0,#0FDH
						MOV     R1,#0EEH
			 SJMP    Seventh7
			 Disable7:	SJMP    Disable
			 RET
;扫描到按键8被按下
KEY8:		  	 		MOV     P2,#080H
						MOV     R0,#0FDH
						MOV     R1,#0EEH
						SETB    EA
			 Eighth8:	JB      P3.7,Disable8
						;在第8个按键被按下的情况下判断其他按键是否被按下
					    ;判断第1个按键是否被按下
						JB      P3.0,Eighth2
						MOV     P2,#0FCH
						MOV     R0,#0FBH
						MOV     R1,#0E9H
						;判断第2个按键是否被按下
			 Eighth2:	JB      P3.1,Eighth3
						MOV     P2,#0A2H
						MOV     R0,#0FCH
						MOV     R1,#05CH
						;判断第3个按键是否被按下
			 Eighth3:	JB      P3.2,Eighth4
						MOV     P2,#0B0H
						MOV     R0,#0FCH
						MOV     R1,#0C1H
						;判断第4个按键是否被按下
			 Eighth4:	JB      P3.3,Eighth5
						MOV     P2,#09CH
                        MOV     R0,#0FCH
						MOV     R1,#0EFH
						;判断第5个按键是否被按下
			 Eighth5:	JB      P3.4,Eighth6
						MOV     P2,#091H
						MOV     R0,#0FDH
						MOV     R1,#045H
						;判断第6个按键是否被按下
			 Eighth6:	JB      P3.5,Eighth7
						MOV     P2,#081H
						MOV     R0,#0FDH
						MOV     R1,#092H
						;判断第7个按键是否被按下
			 Eighth7:	JB      P3.6,Eighth8
						MOV     P2,#0F8H
						MOV     R0,#0FDH
						MOV     R1,#0D0H
			 SJMP    Eighth8
			 Disable8:	SJMP    Disable
			 RET
;没有按键被按下
None:		CLR     EA
			CLR     P1.4
			MOV     P2,#0FFH
            RET
;延时1s子程序
DELAY:      MOV    R7,#10    
            DL1:   MOV      R6,#150
            DL2:   MOV      R5,#200
            DJNZ   R5,$
            DJNZ   R6,DL2
            DJNZ   R7,DL1
            RET
;当按下的键松开时调用此函数
Disable:	MOV     P2,#0FFH  ;清除数码管的显示
			LCALL   DELAY	  ;调用延时函数,此时的中断仍然是打开的,即延时期间播放音调
			CLR     EA		  ;关闭中断
			CLR     P1.4	  ;断开声音
			RET	   
;中断服务程序
INQP:    	 MOV     TH0,R0
             MOV     TL0,R1
			 CPL     P1.4
			 RETI
END
单片机

IC设计常见面试题目:前端和后端的设计流程

2024-5-3 20:01:41

单片机

南开大学建党百年特别版录取通知书创意最戳中你心

2024-5-3 21:08:58

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索