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

📄 cs8900a.asm

📁 在51单片机上用汇编实现的TCP/TP协议网络通信
💻 ASM
📖 第 1 页 / 共 2 页
字号:
MOV	R0,#PacketRAM+u_src
ADD	A,R0
MOV	R0,A
MOV	@R0,0DH
INC	R0
MOV	@R0,0AH
INC	R0
MOV	@R0,48H
INC	R0
MOV	@R0,65H
INC	R0
MOV	@R0,6CH
INC	R0
MOV	@R0,6CH
INC	R0
MOV	@R0,6FH
INC	R0
MOV	@R0,20H
INC	R0
MOV	@R0,57H
INC	R0
MOV	@R0,6FH
INC	R0
MOV	@R0,72H
INC	R0
MOV	@R0,6CH
INC	R0
MOV	@R0,64H
INC	R0
MOV	@R0,21H

MOV	R1,#PacketRAM+u_len
MOV	A,@R1
MOV	R0,#PacketRAM+u_cksum
MOV	@R0,A
INC	R0
INC	R1
MOV	A,@R1
MOV	@R0,A
; 修改帧长度
MOV	R0,#PacketRAM+u_pktLenL
MOV	A,@R0
ADD	A,#14
MOV	@R0,A
MOV	R0,#PacketRAM+ip_len+1
MOV	A,@R0
ADD	A,#14
MOV	@R0,A
MOV	R0,#PacketRAM+u_len+1
MOV	A,@R0
ADD	A,#14
MOV	@R0,A
MOV	R0,#PacketRAM+u_cksum
MOV	@R0,#0
INC	R0
MOV	@R0,#0
; 然后计算IP头的校验和
LCALL	IpResp
; 发送帧
LCALL	TxPacket
RET
;************************************
; 发送帧
;************************************
TxPacket:
MOV	CAB,#portTxCmd
MOV	CDB,#TxCmd
CLR	AEN
CLR	IOW
MOV	CAB,#portTxCmd+1
MOV	CDB,#0
CLR	AEN
CLR	IOW
MOV	CAB,#portTxLength
MOV	R0,#PacketRAM+pktLenL
MOV	CDB,@R0
CLR	AEN
CLR	IOW
MOV	CAB,#portTxLength+1
MOV	R0,#PacketRAM+pktLenH
MOV	CDB,@R0
CLR	AEN
CLR	IOW
TxPktl:
LCALL	RegRead
DW	ppBusST
MOV	A,TempH
ANL	A,#00000001B
CJNE	A,#1,TxPktl
MOV	R0,#PacketRAM+pktDestH
MOV	R1,#PacketRAM+pktLenL
MOV	A,@R1
MOV	R1,A
TxL:
MOV	A,@R0
MOV	CDB,A
MOV	CAB,#portRxTxData+1
CLR	AEN
CLR	IOW
INC	R0
DJNZ	R1,TxL
QuitTxP:
RET
;************************************
; 延时模块
;************************************
VWAIT:
MOV	R0,#5
VWL1:
MOV	R1,#200
VWL2:
MOV	R2,#200
VWL3:
NOP
NOP
DJNZ	R2,VML3
DJNZ	R1,VML2
DJNZ	R0,VML1
RET
;************************************
; 芯片复位
;************************************
Resetchip:
		ACALL	Regwrite		; 将复位命令写入SelfCTL寄存器
		DW		ppSelfCTL
		DW		Slfctlrst
Resetwait:						; 等待复位完成
		ACALL	Regread
		DW		ppSelfCTL
		MOV		a, TempL
		ANL		a, #40H
		JNZ		Resetwait
		RET					; 程序返回
;************************************
; 芯片初始化
;************************************
Initchip:
; 寄存器初始化
		ACALL	Regwrite		; 写LineCTL寄存器初值
		DW		ppLineCTL
		DW		LineCTL
		ACALL	Regwrite		; 写TestCTL寄存器初值
		DW		ppTestCTL
		DW		TestCTL
		ACALL	Regwrite		; 写RxCFG寄存器初值
		DW		ppRxCFG
		DW		RxCFG
		ACALL	Regwrite		; 写RxCTL寄存器初值
		DW		ppRxCTL
		DW		RxCTL
		ACALL	Regwrite		; 写TxCFG寄存器初值
		DW		ppTxCFG
		DW		TxCFG
; 写MAC地址
		ACALL	Regwrite
		DW		ppindaddr
		DW		MAC00
		ACALL	Regwrite
		DW		ppindadds
		DW		MAC01
		ACALL	Regwrite
		DW		ppindaddt
		DW		MAC02
		ACALL	Regwrite
		DW		ppintnum
		DW		0000H
		ACALL	Regread
		DW		ppBusCTL
		ORL		TempH, #80H
; 设置IRQ
		MOV		CAB, #PortData
		MOV		CDB, TempL
		CLR		AEN
		CLR		IOW
		MOV		CAB, #PortData+1
		MOV		CDB, TempH
		CLR		AEN
		CLR		IOW
		ACALL	Regread
		DW		ppLineCTL
		ORL		TempL, #0C0H
		MOV		CAB, #PortData
		MOV		CDB, TempL
		CLR		AEN
		CLR		IOW
		MOV		CAB, #PortData+1
		MOV		CDB, TempH
		CLR		AEN
		CLR		IOW
		RET
;************************************
; 写寄存器
;************************************
Regwrite:
		POP		dph
		POP		dpl
; 写地址
		MOV	a, 	#01H
		MOVC	a, @a+dptr
		MOV		CDB, a
		MOV		CAB, #PortPtr		; 写入地址的高8位
		CLR		AEN
		CLR		IOW

		MOV		a, #00H
		MOVC	a, @a+dptr
		MOV		CDB, a
		MOV		CAB, #PortPtr+1		;写入地址的低8位
		CLR		AEN
		CLR		IOW
; 写参数
		MOV		a, #03H
		MOVC	a, @a+dptr
		MOV		CDB, a
		MOV		CAB, #PortData		; 写入数据的高8位
		CLR		AEN
		CLR		IOW

		MOV		a, #02H
		MOVC	a, @a+dptr
		MOV		CDB, a
		MOV		CAB, #PortData+1	;写入数据的低8位
		CLR		AEN
		CLR		IOW
; 程序返回
		MOV		a, #04H
		JMP		@a+dptr
;************************************
; 读寄存器
;************************************
Regread:
		POP		dph
		POP		dpl
; 写地址
		MOV		a, #01H
		MOVC	a, @a+dptr
		MOV		CDB, a
		MOV		CAB, #PortPtr		; 写入地址的高8位
		CLR		AEN
		CLR		IOW

		MOV		a, #00H
		MOVC	a, @a+dptr
		MOV		CDB, a
		MOV		CAB, #PortPtr+1		; 写入地址的低8位
		CLR		AEN
		CLR		IOW
; 读出数据
		MOV		CAB, #PortData
		MOV		90H, #0FFH
		CLR		AEN
		CLR		IOR
		NOP						; 延时以保证读写时序正确
		MOV		TempL, CDB		; 读数据低8位
		SETB	AEN

		MOV		CAB, #PortData+1
		MOV		90H, #0FFH
		CLR		AEN
		CLR		IOR
		NOP						; 延时以保证读写时序正确
		MOV		TempH, CDB		; 读数据高8位
		SETB	AEN
; 程序返回
		MOV		a, #02H
		JMP		@a+dptr
;************************************
; 接收数据模块
; 仅接收帧长度、源MAC、目的MAC、以太网帧头
;************************************
Receiver:
; 首先读取的是RxStatus和RxLength
MOV	CAB,#PortPtr
MOV	CDB,#00H
CLR	AEN
; 不进行处理,直接忽略
CLR	IOW
MOV	CAB,#PortPtr+1
MOV	CDB,#04H
CLR	AEN
CLR	IOW
MOV	CAB,#PortRxTxData+1
MOV	90H,#0FFH
CLR	AEN
CLR	IOR
NOP
MOV	TempH,CDB
MOV	CAB,#PortRxTxData
MOV	90H,#0FFH
CLR	AEN
CLR	IOR
NOP
MOV	TempL,CDB
; 读出数据存入PocketRAM中
MOV	CAB,#PortPtr
MOV	CDB,#02H
CLR	AEN
CLR	IOW
MOV	CAB,#PortPtr+1
MOV	CDB,#04H
CLR	AEN
CLR	IOW
MOV	CAB,#PortRxTxData+1
MOV	90H,#0FFH
CLR	AEN
CLR	IOR
NOP
MOV	TempH,CDB
MOV	CAB,#PortRxTxData
MOV	90H,#0FFH
CLR	AEN
CLR	IOR
NOP
MOV	TempL,CDB
; 长度为0则跳过当前帧
MOV	A,TempH
ORL	A,TempL
JZ	Ignore_Frame
; 将帧长度存入PacketRAM前两个字节
MOV	R0,#PacketRAM+pktLenH
MOV	A,TempH
MOV	@R0,A
MOV	R0,#PacketRAM+pktLenL
MOV	A,TempL
MOV	@R0,A
; 开始接收源、目的MAC地址和pktType
MOV	R0,#PacketRAM+pktDest0H
MOV	R1,#14
LCALL	LoadPacket
RET
;************************************
; 从CS8900A中读取数据
; R0存放读出数据的存放地址,R1存放读取数目
;************************************
; 读取数据
LoadPacket:
		MOV		a,r0				; 这两步程序仅起到延时作用,并无实际意义
		MOV		r0,a
		MOV		CAB, #PortRxTxData		; 读取第一个字节
		MOV		90H, #0FFH		; 读取数据之前将P3口置位
		CLR		AEN
		CLR		IOR
		NOP
		MOV		@r0, CDB
		INC		r0
		DEC		r1
		JZ		LdPktDone
		MOV		CAB, #PortRxTxData+1	; 读取第二个字节
		MOV		90H, #0FFH
		CLR		AEN
		CLR		IOR
		NOP
		MOV		@r0, CDB
		INC		r0
		DEC		r1
		CJNE	r1, #0, LoadPacket
LdPktDone:						; 读取完成
		RET						; 程序返回
;************************************
; 忽略当前帧
;************************************
Ignore_Frame:
LCALL	RegWrite
DW	ppRxCfg
DW	SKIP
JMP	LOOP
;************************************
; 检查帧长度是否超过缓冲区容量
;************************************
ChkPktLen:
CLR	C
MOV	R0,#PacketRAM+pktLenH
MOV	A,@R0
JZ	HlenOK
SETB	C
RET
HlenOK:
INC	R0
MOV	A,@R0
SUBB	A,#MaxPackLen
CPL	C
RET
;************************************
; 交换IP头地址并计算校验和
;************************************
IpResp:
MOV	R0,#PacketRAM+ip_cksum
MOV	@R0,#0
INC	R0
MOV	@R0,#0

MOV	R0,#PacketRAM+ip_src
MOV	R1,#PacketRAM+ip_dest
MOV	A,@R0
MOV	@R1,A

INC	R0
INC	R1
MOV	A,@R0
MOV	@R1,A

INC	R0
INC	R1
MOV	A,@R0
MOV	@R1,A

INC	R0
INC	R1
MOV	A,@R0
MOV	@R1,A

MOV	R0,#PacketRAM+ip_src
MOV	@R0,#IP1
INC	R0
MOV	@R0,#IP2
INC	R0
MOV	@R0,#IP3
INC	R0
MOV	@R0,#IP4

; 计算头校验和
MOV	R1,#20
MOV	R0,#PacketRAM+ip_verlen
LCALL	Cksum
MOV	R0,#PacketRAM+ip_cksum
MOV	@R0,TempH
INC	R0
MOV	@R0,TempL
RET
;************************************
; 计算校验和
;************************************
CkSum:
		MOV		cnt_low, #0		; 临时变量
		MOV		cnt_mid, #0
		MOV		cnt_hi, #0
CkSumL:						; 处理低8位字节
		INC		r0
		MOV		a, r1			; 检查当前字节是否为最后一个字节
		DEC		a
		JZ		SkpLChk		; 是,跳过低8位字节处理
		MOV		a, cnt_low		; 低8位字节处理
		ADD		a, @r0
		MOV		cnt_low,a
		PUSH	psw
		DEC		r1
SkpLChk:						; 高8位字节处理
		DEC		r0
		MOV		a, cnt_mid
		POP		psw
		ADDC	a, @r0
		MOV		cnt_mid, a
		PUSH	psw
		INC		r0
		INC		r0
		CLR		a
		POP		psw
		ADDC	a, cnt_hi
		MOV		cnt_hi, a
		DJNZ	r1, CkSumL	; 如果还有数据则跳回低8位字节处理程序
QuitChk:						; 完成校验,保存计算结果
		MOV		a, cnt_hi
		ADD		a, cnt_low
		MOV		cnt_low, a
		PUSH	psw
		CLR		a
		POP		psw
		ADDC	a, cnt_mid
		MOV		cnt_mid, a
		MOV		a, cnt_low
		CPL		a
		MOV		TempL, a
		MOV		a, cnt_mid
		CPL		a
		MOV		Temp_H, a
		RET					; 程序返回
;************************************
; 计算UDP校验和
;************************************
CkSumUDP:
		MOV		r0, #PacketRam+u_len+1
		MOV		a, #8
		ADD		a, @r0
		MOV		r1, a			; R1中保存要计算数据的长度
		MOV		r0, #PacketRam+ip_src		; R0中保存要计算数据的首地址
		MOV		cnt_low, #0		; 临时变量
		MOV		cnt_mid, #0
		MOV		cnt_hi, #0	
CkSumLUDP:					; 处理低8位字节
		INC		r0
		MOV		a, r1			; 检查当前字节是否为最后一个字节
		DEC		a
		JZ		SkpLChkUDP	; 是,跳过低8位字节处理
		MOV		a, cnt_low		; 低8位字节处理
		ADD		a, @r0
		MOV		cnt_low,a
		DEC		r1
SkpLChkUDP:					; 高8位字节处理
		DEC		r0
		MOV		a, cnt_mid
		ADDC	a, @r0
		MOV		cnt_mid, a
		INC		r0
		INC		r0
		CLR		a
		ADDC	a, cnt_hi
		MOV		cnt_hi, a
		DJNZ	r1, CkSumLUDP		; 如果还有数据则跳回低8位字节处理程序
		MOV		a, cnt_low
		ADD		a, #17H
		MOV		cnt_low, a
		MOV		a, #00H
		ADDC	a, cnt_mid
		MOV		cnt_mid, a
		MOV		a, #00H
		ADDC	a, cnt_hi
		MOV		cnt_hi, a
		MOV		r0, #PacketRam+u_len+1
		MOV		a, cnt_low
		ADD		a, @r0
		MOV		cnt_low, a
		CLR		a
		ADDC	a, cnt_mid
		MOV		cnt_mid, a
		CLR		a
		ADDC	a, cnt_hi
		MOV		cnt_hi, a
		ADD		a, cnt_low
		MOV		cnt_low, a
		MOV		a, #00H
		ADDC	a, cnt_mid
		MOV		cnt_mid, a
		MOV		a, cnt_low			; 完成校验,保存计算结果
		CPL		a
		MOV		TempL, a
		MOV		a, cnt_mid
		CPL		a
		MOV		TempH, a
		RET						; 程序返回
;************************************
; 调试模块
;************************************
Debug:
		LCALL	Regwrite
		DW		ppSelfCTL
		DW		Slfctlrst
		SJMP	Debug

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -