📄 dp51de.asm
字号:
; DP-51实验板上EEPROM读写操作程序
; 通过串口,接收上位机发送的命令,并进行CSI24WC02的读写操作,并返回相应
;数据或应答。使用了多个从机挂在总线上,通过上位机指定从机进行读写操作。
;
;File: DP51DE.ASM
;Date: 2002.10.30
ACK BIT 10H ;应答标志位
SLA DATA 50H ;器件从地址
SUBA DATA 51H ;器件子地址
NUMBYTE DATA 52H ;读/写的字节数
;使用前定义常量:
SDA EQU P3.4
SCL EQU P3.5
CSI24WC02 EQU 0A0H ;定义CSI24WC02的从地址
MTD EQU 30H ;发送数据缓冲区首址 (缓冲区30H-3FH)
MRD EQU 30H ;接收数据缓冲区首址 (缓冲区30-3FH)
;定义串行通讯数据缓冲区40H---4FH
DATA_BUF EQU 40H
;定义本机的从机地址,其它从机要定义成其它地址
SLA_ADR EQU 0C0H
;SLA_ADR EQU 0C1H
;SLA_ADR EQU 0C2H
;SLA_ADR EQU 0C3H
;SLA_ADR EQU 0C4H
;=========================================================================
ORG 0000H
AJMP MAIN
ORG 0023H
AJMP SERIAL_INT ;串口中断入口
ORG 0100H
MAIN:
MOV SP,#60H
MOV R7,#0
DJNZ R7,$
SERIAL_INI:
MOV TMOD,#20H ;设置定时器1工作模式
MOV TH1,#0FDH ;设置波特率为9600b
MOV TL1,#0FDH
SETB TR1
MOV SCON,#50H ;设置串口位方式1
MOV PCON,#00H
SETB ES ;打开串口中断允许
SETB EA
SJMP $
;串口中断
;处理接收中断,若接收到命令帧的帧头,则开始接收一帧命令,否则不理会此数据。
;注:则于主程序不使用系统资源,固中断不用进行现场保护。
SERIAL_INT:
JB TI,SERIAL_INT_EXT ;若是发送中断,则直接退出。
MOV A,SBUF
CJNE A,#12H,SERIAL_INT_EXT ;等待帧头。若不是帧头则直接退出
;接收命令字,并放入DATA_BUF中
MOV R0,#DATA_BUF
ACALL SERIAL_RCV_DATA ;接收一字节串口上的数据,接收到的数据在R1中
JZ SERIAL_INT_EXT ;若接收超时,则退出中断
MOV A,R1 ;进行命令字的分析
MOV @R0,A
;接收命令帧的参数个数,放入DATA_BUF+1中
INC R0
ACALL SERIAL_RCV_DATA ;接收一字节串口上的数据,接收到的数据在R1中
JZ SERIAL_INT_EXT ;若接收超时,则退出中断
MOV A,R1
MOV @R0,A
ACALL SERIAL_RCV_DATA ;使用了A、R1、R6、R7
JZ SERIAL_INT_EXT
MOV A,R1
CJNE A,#SLA_ADR,SERIAL_INT_EXT;判断是否是访问本从机,若不是则直接退出
;接收命令帧的其它参数,放入DATA_BUF+2....
MOV A,@R0
DEC A
MOV R5,A ;取出所要接收的字节数
SERIAL_INTRD:
INC R0
ACALL SERIAL_RCV_DATA ;接收一字节串口上的数据,接收到的数据在R1中
JZ SERIAL_INT_ERR ;若接收超时,返回命令接收错误,并退出中断
MOV A,R1
MOV @R0,A
DJNZ R5,SERIAL_INTRD
;进行命令帧数据的校验
MOV B,A ;保存接收到的校验字
MOV R1,#00 ;DATA_BUF缓冲区的数据进行异或结果 (最后一字节除外)
SERIAL_CHKD:
MOV A,R1
DEC R0
XRL A,@R0 ;将DATA_BUF缓冲区的数据进行异或操作
MOV R1,A
MOV A,R0
CJNE A,#DATA_BUF,SERIAL_CHKD ;判断是否已经对接收到的数据全部进行异或操作
MOV A,#12H ;和帧头字异或操作
XRL A,R1
XRL A,#SLA_ADR ;与从机地址值进行异或
MOV R1,A
MOV A,B
CJNE A,01H,SERIAL_INT_ERR ;与异或结果R1进行比较,若出错,则向上位机返回出错帧
MOV A,@R0 ;取出命令字
CJNE A,#20H,SERIAL_WREEPROM
SERIAL_RDEEPROM:
ACALL RDEEPROM ;命令字为20H,读EEPROM操作
SJMP SERIAL_INT_EXT
SERIAL_WREEPROM:
CJNE A,#21H,SERIAL_INT_ERR ;若命令字不是20H,也不是21H,则退出中断接收
ACALL WREEPROM ;命令字为21H,写EEPROM操作
SERIAL_INT_EXT:
CLR TI
CLR RI
RETI
;接收命令出错,返回出错码00H
SERIAL_INT_ERR:
MOV R7,#5
MOV DATA_BUF,#12H ;命令帧的帧头
MOV DATA_BUF+1,#0A1H ;命令字--操作失败
MOV DATA_BUF+2,#2 ;返回参数--2字节
MOV DATA_BUF+3,#00H ;返回码00H,表示接收命令出错
MOV DATA_BUF+4,#0B1H ;异或校验和
ACALL SERIAL_SENDPC
CLR TI
CLR RI
RETI
;写CSI24WC02的指定单元
;操作成功则返回操作成功回应帧
;
WREEPROM:
MOV A,DATA_BUF+2 ;取出要读取的EEPROM地址
MOV SUBA,A
MOV A,DATA_BUF+1
DEC A
DEC A
DEC A
MOV NUMBYTE,A
MOV R7,A
;将所要写入的数据装入MTD缓冲区
MOV R0,#MTD
MOV R1,#DATA_BUF+4
WREEPROM_MOV:
MOV A,@R1
MOV @R0,A
INC R0
INC R1
DJNZ R7,WREEPROM_MOV
MOV SLA,#CSI24WC02
ACALL IWRNBYTE ;读取EEPROM的数据
JB ACK,WREEPROM_OK
;若写EEPROM出错,则返回写EEPROM出错帧
WREEPROM_ERR:
MOV R7,#6
MOV DATA_BUF,#12H ;命令帧的帧头
MOV DATA_BUF+1,#0A1H ;命令字--操作失败
MOV DATA_BUF+2,#3 ;返回参数--3字节
MOV DATA_BUF+3,SUBA ;返回出错地址
MOV DATA_BUF+4,#00H
MOV A,#0B0H
XRL A,SUBA
MOV DATA_BUF+5,A ;异或校验和
ACALL SERIAL_SENDPC
RET
WREEPROM_OK:
MOV R7,#4
MOV DATA_BUF,#12H ;命令帧的帧头
MOV DATA_BUF+1,#0A0H ;命令字--操作失败
MOV DATA_BUF+2,#1 ;返回参数--2字节
MOV DATA_BUF+3,#0B3H ;异或校验和
ACALL SERIAL_SENDPC
RET
;读CSI24WC02的指定单元,并将数据返回给上位机
;若读CSI24WC02无应答,则返回操作失败帧
;
RDEEPROM:
MOV A,DATA_BUF+2 ;取出要读取的EEPROM地址
MOV SUBA,A
MOV A,DATA_BUF+4
MOV NUMBYTE,A
MOV SLA,#CSI24WC02
ACALL IRDNBYTE ;读取EEPROM的数据
JB ACK,RDEEPROM_OK
RDEEPROM_ERR:
MOV R7,#5
MOV DATA_BUF,#12H ;命令帧的帧头
MOV DATA_BUF+1,#0A1H ;命令字--操作失败
MOV DATA_BUF+2,#2 ;返回参数--2字节
MOV DATA_BUF+3,#01H ;返回码01H,表示操作CSI24WC02出错
MOV DATA_BUF+4,#0B1H ;异或校验和
ACALL SERIAL_SENDPC
RET
RDEEPROM_OK:
MOV DATA_BUF,#12H
MOV DATA_BUF+1,#0A0H
MOV A,NUMBYTE
MOV R7,A ;保存所读取的数据个数
INC A
MOV DATA_BUF+2,A ;设置返回数据个数
MOV A,#0B2H ;设置帧头的异或效验
XRL A,DATA_BUF+2
MOV R2,A
;将数据装入DATA_BUF,并进行异或求取校验字
MOV R0,#DATA_BUF+3
MOV R1,#MRD
RDEEPROM_MOV:
MOV A,@R1
MOV @R0,A
INC R0
INC R1
XRL A,R2 ;进行求异或效验和操作
MOV R2,A
DJNZ R7,RDEEPROM_MOV
MOV @R0,A ;写入效验字
MOV A,DATA_BUF+2
INC A ;设置发送数据帧的个数
INC A
INC A
MOV R7,A
ACALL SERIAL_SENDPC
RET
;将DATA_BUF的数据发送回上位机
;发送的数据个数R7中
;
SERIAL_SENDPC:
MOV R1,#DATA_BUF
SERIAL_SPL1:
CLR TI
MOV A,@R1
MOV SBUF,A
INC R1
JNB TI,$
DJNZ R7,SERIAL_SPL1
RET
;接收一字节串口上的数据
;返回值:R1 接收到的数据
; A 出错值,为00H时表示接收超时,为0FH时表示正确接收。
;占用资源:A、R1、R6、R7
;
SERIAL_RCV_DATA:
CLR RI
MOV R7,#0
MOV R6,#0
SERIAL_RCVD_L1:
JB RI,SERIAL_RCVD_OK
DJNZ R6,SERIAL_RCVD_L1
DJNZ R7,SERIAL_RCVD_L1
MOV A,#00 ;接收超时,超时退出
RET
SERIAL_RCVD_OK:
MOV A,SBUF ;接收数据
MOV R1,A ;将接收到的数据放入R1返回
MOV A,#0FH ;设置接收正确
RET
$INCLUDE (VI2C_24A.INC)
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -