汇编语言实现人体感应灯

ORG     0000H
 		LJMP    MAIN
		ORG     0003H								;定时器中断0
		AJMP    WAITKEYBEGIN
		ORG     001BH								;定时器中断1
		AJMP    T1INT
		ORG     0100H
;*********************************************************************************************************************************************************************				 
		S1      EQU    30H
		S2      EQU    31H
		S3      EQU    32H
		S4      EQU    33H
		S5      EQU    34H
		S6      EQU    35H

		SS1     EQU    40H
		SS2     EQU    41H
		SS3     EQU    42H
		SS4     EQU    43H
		SS5     EQU    44H
		SS6     EQU    45H
MAIN:  
		SETB    IT0
		SETB	EX0
		SETB	EA	 
		MOV     SP,     #60H		
		MOV		A,		#4
		ACALL	SENDNUM
		LJMP	WAITPEOPLE

;独立键盘检测********************************************************************************************设置倒计时初值*********************KEYTEST******************************************
WAITKEYBEGIN:
		CJNE	R7,		#01H,	KEYTEST
		SETB	P1.5
		AJMP	NEXTSTEP
KEYTEST:
		MOV     A,	    #0FFH
		MOV     P3,	    A
WAITKEY:
		MOV     A,      P3							;读键盘状态	 
		XRL		A,		#0FFH						;REVERSE
		ANL		A,		#0F0H
		CJNE	A,		#00H,		TESTAGAIN		;不全为0时,有键按下
		SJMP	WAITKEYBEGIN
TESTAGAIN:
		ACALL   DELAY_10MS							;延时10ms
		MOV     A,		P3							;读键盘状态	 
		XRL		A,		#0FFH						;REVERSE
		ANL		A,		#0F0H						;再次读键盘状态
		CJNE	A,		#00H,		RUNKEY			;确实有键按下
		SJMP	WAITKEY
RUNKEY:
		JNB		P3.7,	K4
		JNB		P3.6,	K3
		JNB		P3.5,	K2
		SJMP	WAITKEY
K1:
		MOV     A,		#20
		AJMP	WAITPEOPLE
K2:
		MOV		R7,		#01H
		CLR		P1.5
		SJMP	WAITKEYBEGIN
K3:
		ACALL   ADDNUM
		ACALL	SHOWNUM
		SJMP	WAITKEYBEGIN
K4:
		ACALL	SUBNUM
		ACALL	SHOWNUM
		SJMP	WAITKEYBEGIN
NEXTSTEP:
		RETI

;***************************************************************************************************检测外界信号*******************WAITPEOPLE*****************************************
WAITPEOPLE:	 
		SETB	IT1									;人体感应对应接入的外部中断,设置下降沿触发中断	
WAITCOME: 
		JNB		P2.1,	WAITCOME					;白天输出低电平0,则一直等待,直到输出高电平
		MOV		C,		P2.2						;有声音时P3.2是低电平
		CPL		C
		JC		WAITUP								;C等于1的时候,外部声音输入为0,已经检测到声音,等于一跳转,等待声音结束

		MOV     C,     P3.3						  
		CPL     C				
		JNC		WAITDOWN							;C等于0的时候,外部感应输入为1,已经检测到人体,跳转,等待下降沿到来
		SJMP	WAITPEOPLE

WAITDOWN:
		CLR     P1.1	 							;点亮P1.1指示灯	 
		CLR		P1.7								;点亮P1.7模拟光	   
		JNB		IE1,	WAITDOWN					;IE1=0,下降沿还未到来,继续等待下降沿,等于零转移
		CLR		IE1									;清除人体感应中断请求		 
		SJMP	SETLIGHT							;跳转设置开灯
WAITUP:
		CLR     P1.3	 							;点亮P1.0指示灯
		CLR		P1.7								;点亮P1.7模拟光	 
		SJMP	SETLIGHT							;IE0=1,声音感应信号低电平出现,跳转设置开灯
SETLIGHT:
		ACALL	INT133		
		LJMP	WAITPEOPLE

	
;数码管倒计时显示子程序******************************************************************在调用前往30H,31H送好倒计时初值***************DISPLAYBEGIN*************************
DISPLAYBEGIN:
		MOV     40H,	30H
		MOV     41H,	31H
		MOV     42H,	32H
		MOV     43H,	33H
		MOV     44H,	34H
		MOV     45H,	35H
DISPBEGIN:
		MOV     R6,    #20															 		      	;;;;;;;;;;R6 R6 R6 R6 R6
DISPBEGIN1:	   
		MOV     TMOD,  #01H     	 				;T0工作在定时工作方式1
		MOV     TH0,   #4CH		 					;定时0.05s
		MOV     TL0,   #00H		  
		SETB    TR0             					;开启定时器开始定时
DISP:		    
		MOV     R0,    #40H			 				;要显示的数字存储首地址				       	   ;;;;;;;;;;;;;;;R0 R0 R0 R0 R0
		MOV     R2,    #0DFH 		     			;11011111									 ;;;;;;;;;;;;;;;;;R2 R2 R2 R2 R2
		MOV     R7,    #2		         			;控制循环次数					控制显示的位数;;;;;;;;;;;;;;;;R7 R7 R7 R7 R7  
DISPLAY:
		MOV     A,     R2				 			;选择要亮的数码管										      		R2
		SETB    P2.7					 			;开锁存器
		MOV     P0,    A			     			;为0时选定对应数码管	 		  
		CLR     P2.7					 			;关锁存器
			    
		MOV     A,     @R0			 				;R0存的为要显示的数值										  		R0
			     
		MOV     DPTR,  #SEGTAB		 				;查表获得显示特定数值需要的码  
		MOVC    A,     @A+DPTR		 				;设置要显示的数字
			     
		SETB    P2.6					 			;开锁存器
		MOV     P0,    A			     			;为1时选定对应段				 
		ACALL   DELAY_1MS			     			;延时1ms
		CLR     P2.6					 			;关锁存器
			  	 
		DJNZ    R7,    DISPLOOP		 				;扫描完一个,显示下一个,扫描完六个(R7=0),重新扫描					R7
		LJMP    NEXT
		RET	     
			    
DISPLOOP:	    
		INC     R0									;取下一个数码管要显示的数字     									R0
		MOV     A,      R2							;下一个要亮的数码管									  				R2
		RR      A 
		MOV     R2,     A	
		LJMP    DISPLAY
				 
NEXT:			  
		JNB     TF0,   DISP			  				;;;;;;有没有过0.05s
		CPL     TF0
		DEC     R6 
		CJNE    R6,     #00H,    DISPBEGIN1	 	 	;R6不等于零时转移,说明还没到一秒
		MOV     A,      40H
		CJNE    A,      #00H,    RUNS1	 			;个位还没有减为零跳转
		MOV     A,      41H			     			;个位为零时,判断十位是不是零
		CJNE    A,      #00H,    RUNS2 				;十位不为零跳转
		MOV     A,      #0FFH			 			;关闭数码管										      
		SETB    P2.7					 			;开锁存器
		MOV     P0,    	A			     			;关掉所有数码管	 		  
		CLR     P2.7					 			;关锁存器
		RET	     

RUNS1:		    
		DEC     40H
		LJMP    DISPBEGIN
			    
RUNS2:		    
		DEC     41H
		MOV     40H,   #9
		LJMP    DISPBEGIN



;显示键盘对应数字***************************************************************在调用前往30H,31H送好倒计时初值**************************SHOWNUM**********************************************
SHOWNUM:
		MOV     40H,	30H
		MOV     41H,	31H
		MOV     42H,	32H
		MOV     43H,	33H
		MOV     44H,	34H
		MOV     45H,	35H
DISPNUMBEGIN:
		MOV     R6,    #10															 			   ;;;;;;;;;;R6 R6 R6 R6 R6
DISPNUMBEGIN1:	   
		MOV     TMOD,  #01H     	 				;T0工作在定时工作方式1
		MOV     TH0,   #4CH		 					;定时0.05s
		MOV     TL0,   #00H		  
		SETB    TR0             					;开启定时器开始定时
DISPNUM:		    
		MOV     R0,    #40H			 				;要显示的数字存储首地址				       	   ;;;;;;;;;;;;;;;R0 R0 R0 R0 R0
		MOV     R2,    #0DFH 		     			;11011111									   ;;;;;;;;;;;;;;;R2 R2 R2 R2 R2
		MOV     R7,    #2		         			;控制循环次数				 控制显示的位数    ;;;;;;;;;;;;;;;R7 R7 R7 R7 R7 
DISPLAYNUM:
		MOV     A,     R2				 			;选择要亮的数码管										      R2
		SETB    P2.7					 			;开锁存器
		MOV     P0,    A			     			;为0时选定对应数码管	 		  
		CLR     P2.7					 			;关锁存器
			    
		MOV     A,     @R0			 				;R0存的为要显示的数值										  R0
			     
		MOV     DPTR,  #SEGTAB		 				;查表获得显示特定数值需要的码  
		MOVC    A,     @A+DPTR		 				;设置要显示的数字
			     
		SETB    P2.6					 			;开锁存器
		MOV     P0,    A			     			;为1时选定对应段				 
		ACALL   DELAY_1MS			     			;延时1ms
		CLR     P2.6					 			;关锁存器
			  	 
		DJNZ    R7,    DISPNUMLOOP		 			;扫描完一个,显示下一个,扫描完六个(R7=0),重新扫描			  R7
		LJMP    NEXTNUM
		RET	     
			    
DISPNUMLOOP:	    
		INC     R0									;取下一个数码管要显示的数字     							  R0
		MOV     A,      R2							;下一个要亮的数码管									  		  R2
		RR      A 
		MOV     R2,     A	
		LJMP    DISPLAYNUM
NEXTNUM:			  
		JNB     TF0,   DISPNUM			  			;有没有过0.05s
		CPL     TF0
		DEC     R6 
		CJNE    R6,     #00H,    DISPNUMBEGIN1	 	;R6不等于零时转移,说明还没到一秒
		MOV     A,      #0FFH			 			;关闭数码管										      
		SETB    P2.7					 			;开锁存器
		MOV     P0,    A			     			;关掉所有数码管	 		  
		CLR     P2.7					 			;关锁存器
		RET	   			 	 	 		
				  				 

;延时子程序**********************************************************************延时一毫秒,调用前无需操作******************************DELAY_1MS******************************************
DELAY_1MS:
		MOV	    R3,	 #180			 			;1ms	                   	;;;;;;;;;;;;;;;;;;;;;;;;;;R3 R3 R3 R3 R3
LOOP_1MS:       
		MOV	    R4,	 #1										                 ;;;;;;;;;;;;;;;;;;;;;;;;;R4 R4 R4 R4 R4
		DJNZ    R4,	 $		    															               ;R4
	 	DJNZ    R3,	 LOOP_1MS	        													               ;R3
		RET	    	 


;延时子程序**********************************************************************延时10毫秒,调用前无需操作*****************************DELAY_10MS*******************************************
DELAY_10MS:
		MOV	    R3,	 #180			 			;1ms		                ;;;;;;;;;;;;;;;;;;;;;;;;;;R3 R3 R3 R3 R3
LOOP_10MS:       
		MOV	    R4,	 #24										             ;;;;;;;;;;;;;;;;;;;;;;;;;R4 R4 R4 R4 R4
		DJNZ    R4,	 $		    														               	   ;R4
	 	DJNZ    R3,	 LOOP_10MS	        													               ;R3
		RET	    	 
			    

;定时器1中断******************************************************************中断计时50ms,中断前需设置好R5的值**************************T1INT**********************************************
T1INT:
		MOV     TH1,  #4CH	     	 				;定时R5个0.05s   
		MOV     TL1,  #00H
		DJNZ    R5,   T1INTLOOP																               ;R5
		;MOV     P1,   #44H
		CLR     TR1
T1INTLOOP:	   
		RETI   


;根据按键值,设置显示缓冲区中的数字***************************************************调用前需要设置好A的值*******************************SENDNUM*****************************************
SENDNUM:
		MOV		B,		#10
		DIV		AB              					;当前值除以10
		MOV		31H,	A							;得出的商送给十位
		MOV		30H,	B							;得出的余数送给个位
		RET


;控制关灯子程序****************************************************************************************************************************INT133*******************
INT133:
		SETB	P1.3								;关指示灯	 
		SETB	P1.1								;关指示灯
		ACALL	DISPLAYBEGIN						;延时,同时数码管显示倒计时
		SETB	P1.7								;关模拟灯
		RET
;************************************************************************************************************************************************************
ADDNUM:												;加一
		MOV		R6,		30H							;个位
		MOV		R7,		31H							;十位
		CJNE	R6,		#09,		ADDONE			;不等于9的时候直接加一
		CJNE	R7,		#09,		ADDONEONE		;十位不是9的时候加一     不相等跳转
		SJMP	ASENDBACK							;十位是9,返回
ADDONEONE:
		INC		R7									;个位等于9的时候给十位加一
		MOV		R6,		#00H
		SJMP	ASENDBACK
ADDONE:
		INC		R6
ASENDBACK:
		MOV		30H,	R6
		MOV		31H,	R7
		RET	
;*************************************************************************************************************************************************************		
SUBNUM:
		MOV		R6,		30H							;个位
		MOV		R7,		31H							;十位
		CJNE	R6,		#00,		SUBONE			;不等于0的时候直接减一
		CJNE	R7,		#00,		SUBONEONE		;十位不等于零的时候,给十位减一
		SJMP	SSENDBACK
SUBONEONE:
		DEC		R7									;等于0的时候给十位减一
		MOV		R6,		#09H
		SJMP	SSENDBACK
SUBONE:
		DEC		R6
SSENDBACK:
		MOV		30H,	R6
		MOV		31H,	R7
		RET					   
;数码管显示数字表*************************************************************************数字对应的BCD码表**********************************SEGTAB**************************************
SEGTAB:		    
		DB      3FH,06H,5BH,4FH,66H     			;0,1,2,3,4
		DB	    6DH,7DH,07H,7FH,6FH     			;5,6,7,8,9
  			   
		END	     
上一篇:i7 11600h和r7 5800h哪个好


下一篇:[PTA] [数据结构] R7-2 括号匹配 [c++实现] [思路分享]