📄 16
字号:
;===CH452显示+按键程序,用CH452两线显示=======
;Modified by Hefanghua.
;MCU:STC89C58. DISPLAY:CH452,4位一体共阴数码管(共8位). USB DOWNLOAD:
; CH341. 软件:伟福6000, STC-ISP
; 22.1184MHz(正常速度),11.0592MHZ(较慢显示)
;CH452_ADDR为1(默认拉高)
;目前已测过的键值(HEX值): 40H~47H ,78H~7FH
;无按键按下时为00H(HEX值)。
LEDA BIT P1.2 ;红色LED
LEDB BIT P1.3 ;绿色LED
CH452_CMD DATA 31H
SDA BIT P2.1 ;定义IIC串行数据线,CH452_SDA数码管显示
SCL BIT P2.0 ;定义IIC串行时钟线,CH452_SCL数码管显示
STACK EQU 0FH ;键盘显示的堆栈区栈顶(向上延伸)
;---------------
LED0 EQU 62H ;第0位,最右边的个位
LED1 EQU 63H ;第1位
LED2 EQU 64H ;第2位
LED3 EQU 65H ;第3位
LED4 EQU 66H ;第4位
LED5 EQU 67H ;第5位
LED6 EQU 68H ;第6位
LED7 EQU 69H ;第7位,最高位
KEYBUF EQU 6AH ;存一个按键值
ONEBYTEHEX EQU 6BH
BCDH EQU 6CH
BCDL EQU 6DH
ISP_CONTR EQU 0E7h
ORG 0000H ;复位后单片机入口
JMP MAIN ;进入主程序MAIN
;====================主程序开始===============================
ORG 0100H
MAIN:
CLR EA ;关中断
MOV SP, #7FH ;设置堆栈指针
mov led7,#8
mov led6,#8
mov led5,#8
mov led4,#8
mov led3,#8
mov led2,#8
mov led1,#8
mov led0,#8
LCALL DELAY1s ;等待CH452完全复位
;----------
; 启动CH452的显示驱动和键盘扫描,2线接口,兼容IIC时序
MOV CH452_CMD,#04H ;设置系统参数命令
MOV A,#03H ;01H ;禁止看门狗、键盘功能,使能显示驱动,
CALL CH452_WRITE ;发出命令
MOV CH452_CMD,#05H ;设置显示参数
MOV A,#80H ;BCD译码方式,扫描极限为8. #11000000b为扫描极限是4
CALL CH452_WRITE ;发出命令
MOV A,PCON ;+++++++++++++++
ANL A,#10H ;+++++++++++++++
JZ RUN_ISP ;判POF是否为1 ;+++++++++++++++
Initiate: ;POF=1, 是冷启动--上电复位
ANL PCON,#0EFH ;将POF清0 ;+++++++++++++++
;...... ;初始化
MOV A,#0FFH
MOV P0,A
MOV P1,A ;清端口状态
MOV P2,A
MOV P3,A
CLR A
MOV ONEBYTEHEX,#0FFH
CALL DISPLAY452
CALL cleardisplay
SETB LEDA
SETB LEDB
LCALL DELAY1s
CLR LEDA
CLR LEDB
LCALL DELAY1s
SETB LEDA
SETB LEDB
CALL CH452_READ
LCALL DELAY1s
AGAIN:
;clr leda
SETB LEDB
CALL CH452_READ ;查询式读取按键的值
MOV KEYBUF,A
MOV ONEBYTEHEX,A
call ONEBYTE2BCD ;拆开
mov led3,BCDH
mov led2,BCDL
MOV LED1,#17H ;H
CALL DISPLAY452 ;送CH452显示
;SETB LEDA
CLR LEDB
call KEYSjudge ;判断按键的值,并执行对应程序
CALL cleardisplay
Lcall delay
JMP AGAIN
RUN_ISP:
;软件实现系统复位到ISP区.POF=0, 是热重启--外部手动复位或看门狗复位
ORL PCON,#10H ;将POF置1 ;+++++++++++++++
MOV ISP_CONTR, #11100000B ;复位并进ISP,#01100000B 只是软复位 ;++++++++++
CALL DELAY1S ;++++++++++
JMP Initiate ;ISP结束后自动恢复运行
;==========================================
;==========主程序结束======================
;==========================================
KEYSjudge: ;处理KEYBUF中的键值
CLR EA
CLR C ;清进位标志
MOV A,KEYBUF
jz endkeyscan ;未按按键的处理
SUBB A,#96 ;数据的一半值 20h+40H
JC smaller96 ;若小于60H,则转
larger96: ;≥96
CLR C ;必须先清零,否则计算的结果不正确
MOV A,KEYBUF
SUBB A,#112 ;数据的一半值
JC smaller112
larger112: ;≥112
CLR C
MOV A,KEYBUF
SUBB A,#120 ;数据的一半值
JC smaller120
larger120: ;处理120~127
MOV A,KEYBUF
SUBB A,#120
JZ KEYis120 ;120?
MOV A,KEYBUF
SUBB A,#121
JZ KEYis121 ;121?
MOV A,KEYBUF
SUBB A,#122
JZ KEYis122 ;122?
MOV A,KEYBUF
SUBB A,#123
JZ KEYis123 ;123?
MOV A,KEYBUF
SUBB A,#124
JZ KEYis124 ;124?
MOV A,KEYBUF
SUBB A,#125
JZ KEYis125 ;125?
MOV A,KEYBUF
SUBB A,#126
JZ KEYis126 ;126?
MOV A,KEYBUF
SUBB A,#127
JZ KEYis127 ;127?
jmp errorkey ;其它为错误
;RET
;中间跳转
smaller112: ljmp smallerthan112
smaller120: ljmp smallerthan120
KEYis120: ljmp KEY120
KEYis121: ljmp KEY121
KEYis122: ljmp KEY122
KEYis123: ljmp KEY123
KEYis124: ljmp KEY124
KEYis125: ljmp KEY125
KEYis126: ljmp KEY126
KEYis127: ljmp KEY127
endkeyscan:
nop
ret
;
smaller96:
CLR C
MOV A,KEYBUF
SUBB A,#80 ;数据的一半值
JNC larger80
smaller80:
CLR C
MOV A,KEYBUF
SUBB A,#72 ;数据的一半值
JNC larger72
smaller72: ;处理64~71
CLR C
MOV A,KEYBUF
SUBB A,#64
JZ KEYis64 ;64?
MOV A,KEYBUF
SUBB A,#65
JZ KEYis65 ;65?
MOV A,KEYBUF
SUBB A,#66
JZ KEYis66 ;66?
MOV A,KEYBUF
SUBB A,#67
JZ KEYis67 ;67?
MOV A,KEYBUF
SUBB A,#68
JZ KEYis68 ;68?
MOV A,KEYBUF
SUBB A,#69
JZ KEYis69 ;69?
MOV A,KEYBUF
SUBB A,#70
JZ KEYis70 ;70?
MOV A,KEYBUF
SUBB A,#71
JZ KEYis71 ;71?
jmp errorkey ;错误
;
KEYis64: ljmp KEY64
KEYis65: ljmp KEY65
KEYis66: ljmp KEY66
KEYis67: ljmp KEY67
KEYis68: ljmp KEY68
KEYis69: ljmp KEY69
KEYis70: ljmp KEY70
KEYis71: ljmp KEY71
;
larger80: ;≥80
CLR C
MOV A,KEYBUF
SUBB A,#88
JC smaller88
larger88: ;处理88~95
;......
jmp errorkey
smaller88: ;处理80~87
;......
jmp errorkey
larger72 : ;处理72~79
;......
jmp errorkey
smallerthan112:
CLR C
MOV A,KEYBUF
SUBB A,#104
JC smaller104
larger104: ;处理104~111
;......
jmp errorkey
smaller104: ;处理96~103
;......
jmp errorkey
smallerthan120: ;处理112~119
;......
jmp errorkey
;
;---------------
KEY64:
call run_key01
jmp endkeyscan
KEY65:
call run_key02
jmp endkeyscan
KEY66:
call run_key03
jmp endkeyscan
KEY67:
call run_key04
jmp endkeyscan
KEY68:
call run_key05
jmp endkeyscan
KEY69:
call run_key06
jmp endkeyscan
KEY70:
call run_key07
jmp endkeyscan
KEY71:
call run_key08
jmp endkeyscan
;......
;......
KEY120:
call run_key09
jmp endkeyscan
KEY121:
call run_key10
jmp endkeyscan
KEY122:
call run_key11
jmp endkeyscan
KEY123:
call run_key12
jmp endkeyscan
KEY124:
call run_key13
jmp endkeyscan
KEY125:
call run_key14
jmp endkeyscan
KEY126:
call run_key15
jmp endkeyscan
KEY127:
call run_key16
jmp endkeyscan
RUN_KEY01:
MOV LED7,#10H
MOV LED6,#1
CALL DISPLAY452
RET
RUN_KEY02:
MOV LED7,#10H
MOV LED6,#2
CALL DISPLAY452
RET
RUN_KEY03:
MOV LED7,#10H
MOV LED6,#3
CALL DISPLAY452
RET
RUN_KEY04:
MOV LED7,#10H
MOV LED6,#4
CALL DISPLAY452
RET
RUN_KEY05:
MOV LED7,#10H
MOV LED6,#5
CALL DISPLAY452
RET
RUN_KEY06:
MOV LED7,#10H
MOV LED6,#6
CALL DISPLAY452
RET
RUN_KEY07:
MOV LED7,#10H
MOV LED6,#7
CALL DISPLAY452
RET
RUN_KEY08:
MOV LED7,#10H
MOV LED6,#8
CALL DISPLAY452
RET
RUN_KEY09:
MOV LED7,#10H
MOV LED6,#9
CALL DISPLAY452
RET
RUN_KEY10:
MOV LED7,#1
MOV LED6,#0
CALL DISPLAY452
RET
RUN_KEY11:
MOV LED7,#1
MOV LED6,#1
CALL DISPLAY452
RET
RUN_KEY12:
MOV LED7,#1
MOV LED6,#2
CALL DISPLAY452
RET
RUN_KEY13:
MOV LED7,#1
MOV LED6,#3
CALL DISPLAY452
RET
RUN_KEY14:
MOV LED7,#1
MOV LED6,#4
CALL DISPLAY452
RET
RUN_KEY15:
MOV LED7,#1
MOV LED6,#5
CALL DISPLAY452
RET
RUN_KEY16:
MOV LED7,#1
MOV LED6,#6
CALL DISPLAY452
RET
errorkey:
mov ONEBYTEHEX,keybuf
call ONEBYTE2BCD ;拆开
mov led5,BCDH
mov led4,BCDL
mov led7,#0eh
MOV LED6,#10H
mov led3,#10h
mov led2,#10h
MOV LED1,#10H
MOV LED0,#10H
CALL DISPLAY452 ;送CH452显示
clr leda
SETB LEDB
jmp $ ;停机
;---------------------------------
CH452_I2C_START: SETB SDA
CLR SCL ;通知CH452,将要对其操作,此段时间不要再产生按键中断
CH452_I2C_START1: NOP
NOP ;保留足够的时间给CH452产生中断
NOP
JNB SDA,CH452_I2C_START1 ;CH452正在请求中断?
NOP
NOP
CLR EX1 ;禁止键盘中断,防止开始时被CH452中断而进入中断服务程序中的START
SETB SDA
SETB SCL
NOP
NOP
CLR SDA
NOP
NOP
CLR SCL ;钳住总线,准备发数据
RET
;结束总线子程序
CH452_I2C_STOP: CLR SDA
NOP
NOP
SETB SCL ;发送结束条件的时钟信号
NOP
NOP
SETB SDA ;结束总线
CLR IE1 ;清除中断标志,因为通过SDA输出数据所以会误中断
SETB EX1
RET
;发送字节子程序
;字节数据放入ACC
CH452_IIC_WR: MOV R7,#08H
CH452_IIC_WR1: RLC A ;取数据位
MOV SDA,C
SETB SCL
NOP
NOP
NOP
CLR SCL
DJNZ R7,CH452_IIC_WR1
NOP
SETB SDA
SETB SCL
NOP
NOP
NOP
CLR SCL
RET
;
;读取字节子程序
;读出的值在ACC
CH452_IIC_RD: MOV R7,#08H
CH452_IIC_RD1: SETB SDA
SETB SCL ;时钟线为高,接收数据位
NOP
NOP
MOV C,SDA ;读取数据位
CLR SCL
RLC A ;进行数据位的处理
DJNZ R7,CH452_IIC_RD1 ;未够8位,再来一次
SETB SDA
SETB SCL
NOP
NOP
NOP
CLR SCL
RET
; 无子地址器件写字节数据
; 入口参数: CH452_CMD命令高字节, ACC命令低字节
CH452_WRITE: PUSH ACC
CH452_WRITE1: LCALL CH452_I2C_START ;起动总线
MOV A,CH452_CMD
RLC A
ANL A,#3EH
ORL A,#60H ;当ADDR=0时此值为40H,当ADDR=1时此值为60H
LCALL CH452_IIC_WR ;发送命令高字节
POP ACC ;写数据
LCALL CH452_IIC_WR
LCALL CH452_I2C_STOP
RET
; 读取按键值.返回按键值在ACC中:
CH452_READ: LCALL CH452_I2C_START
MOV A,#6FH ;发送读键盘命令,
;当ADDR=0时此值为4FH,当ADDR=1时此值为6FH
LCALL CH452_IIC_WR ;发送命令高字节
LCALL CH452_IIC_RD ;进行读字节操作
LCALL CH452_I2C_STOP ;结束总线
RET
;---------------------------------
;-------显示----------------------
display452:
MOV CH452_CMD,#0FH
MOV A,LED7 ;7位显示
CALL CH452_WRITE
MOV CH452_CMD,#0EH
MOV A,LED6 ;6位显示
CALL CH452_WRITE
MOV CH452_CMD,#0DH
MOV A,LED5 ;5位显示
CALL CH452_WRITE
MOV CH452_CMD,#0CH
MOV A,LED4 ;4位显示
CALL CH452_WRITE
MOV CH452_CMD,#0BH
MOV A,led3 ;3位显示
CALL CH452_WRITE
MOV CH452_CMD,#0AH
MOV A,led2 ;2位显示
CALL CH452_WRITE
MOV CH452_CMD,#09H
MOV A,led1 ;1位显示
CALL CH452_WRITE
MOV CH452_CMD,#08H
MOV A,led0 ;0位显示
CALL CH452_WRITE
;CH452支持特殊的BCD码:
;11H -| -1 或加号
;12H - 负号减号
;13H = 等于号
;14H [ 左方括号
;15H ] 右方括号
;16H _ 下划线
;17H H 字母 H
;18H L 字母 L
;19H P 字母 P
;1AH . 小数点
;1EH 自定义字符
;其余 空格
ret
cleardisplay: ;BCD译码模式清屏
mov led7,#10H ;7位显示空格
mov led6,#10H ;6位显示空格
mov led5,#10H ;5位显示空格
mov led4,#10H ;4位显示空格
mov led3,#10H ;3位显示空格
mov led2,#10H ;2位显示空格
mov led1,#10H ;1位显示空格
mov led0,#10H ;0位显示空格
ret
ONEBYTE2BCD:
MOV A,ONEBYTEHEX
ANL A,#0F0H
SWAP A
MOV BCDH,A ;得高4位
MOV A,ONEBYTEHEX
ANL A,#0FH
MOV BCDL,A ;得低4位
RET
;----------延时子程序-------------
DELAY1S: MOV R7,#181 ;1秒,22.1184MHz ;#98 ;约1秒,12MHz ,11.0592MHz
LOOP7: MOV R6,#100
LOOP6: NOP
mov R5,#49
DJNZ R5,$
DJNZ R6,LOOP6
DJNZ R7,LOOP7
RET
DELAY: MOV R3,#100
LOOP2: MOV R2,#55
LOOP1: NOP
mov R1,#55
DJNZ R1,$
DJNZ R2,LOOP1
DJNZ R3,LOOP2
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -