作者:未知 来源:89s52.cn
;***************************;
; 数控调频台控制器 ;
;***************************;
;
;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 ;程序结束