www.pudn.com > xk.rar > xk.ASM


;***************************; 
;     数控调频台控制器      ; 
;***************************; 
; 
;26H-29H放显示小数位、个位、十位、百位BCD码数,24H-25H放频率控制数据(十六进制) 
; 
             CONBITL  EQU  21H  ;频率控制字节低8位 
             CONBITH  EQU  22H  ;频率控制字节高8位 
             KEYWORD  EQU  23H  ;存放键扫描时P1口值 
; 
; 
              ORG	0000H   ;程序开始地址 
              LJMP      START    ;转START执行 
              ORG 	0003H       ; 
              RETI       		;不用中断程序 
              ORG 	000BH       ; 
	      RETI       		; 不用中断程序 
              ORG 	0013H       ; 
	      RETI       		; 不用中断程序 
	      ORG 	001BH       ; 
	      RETI       		; 不用中断程序 
	      ORG 	0023H       ; 
	      RETI       		; 不用中断程序 
	      ORG	 002BH      ; 
 	      RETI       		; 不用中断程序 
; 
;初始化程序 
CLEARMEN:    MOV   R0,#20H       ;20H-29H循环清0 
             MOV   R1,#0AH       ; 
CLEARLOOP:   MOV   @R0,#00H      ; 
             INC   R0       		 ; 
             DJNZ  R1,CLEARLOOP  ; 
             MOV   P0,#0FFH      ;四端口置1 
             MOV   P1,#0FFH      ; 
             MOV   P2,#0FFH      ; 
             MOV   P3,#0FFH      ; 
             CLR   P3.0       	;BH1415禁止操作 
             CLR   P3.1       	; 
             CLR   P3.2       	; 
             LCALL KEYFUN15      ;置立体声发射方式,开立体声发射指示灯 
CLEAR1:      MOV   PCON,#00H    	;控制寄存器清0 
             MOV   29H,#00H       	; 置初始值为88MHZ(显示为088.0) 
             MOV   28H,#08H   		; 
             MOV   27H,#08H       	; 
             MOV   26H,#00H       	; 
             LCALL DISPUPDAT    		;写入BH1415芯片(修改发送频率) 
             RET       				;子程序返回 
; 
;主程序 
START:       LCALL  CLEARMEN       	;上电初始化 
MAIN:        LCALL  KEYWORK        	;调查键子程序 
             LCALL  DISPLAY        	;LED显示一次 
             AJMP   MAIN       		;转MAIN循环 
             NOP       				;PC出错处理 
             NOP       				; 
             AJMP   START       		;重新初始化 
; 
; 4*4行列扫描查键子程序 
KEYWORK:     MOV    P1,#0FFH     	; 置P1口为输入状态 
             CLR    P1.0       		;扫描第一行(第一行为0) 
             MOV    A,P1       		;读入P1口值 
             ANL    A,#0F0H       	;低四位为0 
             CJNE   A,#0F0H,KEYCON  ;高四位不为全1(有键按下)转KEYCOON 
             SETB   P1.0       		; 扫描第二行(第二行为0) 
             CLR    P1.1       		; 
             MOV    A,P1       		; 读入P1口值 
             ANL    A,#0F0H       	; 低四位为0 
             CJNE   A,#0F0H,KEYCON  ; 高四位不为全1(有键按下)转KEYCOON 
             SETB   P1.1       		; 扫描第三行(第三行为0) 
             CLR    P1.2       		; 
             MOV    A,P1       		; 读入P1口值 
             ANL    A,#0F0H       	; 低四位为0 
             CJNE   A,#0F0H,KEYCON   ; 高四位不为全1(有键按下)转KEYCOON 
             SETB   P1.2       		; 扫描第四行(第四行为0) 
             CLR    P1.3       		; 
             MOV    A,P1       		; 读入P1口值 
             ANL    A,#0F0H       	; 低四位为0 
             CJNE   A,#0F0H,KEYCON   ; 高四位不为全1(有键按下)转KEYCOON 
             SETB   P1.3       		;结束行扫描 
             RET       				;子程序返回 
KEYCON:      LCALL  DL10MS          ;消抖处理 
             MOV    A,P1       		;再读入P1口值 
             ANL    A,#0F0H       	; 低四位为0 
             CJNE   A,#0F0H,KEYCHE   ; 高四位不为全1,确有键按下,转KEYCHE 
KEYOUT:      RET       				;干扰,子程序返回 
KEYCHE:      MOV    A,P1       		;读P1口值 
             MOV    KEYWORD,A        ;放入23H暂存 
CJLOOP:      LCALL  DISPLAY       	;调显示子程序 
             MOV    A,P1       		;读P1口值 
             ANL    A,#0F0H       	;低四位为0 
             CJNE   A,#0F0H,CJLOOP   ;高四位为全1(键还按着),转CJLOOP等待释放 
             MOV    R7,#00H       	;键释放,置R7初值为#00H(查表次数) 
             MOV    DPTR,#KEYTAB     ;取键值表首址 
CHEKEYLOOP:  MOV    A,R7       		;查表次数入A 
             MOVC    A,@A+DPTR       ;查表 
             XRL    A,KEYWORD       	;查表值与P1口读入值比较 
             JZ     KEYOK       		;为0(相等)转KEYOK 
             INC    R7       			;不等,查表次数加1 
             CJNE   R7,#10H,CHEKEYLOOP   ;查表次数不超过16次转CHEKEYLOOP再查 
             RET       					;16次到,退出 
; 
KEYOK:       MOV    A,R7       		;查表次数入A(即键号值) 
             MOV    B,A       		;放入B 
             RL	    A       			;左移 
	     ADD    A,B       		;相加(键号乘3处理JMP 3字节指令) 
	     MOV    DPTR,#KEYFUNTAB	;取键功能散转表首址 
	     JMP    @A+DPTR       	;查表 
KEYFUNTAB:   LJMP   KEYFUN00       	; 键功能散转表。跳至0号键功能程序 
	     LJMP   KEYFUN01       	; 跳至01号键功能程序 
             LJMP   KEYFUN02       	; 跳至02号键功能程序 
	     LJMP   KEYFUN03 
             LJMP   KEYFUN04 
	     LJMP   KEYFUN05 
             LJMP   KEYFUN06 
	     LJMP   KEYFUN07 
             LJMP   KEYFUN08 
	     LJMP   KEYFUN09 
             LJMP   KEYFUN10 
	     LJMP   KEYFUN11 
             LJMP   KEYFUN12 
	     LJMP   KEYFUN13 
             LJMP   KEYFUN14 
	     LJMP   KEYFUN15       	; 跳至15号键功能程序 
             RET       				;散转出错返回 
; 
;键号对应P1口数值表(同时按下两键为无效操作) 
KEYTAB:      DB     0EEH,0DEH,0BEH,7EH,0EDH,0DDH,0BDH,7DH 
             DB    0EBH,0DBH,0BBH,7BH,0E7H,0D7H,0B7H,77H,0FFH,0FFH 
; 
;0号键功能程序 
KEYFUN00:    INC    29H          	;百位数加1 
             MOV    A,29H        	;入A 
             CLR    C         		;清进位标志 
             CJNE   A,#02H,FUN00     ; 
FUN00:       JC     FUN00OUT         ;百位小于2转FUNOO0UT 
             MOV    29H,#00H         ;大于等于2清为0(百位只能是0或1) 
FUN00OUT:    MOV    A,29H       		; 判断百位是0还是1 
             XRL    A,#01H			; 
             JNZ     F00OUT1			;若百位为0转FOOOUT1 
             MOV    28H,#00H			;若百位为1,十位为0 
             AJMP   F00OUT			; 
F00OUT1:     MOV    28H,#08H			;若百位为0,十位数改为8 
F00OUT:      LCALL  DISPUPDAT       ;写入控制芯片(修改发射频率) 
             RET						;返回 
; 
;01号键功能程序 
KEYFUN01:    INC    28H				;十位数加1 
             MOV    A,28H			;入A 
             CLR    C				;清进位标志 
             CJNE   A,#0AH,FUN01		;判断是否小于10 
FUN01:       JC     FUN01OUT			;十位数小于10转FUN01OUT 
             MOV    28H,#00H			;十位数大于或等于10清为0 
FUN01OUT:    MOV    A,29H			;判断百位数是0不是1 
             XRL    A,#01H			; 
             JNZ     F01OUT			; 
             MOV    28H,#00H			;百位数为1时,十位数为0 
             AJMP   F001OUT			; 
F01OUT:      MOV    A,28H     		;百 位为0时,十位数只能是8或9 
             XRL    A,#08H			;判断是不是8 
             JZ     F001OUT			;十位数是8转F001OUT 
             MOV    A,28H			; 
             XRL    A,#09H			;判断是不是9 
             JZ     F001OUT			;十位数是9转F001OUT 
             MOV    28H,#08H			;不是8也不是9,十位赋值为8 
F001OUT:     LCALL  DISPUPDAT       ;写入控制芯片(修改发射频率) 
             RET						;返回 
; 
;02号键功能程序 
KEYFUN02:    INC    27H				;个位数加1 
             MOV    A,27H			; 
             CLR    C				; 
             CJNE   A,#0AH,FUN02		;判断是否小于10 
FUN02:       JC     FUN02OUT			;小于10转FUN02OUT 
             MOV    27H,#00H			;大于或等于10清为0 
FUN02OUT:    LCALL  DISPUPDAT       ;写入控制芯片(修改发射频率) 
             RET						; 
; 
;03号键功能程序 
KEYFUN03:    INC    26H				;个位数加1 
             MOV    A,26H			; 
             CLR    C				; 
             CJNE   A,#0AH,FUN03		;判断是不小于10 
FUN03:       JC     FUN03OUT			;小于10转FUN03OUT 
             MOV    26H,#00H			;大于或等于10清为0 
FUN03OUT:    LCALL  DISPUPDAT       ;写入控制芯片(修改发射频率) 
             RET      				;返回 
; 
;04号键功能程序(频率预置键) 
KEYFUN04:    MOV   29H,#01H       ; 预置109.0MHZ发射频率 
             MOV   28H,#00H 
             MOV   27H,#09H 
             MOV   26H,#00H 
             LCALL  DISPUPDAT       ;写入控制芯片(修改发射频率) 
             RET 
; 
;05号键功能程序(频率预置键) 
KEYFUN05:    MOV   29H,#01H       ; 预置108.0MHZ发射频率 
             MOV   28H,#00H 
             MOV   27H,#08H 
             MOV   26H,#00H 
             LCALL  DISPUPDAT       ;写入控制芯片(修改发射频率) 
             RET 
; 
;06号键功能程序(频率预置键) 
KEYFUN06:    MOV   29H,#01H       ; 预置105.0MHZ发射频率 
             MOV   28H,#00H 
             MOV   27H,#05H 
             MOV   26H,#00H 
             LCALL  DISPUPDAT       ;写入控制芯片(修改发射频率) 
             RET 
; 
;07号键功能程序(频率预置键) 
KEYFUN07:    MOV   29H,#01H       ; 预置100.0MHZ发射频率 
             MOV   28H,#00H 
             MOV   27H,#00H 
             MOV   26H,#00H 
             LCALL  DISPUPDAT       ;写入控制芯片(修改发射频率) 
             RET 
; 
;08号键功能程序(频率预置键) 
KEYFUN08:    MOV   29H,#00H        ; 预置98.0MHZ发射频率 
             MOV   28H,#09H 
             MOV   27H,#08H 
             MOV   26H,#00H 
             LCALL  DISPUPDAT       ;写入控制芯片(修改发射频率) 
             RET 
; 
;09号键功能程序(频率预置键) 
KEYFUN09:    MOV   29H,#00H         ; 预置96.0MHZ发射频率 
             MOV   28H,#09H 
             MOV   27H,#06H 
             MOV   26H,#00H 
             LCALL  DISPUPDAT       ;写入控制芯片(修改发射频率) 
             RET 
; 
;10号键功能程序(频率预置键) 
KEYFUN10:    MOV   29H,#00H         ; 预置94.0MHZ发射频率 
             MOV   28H,#09H 
             MOV   27H,#04H 
             MOV   26H,#00H 
             LCALL  DISPUPDAT       ;写入控制芯片(修改发射频率) 
             RET 
; 
;11号键功能程序(频率预置键) 
KEYFUN11:    MOV   29H,#00H         ; 预置92.0MHZ发射频率 
             MOV   28H,#09H 
             MOV   27H,#02H 
             MOV   26H,#00H 
             LCALL  DISPUPDAT       ;写入控制芯片(修改发射频率) 
             RET 
; 
;12号键功能程序(频率预置键) 
KEYFUN12:    MOV   29H,#00H         ; 预置90.0MHZ发射频率 
             MOV   28H,#09H 
             MOV   27H,#00H 
             MOV   26H,#00H 
             LCALL  DISPUPDAT       ;写入控制芯片(修改发射频率) 
             RET 
; 
;13号键功能程序(频率预置键) 
KEYFUN13:    MOV   29H,#00H         ; 预置88.0MHZ发射频率 
             MOV   28H,#08H 
             MOV   27H,#08H 
             MOV   26H,#00H 
             LCALL  DISPUPDAT       ;写入控制芯片(修改发射频率) 
             RET 
; 
;14号键功能程序(频率预置键)        ; 预置87.0MHZ发射频率 
KEYFUN14:    MOV   29H,#00H 
             MOV   28H,#08H 
             MOV   27H,#07H 
             MOV   26H,#08H 
             LCALL  DISPUPDAT       ;写入控制芯片(修改发射频率) 
             RET 
; 
;15号键功能程序(立体声/单声道设置键) 
KEYFUN15:    CPL   03H         		;立体/单声标志取反 
             JNB    03H,MONO   		;为0转单声道MONO 
             CLR    P3.3   			;为1开立体声指示灯 
             LCALL  PUTBIT   		;发送控制字至BH1415 
             RET   					;返回 
MONO:        SETB   P3.3   			;关立体声指示灯 
             LCALL  PUTBIT   		;发控制字至BH1415 
             RET   					;返回 
; 
; 将BCD码转为十六进制数,与5位控制码合成操作码,写入控制芯片 
DISPUPDAT:   LCALL  BCDB       		; 调BCD码转为十六进制数程序 
             LCALL  CONCOMMAND  		; 调与5位控制码合成操作码程序 
             LCALL  PUTBIT       	; 发控制字至BH1415 
             RET   					;返回 
; 
; 将BCD码转为十六进制数程序 
BCDB:        MOV    CONBITL,#00H   	; 控制字清0 
             MOV    CONBITH,#00H   	; 控制字清0 
             MOV    CONBITL,26H   	;小数位数放入控制字低8位 
             MOV    A,27H   			;个位数乘10操作 
             MOV    B,#10   			; 
             LCALL  MULLOOP   		;调乘法子程序 
             MOV    A,28H   			;十位数乘100操作 
             MOV    B,#100   		; 
             LCALL  MULLOOP   		; 调乘法子程序 
             MOV    A,29H   			; 
             JNZ    ADD3E8   		;百位数为1转ADD3E8(加1000操作) 
             RET   					; 百位数为0退出 
ADD3E8:      CLR    C   				;清进位档标志 
             MOV    A,#0E8H   			;低8位加法 
             ADD    A,CONBITL   			;累加 
             MOV    CONBITL,A   			;放回CONBITL 
             MOV    A,#03H   			; 高8位加法 
             ADDC   A,CONBITH   			;控制字高8位处理 
             MOV    CONBITH,A   			;放回CONBITH 
             RET   						;返回 
; 
;乘法及累加处理程序(将四位显示的十进制BCD码转为1个二进制数) 
MULLOOP:     MUL    AB   				;乘法 
             CLR    C   					;清进位标志 
             ADD    A,CONBITL   			;积低8位与CONBITL相加 
             MOV    CONBITL,A   			;放回CONBITL 
             MOV    A,CONBITH   			; 
             ADDC   A,B   				;积高8位与CONBITH带进位累加 
             MOV    CONBITH,A   			;放回CONBITH 
             RET   						;返回 
; 
;频率控制数据与5位控制码合成BH1415控制字 
CONCOMMAND:   ANL   CONBITH,#07H   		;高四位为0 
             MOV   A,20H   				;控制字放入A 
             ORL   A,CONBITH   			;合成控制字 
             MOV   CONBITH,A   			;放回CONBITH 
             RET   						;返回 
; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;;           显示程序                  ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;共阳LED显示,P0口输出段码,P2口输出扫描字 
DISPLAY:     MOV R1,#26H   				;显示首址 
             MOV R5,#0FEH   				;设扫描字 
PLAY:        MOV A,R5   					;放入A 
             MOV P2,A   					;P2口输出 
             MOV A,@R1   				;取显示数据 
             MOV DPTR,#TAB   			;取段码表首址 
             MOVC A,@A+DPTR   			;查段码 
             MOV P0,A   					;从P0输出 
             MOV A,R5   					;读入扫描字 
             JB ACC.1,PLAY1   			; 不是十位(LED),不显示小数点 
             CLR P0.7   					;是十位,显示小数点 
PLAY1:       LCALL DL1MS   				;点亮1毫秒 
             INC R1   					;指向下一显示数据 
             JNB ACC.3,ENDOUT   			;是第四位LED,退出 
             RL A   						;不是,左移一位 
             MOV R5,A   					;放回R5 
             SETB  P0.7   				;关小数点 
             AJMP PLAY   				;转PLAY循环 
ENDOUT:      MOV  P2,#0FFH   			;显示结束,关显示输出口 
             MOV  P0,#0FFH   			; 
             RET   						;返回 
; 
;0-9共阳段码表 
TAB: DB  0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH,0FFH 
; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
;;           发送控制字节子程序        ;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
; 
PUTBIT:      MOV   A,CONBITL   			;低8位控制字入A 
             SETB  P3.2   				;BH1415使能(允许写) 
             LCALL PUT   				;发送8位 
             MOV   A,CONBITH   			; 高8位控制字入A 
             LCALL PUT   				; 发送8位 
             CLR   P3.2   				; BH1415写禁止 
             CLR   P3.0   				;复位 
             CLR   P3.1   				;复位 
             RET   						;返回 
; 
;字节发送子程序 
PUT:         MOV   R3,#8   				;发送8位控制 
             CLR   C   					;清C 
PUT1:        RRC   A   					;带进位位右移(先发低位) 
             MOV   P3.0,C   				;低位送至P3.0口 
             NOP   						;延时4微秒 
             NOP   						; 
             NOP   						; 
             NOP   						; 
             SETB  P3.1   				;锁存数据(上升沿时锁存数据) 
             NOP   						;延时4微秒 
             NOP   						; 
             NOP   						; 
             NOP   						; 
             CLR   P3.1   				; 
             DJNZ  R3,PUT1   			;8位未发完转PUT1再发 
             RET   						; 8位发完结束 
; 
;513微秒延时子程序 
DL513:       MOV   R3,#0FFH 
DL513LOOP:   DJNZ  R3,DL513LOOP 
             RET 
; 
;1毫秒延时子程序(LED点亮用) 
DL1MS:       MOV   R4,#02H 
DL1MSLOOP:   LCALL DL513 
             DJNZ  R4,DL1MSLOOP 
             RET 
; 
;10毫秒延时子程序(消抖动用) 
DL10MS:      MOV   R6,#0AH 
DL10MSLOOP:  LCALL DL1MS 
             DJNZ  R6,DL10MSLOOP 
             RET 
; 
; 
             END   							;程序结束