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

📄 final_forw77e58.asm

📁 串口服务器
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;2006-6-12
;增加了UDP数据包的校验和功能
;增加数据包在片外RAM中处理的能力

;进一步优化数据打包功能:
;1.将UDP和IP分开,便于下一步实现TCP协议
;2.将数据区划分,分别存储不同的参数
;050H-07FH作为IP相关参数存储区,具体如下:
;050-055:des mac     ; 056-05B:source mac   ;  05C-05D ;ether frame type
;060-063:source ip   ; 064-067:des ip       ; 068-069 :source port  ;06A-06B:des port ; 06C:protocal  ;06F:UDP是否校验
;070-073:local ip    ; 74-77: mask          ;78-7B: gate way        ;7C-7F: ARP的IP
;080-088
;090
;0A0-0B1
;0BC-0BF  收到的数据帧个数
;0C0-0C3              ;0C8-0C9      ;0CA      ;0CC-0CFh
;0D0-0D3    ping_reply  ip           ;0D4-0D7h        ping时暂存064-067h,以方便arp
;串口收到的数据缓存在片外RAM中
;发送缓冲区定义在0100-2FFFH中,偱环存放.(12K)
;接收缓冲区定义在3000-6FFFH中,偱环存放.(16K)
;预留ARP缓存区为 7000H-70FFh (256字节)
;其它空间留作它用.

;下一步打算优化算法,以进一步减少数据处理的时间,提高系统的运行速度
;(发送一个数据包的时间为1.2ms ~ 20ms,真正的物理网卡发送时间仅占到5%左右,所以主要的时间还是花在数据处理上了.).
;目前最耗时的是checksum和对8019的DMA操作
;主要原因是发生在频繁改变DPTR上

;增加ICMP协议,可以ping 通本机
;增加配置功能 config

;77E58有两个DPTR,利用这个特性,可以大大提高处理速度.

org 0000h

LJMP 0030H
org 0003h
LJMP net_INT         ;外部中断0
org 000Bh            ;存储时钟信息
LJMP T0_INT
org 0030H
main:
call clock_initial
call Serial_initial


call welcome

call int_initial
call default_info
call default_setting
call net_initial
call wait_for_change
call work_now

mov  DPTR,#0000h


loop:

;参数 DPTR         返回值 DPTR,R6,R7
call com_buffer


;参数 DPTR, R6,R7  返回值 R6,R7
call pack

;参数 DPTR, R6,R7  无返回值,不改变原有参数
call pac_send

inc DPH
mov A,DPH
clr C
subb A,#30h
jc m5
mov DPH,#00h
m5:

sjmp loop

;end main







;**********************************************
int_initial:
;----------中断初始化设置
clr IT0  ;低电平触发
SETB EX0
ret

T0_INT:
;------将时钟存储在寄存器2D-2F中
inc 2Fh
mov A,2Fh
jnz  con78
inc 2Eh
con74:
mov A,2Eh
jnz con78
inc 2DH
con78:

retI

clock_initial:
clr A
;时钟信号清零
mov 2DH,A
mov 2EH,A
mov 2FH,A
setb ET0
setb EA
ret

net_INT:
;网络口中断,收到新的数据包
nop
clr EX0
push DPh
push DPl
push ACC
push B
mov 40h,R0     ;暂存R0-R7
mov 41h,R1
mov 42h,R2
mov 43h,R3
mov 44h,R4
mov 45h,R5
mov 46h,R6
mov 47h,R7

mov 24H,#40H     ;收到的数据存放位置
mov 25H,#00H


call pac_receive

mov DPTR,#8007h
mov A,#0FFh      ;清中断
movx @DPTR,A

mov R0,40h
mov R1,41h
mov R2,42h
mov R3,43h
mov R4,44h
mov R5,45h
mov R6,46h
mov R7,47h

POP B
pop ACC
pop dpl
pop dph
setb EX0
RETI

;*************************************************
Serial_initial:
;---------------------------------
MOV TMOD,#21h  ;T1工作在方2,自动重装 
mov TL1,#0ffh  ;波特率115200
mov TH1,#0ffh
setb TR1       ;T1开始工作
setb TR0
mov SCON,#40h  ;工作在方式1  10位UART
mov PCON,#80h  ;波特率加倍
setb Ren
ret


com_buffer:
;---------------------------------

mov 20h,DPH
mov 21h,DPl
call com_rec
mov A,dPL
mov DPL,23h
clr C
subb A,23h
mov R7,A
mov A,DPH
mov DPH,22h
subb A,22h
mov R6,A
mov DPH,20h
mov DPL,21h

call command
jnz  com_buffer

mov DPH,20h
mov DPL,21h
ret

command:
;---------
mov A,DPL
add A,#2Ah
mov DPL,A
jnc L204
inc DPH
L204:
movx A,@DPTR
cjne A,#'c',L218
inc DPTR
movx A,@DPTR
cjne A,#'o',exit208
inc DPTR
movx A,@DPTR
cjne A,#'n',exit208
inc DPTR
movx A,@DPTR
cjne A,#'f',exit208
inc DPTR
movx A,@DPTR
cjne A,#'i',exit208
inc DPTR
movx A,@DPTR
cjne A,#'g',exit208
call change
mov A,#0FFh
ret

L218:
cjne A,#'p',exit208
inc DPTR
movx A,@DPTR
cjne A,#'i',exit208
inc DPTR
movx A,@DPTR
cjne A,#'n',exit208
inc DPTR
movx A,@DPTR
cjne A,#'g',exit208
inc DPTR
mov A,R7
clr C
subb A,#6
mov R7,A
L240:
movx A,@DPTR
cjne A,#' ',L242
dec R7
inc DPTR
sjmp L240
L242:
call s_to_i
mov A,B
jnz exit208
call ping
mov A,#0FFH
ret

exit208:
mov A,#0
ret


com_rec:
;接收数据放于 DPTR + 2AH 起始处
mov A,dpl
add A,#2Ah
mov DPL,A
mov A,DPH
addc A,#0
mov DPH,A
mov 22h,DPH
mov 23h,DPL
clr A
mov R6,A
mov R7,A

wait050:
call com_receive
mov B,A
CJNE A,#0Dh,n1012   ; A=0D ?
movx @DPTR,A
inc DPTR
mov A,#0Ah
movx @DPTR,A
inc DPTR
call com_send       ;回应
sjmp ret1023
n1012:
mov A,B
CJNE A,#08h,cd1568        ;退格删除
call dec_dptr
mov A,#20h
call com_send
mov A,#08h
call com_send
sjmp wait050
cd1568:
mov A,B
movx @DPTR,A
inc DPTR
sjmp wait050

ret1023:
ret



dec_dptr:
mov A,DPL
clr C
subb A,#1
mov DPL,A
jnc L225
dec DPH
L225:
ret


com_receive:
;---------------------------------
  JBC RI,next
  SJMP com_receive
next:
  mov A,SBUF
com_send:
;-----------------------------
  mov SBUF,A
wait1:
  JNB TI,wait1
  clr TI
  ret

welcome:
;--------------
mov DPTR,#s1
mov R0,#22
call cout
call delay
mov DPTR,#s2
Mov R0,#14
call cout

mov R0,#60h
mov DPTR,#002Dh
PUSH DPL
PUSH DPH
mov B,#0
loop275:
mov A,B
inc B
mov DPTR,#s6
movc A,@A+DPTR
POP DPH
POP DPL
movx @DPTR,A
inc DPTR
PUSH DPL
PUSH DPH
djnz R0,loop275
POP ACC
POP ACC
ret
;---------------

default_info:
;--------------
mov DPTR,#s3
mov R0,#213      ;s3长度
call cout
call delay
mov DPTR,#s4
mov R0,#37
call cout
ret
;--------

work_now:
;------------
mov dPTR,#s15
mov R0,#20
call cout
ret


cout:
;------DPTR :#data  R0:length ---
loop_c:
clr A
movc A,@A+DPTR
mov SBUF,A
inc DPTR
wait_c:
JNB TI,wait_c
clr TI
djnz R0,loop_c

ret


wait_for_change:
;-----------------
mov A,2Fh
add A,#90
mov B,A
wait340:
jB RI,change
mov A,2FH
clr C
subb A,B
jnz wait340
ret


string:
mov DPTR,#7500h
call com_buffer
mov DPTR,#752Ah
dec R7
dec R7
mov A,R7
ret

change:
;-------
clr RI
mov DPTR,#s14
mov R0,#40
call cout
L3655:
mov DPTR,#s7          ;本机IP:
mov R0,#7
call cout
mov R0,#60h
mov R2,#4
call i_to_s

mov A,#':'
call com_send
call string
jz L372
call S_To_i
mov A,B
jz L366
mov DPTR,#s9
mov R0,#20
call cout
sjmp L3655

L366:
mov DPTR,#s8       ;OK!\n
mov R0,#5
call cout
mov R0,#0C0h
mov R1,#60h
mov R2,#4
Loop373:
mov A,@R0
mov @R1,A
inc R0
inc R1
djnz R2,Loop373

L372:
mov DPTR,#s10    ; 目的IP:
mov R0,#7
call cout
mov R0,#64h
mov R2,#4
call i_to_s
mov A,#':'
call com_send
call string
jz L404
call S_To_i
mov A,B
jz L3760
mov DPTR,#s9
mov R0,#20
call cout
sjmp L372
L3760:
mov R0,#0C0h
mov R1,#64h
mov R2,#4
Loop398:
mov A,@R0
mov @R1,A
inc R0
inc R1
djnz R2,Loop398

mov DPTR,#s8       ;OK!\n
mov R0,#5
call cout

L404:
mov DPTR,#s11    ; 子网掩码:
mov R0,#9
call cout
mov R0,#74h
mov R2,#4
call i_to_s
mov A,#':'
call com_send
call string
jz L420
call S_To_i
mov A,B
jz L412
mov DPTR,#s9
mov R0,#20
call cout
sjmp L404

L412:
mov R0,#0C0h
mov R1,#74h
mov R2,#4
Loop422:
mov A,@R0
mov @R1,A
inc R0
inc R1
djnz R2,Loop422

mov DPTR,#s8       ;OK!\n
mov R0,#5
call cout

L420:
mov DPTR,#s12    ; 网关:
mov R0,#5
call cout
mov R0,#78h
mov R2,#4
call i_to_s
mov A,#':'
call com_send
call string
jz L440
call S_To_i
mov A,B
jz L430
mov DPTR,#s9
mov R0,#20
call cout
sjmp L420

L430:
mov R0,#0C0h
mov R1,#78h
mov R2,#4
Loop451:
mov A,@R0
mov @R1,A
inc R0
inc R1
djnz R2,Loop451

mov DPTR,#s8       ;OK!\n
mov R0,#5
call cout

L440:
mov DPTR,#s13
mov R0,#11
call cout

ret




S_To_i:
;--------------
mov R1,#0C0h
mov R3,#0


loop377:
movx A,@DPTR
mov R0,A
clr C
subb A,#'.'
jz  L376
mov A,R0
subb A,#'0'
jc  ret375
mov A,R0
clr C
subb A,#3Ah     ;'9'+1
jnc ret375

mov A,R0
clr C
subb A,#'0'
mov R2,A
mov A,R3        ;<--------s
mov B,#10
mul AB
xch A,B
cjne A,#0,ret375
xch A,B
add A,R2
jc  ret375
mov R3,A
sjmp L403

L376:
mov A,R3
mov @R1,A
inc R1
mov R3,#0
L403:
inc DPTR
djnz R7,loop377

cjne R1,#0C3h,ret375
mov A,R3
mov @R1,A

mov B,#0
ret

ret375:
mov B,#1        ;错误
ret

i_To_S:
;------将RAM中存储的IP转换成ASCII码,并输出到串口
;------格式 [***.***.***.***]:
;参数:R0,R2
mov A,#'['
call com_send
loop2004:
mov A,@R0
mov R1,#0CCh
loop2005:
mov B,#10
DIV AB
mov @R1,B
jz L336
inc R1
sjmp loop2005
L336:
mov A,@R1
add A,#'0'
call com_send
dec R1
cjne R1,#0CBh,L336
dec R2
mov A,R2
jz L3960
mov A,#'.'
call com_send
inc R0
sjmp loop2004

L3960:
mov A,#']'
call com_send

ret

buffer_send:
;----------DPTR,R6,R7
mov A,#0Dh
call com_send
mov A,#0Ah
call com_send
mov A,#3Eh      ;'>'
call com_send

inc R6
loop312:
movx A,@DPTR
mov SBUF,A
here313:
jnb TI,here313
clr TI
inc DPTR
djnz R7,loop312
djnz R6,loop312

mov A,#0Dh
call com_send
mov A,#0Ah
call com_send

ret




;*********************Data process***************
default_setting:
;----------默认设置
mov DPTR,#ether_data
mov R0,#50H
mov R1,#0
loop872:
mov A,R1
movc A,@A+DPTR
mov @R0,A
inc R0
inc R1
cjne R1,#14,loop872



mov DPTR,#ip_data
mov R0,#60H
mov R1,#0
loop823:
mov A,R1
movc A,@A+DPTR
mov @R0,A
inc R0
inc R1
cjne R1,#12,loop823

mov DPTR,#subnet_data
mov R0,#70H
mov R1,#0
loop888:
mov A,R1
movc A,@A+DPTR
mov @R0,A
inc R0
inc R1
cjne R1,#12,loop888

clr A
mov DPTR,#7000h
movx @DPTR,A     ;ARP条数为0
inc DPL
movx @DPTR,A

mov 06CH,#11h   ;协议类型:UDP
mov 6Fh,#0      ;发送数据不进行UDP校验

mov R0,#0BDh
mov R1,#3
clr A
loop503:
mov @R0,A
inc R0
djnz R1,loop503

ret

pack:
;----------------------将XRAM 中的数据 加上UDP报头和IP头部  
;------------目的地址:0011D8A51E15    目的IP:222.205.9.240
;------------源端口: 3456      目的端口:7788
PUSH 20H
PUSH 21H
PUSH 22H
PUSH 23H
mov 20H,DPH
mov 21H,DPL
call arp
mov DPH,20h
mov DPL,21h
call ether_pack

mov A,R7
add A,#8  ;数据长度 + 8 = UDP长度
mov R7,A
mov A,R6
addc A,#0
mov R6,A

mov B,#16H   ;此偏移量正好是UDP加上伪头部时的位置 22H-0C(12字节)
call add_dptr
call udp_pack

mov A,R7
add A, #20   ; UDP长度 + 20 = IP长度
mov R7,A
mov A,R6
addc A,#0
mov R6,A

mov B,#0EH
call add_dptr
call ip_pack

mov A,R7
add A, #14   ;IP长度 + 14 = 总长度
mov R7,A
mov A,R6
addc A,#0
mov R6,A

mov DPH,20h
mov DPL,21h

POP 23H
POP 22H
POP 21H
POP 20H
ret
;-------------------------

add_dptr:
;------------参数 B---
PUSH ACC

mov DPH,20h
mov A,21H
add A,B
mov dpl,A
mov A,20h
addc A,#0
mov DPH,A
POP ACC
ret


ether_pack:
;---------------
mov R0,#50h
mov R1,#14
wait9510:
mov A,@R0
movx @DPTR,A
inc R0
inc DPTR
djnz R1,wait9510
ret

udp_pack:
;-----------------------------------
;dptr为真正的UDP包位置-12 ,这样做是为了便于加入校验伪头部
;堆栈中的参数为是否进行UDP校验
;------伪头部
clr A
movx @DPTR,A
inc DPTR
mov A,#11h
movx @DPTR,A
inc DPTR
mov A,R6
movx @DPTR,A
inc DPTR
mov A,R7
movx @DPTR,A
inc DPTR
mov R0,#60H
mov R1,#8
wait098:
mov A,@R0
movx @DPTR,A
inc DPTR
inc R0
djnz R1,wait098

;-------- 真正的头部
mov R1,#4
wait056:
mov A,@R0
movx @DPTR,A
inc DPTR
inc R0
djnz R1,wait056
mov A,R6         ;UDP长度
movx @DPTR,A
inc DPTR

⌨️ 快捷键说明

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