📄 ch452w2.asm
字号:
;****************************
; Website: http://wch.cn
; Email: tech@wch.cn
; Author: W.ch 2005.4
;CH452 的真正2 线接口
;****************************
; MCS51 24MHz 频率降低则可以适当减少CH452_SCL CH452_SDA 之间的延时
;CH452 的真正2 线接口,含低电平脉冲按键中断在内,只需要2 个I/O 引脚,兼容IIC 时序
;****************************************************************************
STACK EQU 0FH ;堆栈区栈顶(向上延伸)
CH452_SCL BIT P1.7
CH452_SDA BIT P3.3 ;用来接收按键产生的中断
;CH452_ADDR BIT P1.5
; 暂存两个字节的命令的高8位
CH452_CMD DATA 31H
;ACC ;命令的低字节
ORG 0000H ;复位后单片机入口
LJMP MAIN
ORG 0013H ;CH452中断,键盘中断后将通知PC机应用层
LJMP CH452_INTER
ORG 0100H
CH452_INTER:
PUSH PSW
PUSH ACC
PUSH 07H ;R7
CALL CH452_READ
CLR TI
MOV SBUF,A
JNB TI,$
CLR TI
CPL P1.0
POP 07H
POP ACC
POP PSW
RETI
MAIN: CLR EA ;关中断
MOV SP,#STACK ;置堆栈初值
MOV A,#0FFH
MOV P0,A
MOV P1,A ;清端口状态
MOV P2,A
MOV P3,A
CLR A
CALL DELAY
MOV SCON,#50H
MOV PCON,#80H
MOV TMOD,#21H
MOV TH1,#0F3H ;24MHz晶振, 9600bps
SETB TR1
CLR RI
CLR TI
;设置CH452按键中断
CLR IE1
SETB EX1
CLR P1.0
;
; CALL CH452_READ ;读取CH452的版本号,正式应用时不需要。
; CLR TI
; MOV SBUF,A
; JNB TI,$
; CLR TI
SETB EA ;允许中断
CALL DELAY
; 初始化
; 启动CH452的显示驱动和键盘扫描
MOV CH452_CMD,#04H ;设置系统参数命令
MOV A,#03H ;禁止看门狗,使能键盘功能,使能显示驱动,
CALL CH452_WRITE ;发出命令
MOV CH452_CMD,#05H ;设置显示参数
MOV A,#80H ;BCD译码方式,扫描极限为8
CALL CH452_WRITE ;发出命令
MOV CH452_CMD,#08H
MOV A,#00H ;0位显示0
CALL CH452_WRITE
MOV CH452_CMD,#09H
MOV A,#01H ;1位显示1
CALL CH452_WRITE
MOV CH452_CMD,#0AH
MOV A,#02H ;2位显示2
CALL CH452_WRITE
MOV CH452_CMD,#0BH
MOV A,#03H ;3位显示3
CALL CH452_WRITE
MOV CH452_CMD,#0CH
MOV A,#04H ;4位显示4
CALL CH452_WRITE
MOV CH452_CMD,#0DH
MOV A,#05H ;5位显示5
CALL CH452_WRITE
MOV CH452_CMD,#0EH
MOV A,#06H ;6位显示6
CALL CH452_WRITE
MOV CH452_CMD,#0FH
MOV A,#07H ;7位显示7
CALL CH452_WRITE
;
AGAIN: CLR RI ;接收命令
JNB RI,$
MOV A,SBUF
CLR RI
MOV CH452_CMD,A
ANL A,#0E0H
JNZ AGAIN ;无效命令码
JNB RI,$
MOV A,SBUF
CLR RI
CALL CH452_WRITE
SJMP AGAIN
;
;开始总线子程序
CH452_I2C_START: SETB CH452_SDA
CLR CH452_SCL ;通知CH452,将要对其操作,此段时间不要再产生按键中断
CH452_I2C_START1: NOP
NOP ;保留足够的时间给CH452产生中断
NOP
JNB CH452_SDA,CH452_I2C_START1 ;CH452正在请求中断?
NOP
NOP
CLR EX1 ;禁止键盘中断,防止开始时被CH452中断而进入中断服务程序中的START
SETB CH452_SDA
SETB CH452_SCL
NOP
NOP
CLR CH452_SDA
NOP
NOP
CLR CH452_SCL ;钳住总线,准备发数据
RET
;结束总线子程序
CH452_I2C_STOP: CLR CH452_SDA
NOP
NOP
SETB CH452_SCL ;发送结束条件的时钟信号
NOP
NOP
SETB CH452_SDA ;结束总线
CLR IE1 ;清除中断标志,因为通过SDA输出数据所以会误中断
SETB EX1
RET
;发送字节子程序
;字节数据放入ACC
CH452_IIC_WR: MOV R7,#08H
CH452_IIC_WR1: RLC A ;取数据位
MOV CH452_SDA,C
SETB CH452_SCL
NOP
NOP
NOP
CLR CH452_SCL
DJNZ R7,CH452_IIC_WR1
NOP
SETB CH452_SDA
SETB CH452_SCL
NOP
NOP
NOP
CLR CH452_SCL
RET
;
;读取字节子程序
;读出的值在ACC
CH452_IIC_RD: MOV R7,#08H
CH452_IIC_RD1: SETB CH452_SDA
SETB CH452_SCL ;时钟线为高,接收数据位
NOP
NOP
MOV C,CH452_SDA ;读取数据位
CLR CH452_SCL
RLC A ;进行数据位的处理
DJNZ R7,CH452_IIC_RD1 ;未够8位,再来一次
SETB CH452_SDA
SETB CH452_SCL
NOP
NOP
NOP
CLR CH452_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
;
DELAY: MOV R4,#0FFH
DELAY2: MOV R5,#0FFH
DELAY1: NOP
DJNZ R5,DELAY1
DJNZ R4,DELAY2
RET
;
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -