⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dp51de.asm

📁 周立功串口通讯,附调试软件...可以参考学习下.
💻 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 + -