📄 24cxx.asm
字号:
;实验名称:读写AT24C02实验
; 功能:用串口发送指令读出或写入00-7FH单无的内容,显示结果在LCD上显示
; 读出(16进制数):AA 地址
; 写入(16进制数):BB 地址 内容
; 作者:http://www.mcuprog.com
; 05-02-01
SCK BIT P3.3 ;I2C的时钟线
SDA BIT P3.4 ;I2C的数据线
;读写I2C总线器件要用到的寄存器
ERRFLAG BIT 00H
TEMP1 EQU 1AH
DELAYCOUNT EQU 1BH
ADDREHI EQU 1CH ;读写的地址
ADDRELO EQU 1DH
WRITE_DATA EQU 1EH ;单字节写入的数据
READ_DATA EQU 1FH ;单字节读出的数据
E BIT P2.2
RW BIT P2.1
RS BIT P2.0
LCDPORT EQU P0
CMD_BYTE EQU 30H
DAT_BYTE EQU 31H
READBIT BIT 01H ;读某个单元
WRITEBIT BIT 02H ;写某个单元
RS232OKBIT BIT 03H ;一个完整的串口指令完
RECSUM EQU 32H ;要从232收的字字数
ORG 0000H
AJMP MAIN
ORG 000BH
AJMP TIME0_1
ORG 0023H
RS232: CLR RI
MOV A,SBUF
CJNE A,#0AAH,RS232_1
MOV RECSUM,#01H ;是读EEP后面只要一个地址就可
MOV R0,#40H
SETB READBIT
AJMP RS232_RE
RS232_1: CJNE A,#0BBH,RS232_2
MOV RECSUM,#02H ;是写后要要一个地址一个写的内容
MOV R0,#40H
SETB WRITEBIT
AJMP RS232_RE
RS232_2: MOV @R0,A
INC R0
DJNZ RECSUM,RS232_RE
SETB RS232OKBIT
RS232_RE: RETI
ORG 0100H
MAIN: MOV R0,#20H
CLR0: MOV @R0,#00H
INC R0
CJNE R0,#70H,CLR0
MOV ADDRELO,#00H
LCALL READ_BYTE
LCALL INITLCD
MOV CMD_BYTE,#80H //设置DDRAM的地址
LCALL WRITE_CMD
LCALL DELAY0
MOV DAT_BYTE,#"A"
LCALL WRITE_DAT
MOV DAT_BYTE,#"D"
LCALL WRITE_DAT
MOV DAT_BYTE,#"D"
LCALL WRITE_DAT
MOV DAT_BYTE,#"R"
LCALL WRITE_DAT
MOV DAT_BYTE,#"E"
LCALL WRITE_DAT
MOV DAT_BYTE,#":"
LCALL WRITE_DAT
LCALL DISPEEPAD
MOV CMD_BYTE,#0C0H //设置DDRAM的地址
LCALL WRITE_CMD
MOV DAT_BYTE,#"M"
LCALL WRITE_DAT
MOV DAT_BYTE,#"E"
LCALL WRITE_DAT
MOV DAT_BYTE,#"M"
LCALL WRITE_DAT
MOV DAT_BYTE,#"O"
LCALL WRITE_DAT
MOV DAT_BYTE,#"R"
LCALL WRITE_DAT
MOV DAT_BYTE,#"Y"
LCALL WRITE_DAT
MOV DAT_BYTE,#":"
LCALL WRITE_DAT
LCALL DISPEEPMO
MOV TH0,#0FCH ;1MS
MOV TL0,#67H
MOV TH1,#0FDH ;9600波特
MOV TL1,#0FDH
MOV TMOD,#21H
MOV SCON,#50H
SETB TR0
SETB TR1
MOV IE,#92H
SETB REN
MAIN1: ORL PCON,#01H
AJMP MAIN1
ORG 0200H
TIME0_1: MOV TH0,#0FCH
MOV TL0,#67H
JBC RS232OKBIT,TODP
AJMP TIME0_RE
TODP: JBC READBIT,READ_EEP
JBC WRITEBIT,WRITE_EEP
AJMP TIME0_RE
TIME0_RE: RETI
READ_EEP: MOV ADDRELO,40H
LCALL READ_BYTE
LCALL DISPEEPAD
LCALL DISPEEPMO
AJMP TIME0_RE
WRITE_EEP: MOV ADDRELO,40H
MOV WRITE_DATA,41H
MOV READ_DATA,41H
LCALL WRITE_BYTE
LCALL DISPEEPAD
LCALL DISPEEPMO
AJMP TIME0_RE
;显示EEP地址
DISPEEPAD: MOV CMD_BYTE,#87H //设置DDRAM的地址
LCALL WRITE_CMD
MOV A,ADDRELO
ANL A,#0F0H
SWAP A
CJNE A,#0AH,DPEEPAD_1
DPEEPAD_1: JNC DPEEPAD_2
ADD A,#30H
MOV DAT_BYTE,A
AJMP DPEEPAD_3
DPEEPAD_2: ADD A,#37H
MOV DAT_BYTE,A
DPEEPAD_3: LCALL WRITE_DAT
MOV A,ADDRELO
ANL A,#0FH
CJNE A,#0AH,DPEEPAD_4
DPEEPAD_4: JNC DPEEPAD_5
ADD A,#30H
MOV DAT_BYTE,A
SJMP DPEEPAD_6
DPEEPAD_5: ADD A,#37H
MOV DAT_BYTE,A
DPEEPAD_6: LCALL WRITE_DAT
RET
DISPEEPMO: MOV CMD_BYTE,#0C7H //设置DDRAM的地址
LCALL WRITE_CMD
MOV A,READ_DATA
ANL A,#0F0H
SWAP A
CJNE A,#0AH,DPEEPMO_1
DPEEPMO_1: JNC DPEEPMO_2
ADD A,#30H
MOV DAT_BYTE,A
AJMP DPEEPMO_3
DPEEPMO_2: ADD A,#37H
MOV DAT_BYTE,A
DPEEPMO_3: LCALL WRITE_DAT
MOV A,READ_DATA
ANL A,#0FH
CJNE A,#0AH,DPEEPMO_4
DPEEPMO_4: JNC DPEEPMO_5
ADD A,#30H
MOV DAT_BYTE,A
SJMP DPEEPMO_6
DPEEPMO_5: ADD A,#37H
MOV DAT_BYTE,A
DPEEPMO_6: LCALL WRITE_DAT
RET
;LCD1602要用到的一些子程序
;写命令(入口参数CMD_BYTE)
WRITE_CMD: CLR RS
CLR RW
MOV A,CMD_BYTE
MOV LCDPORT,A
SETB E
NOP
NOP
CLR E
LCALL DELAY0
RET
;写显示数据(入口参数DAT_BYTE)
WRITE_DAT: SETB RS
CLR RW
MOV A,DAT_BYTE
MOV LCDPORT,A
SETB E
NOP
NOP
CLR E
LCALL DELAY0
RET
;LCD显示初始化
INITLCD: MOV CMD_BYTE,#30H
LCALL WRITE_CMD
MOV CMD_BYTE,#30H
LCALL WRITE_CMD
MOV CMD_BYTE,#30H
LCALL WRITE_CMD
MOV CMD_BYTE,#38H ;设定工作方式
LCALL WRITE_CMD
MOV CMD_BYTE,#0CH ;显示状态设置
LCALL WRITE_CMD
MOV CMD_BYTE,#01H ;清屏
LCALL WRITE_CMD
MOV CMD_BYTE,#06H ;输入方式设置
LCALL WRITE_CMD
RET
;延时子程序
DELAY0: MOV R5,#0A0H
DELAY1: NOP
DJNZ R5,DELAY1
RET
;延时子程序
DELAY: MOV A,DELAYCOUNT
JZ DELAY_RE
DEC DELAYCOUNT
MOV R7,#0C8H
DELAY_1: NOP
NOP
NOP
DJNZ R7,DELAY_1
LJMP DELAY
DELAY_RE: RET
;---------------24CXX要用到的子程序---------------------------------
;单字节写(入口ADDREHI,ADDRELO,WRITE_DATA)
WRITE_BYTE: LCALL STARTI2C
JB ERRFLAG,WRITE_B_RE ;不是空闲返回
MOV A,#0A0H
LCALL SHOUT_DATA
JB ERRFLAG,WRITE_B_STOP ;出错停止
; MOV A,ADDREHI ;送高位地址
; LCALL SHOUT_DATA
; JB ERRFLAG,WRITE_B_STOP
MOV A,ADDRELO ;送低位地址
LCALL SHOUT_DATA
JB ERRFLAG,WRITE_B_STOP
MOV A,WRITE_DATA
LCALL SHOUT_DATA
JB ERRFLAG,WRITE_B_STOP
CLR ERRFLAG ;正常清出错位
WRITE_B_STOP: LCALL STOPI2C
MOV DELAYCOUNT,#0AH
LCALL DELAY
WRITE_B_RE: RET
;单字节写没有延时
WRITE_BYTE0: LCALL STARTI2C
JB ERRFLAG,WRITE_B_RE0 ;不是空闲返回
MOV A,#0A0H
LCALL SHOUT_DATA
JB ERRFLAG,WRITE_B_STOP0 ;出错停止
MOV A,ADDRELO ;送低位地址
LCALL SHOUT_DATA
JB ERRFLAG,WRITE_B_STOP0
MOV A,WRITE_DATA
LCALL SHOUT_DATA
JB ERRFLAG,WRITE_B_STOP0
CLR ERRFLAG ;正常清出错位
WRITE_B_STOP0: LCALL STOPI2C
WRITE_B_RE0: RET
;单字节读(入口ADDREHI,ADDRELO;出口READ_DATA)
READ_BYTE: LCALL STARTI2C
JB ERRFLAG,READ_RE
MOV A,#0A0H
LCALL SHOUT_DATA
JB ERRFLAG,READ_STOP
; MOV A,ADDREHI
; LCALL SHOUT_DATA
; JB ERRFLAG,READ_STOP
MOV A,ADDRELO
LCALL SHOUT_DATA
JB ERRFLAG,READ_STOP
LCALL READ_CURRENT
LJMP READ_RE
READ_STOP: LCALL STOPI2C
READ_RE: RET
READ_CURRENT: LCALL STARTI2C
JB ERRFLAG,RE_CURRENTRE
MOV A,#0A1H
LCALL SHOUT_DATA
JB ERRFLAG,RE_CURRENTST
LCALL SHIN_DATA
LCALL NAK
CLR ERRFLAG
RE_CURRENTST: LCALL STOPI2C
RE_CURRENTRE: RET
SHOUT_DATA: MOV R6,#08H
SHOUT_DATA1: RLC A
MOV SDA,C
NOP
SETB SCK
NOP
NOP
NOP
NOP
CLR SCK
DJNZ R6,SHOUT_DATA1
SETB SDA
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
MOV C,SDA
MOV ERRFLAG,C
CLR SCK
RET
SHIN_DATA: SETB SDA
MOV R6,#08H
SHIN_DATA1: NOP
NOP
NOP
SETB SCK
NOP
NOP
MOV C,SDA
RLC A
NOP
CLR SCK
DJNZ R6,SHIN_DATA1
MOV READ_DATA,A
RET
STARTI2C: SETB SDA
SETB SCK
NOP
JNB SDA,STARTI2C_ERR
JNB SCK,STARTI2C_ERR
NOP
CLR SDA
NOP
NOP
NOP
NOP
CLR SCK
CLR ERRFLAG
LJMP STARTI2C_RE
STARTI2C_ERR: SETB ERRFLAG
STARTI2C_RE: RET
STOPI2C: CLR SDA
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
SETB SDA
RET
ACK: CLR SDA
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
CLR SCK
RET
NAK: SETB SDA
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
CLR SCK
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -