📄 startup.a51
字号:
/*********************************************
发送缓冲区信息数据结构:
byte SBB ;send buffer begin(value:68h)(ram:30h)
byte SBTA ;send buffer target address(31h)
byte SBCMD ;send buffer command(32h)
byte SBDL ;sned buffer data length(33h)
bytes SBDS ;send buffer datas(ram:34h-3ch)
byte SBS ;send buffer sum(3dh)
byte SBE ;send buffer end(value:eeh)(ram:3eh)
接收缓冲区类似,但地址改为40H-4fH
接收状态字 RStatus控制接收到的信息存放位置
Rstatus 00H 初始态,等待接收开始符
Rstatus 01H 等待接收地址
Rstatus 02H 等待接收命令字
Rstatus 03H 等待接收数据长
Rstatus 04H 等待接收数据
Rstatus 05H 等待接收校验和
Rstatus 06H 等待接收结束符
command: (SBCMD RBCMD)
value:0fh means:地址为0ffh广播时候重置所有下位机的sm2为1
value:80h means:地址匹配命令 只有下位机地址与数据帧地址一致时候才清该下位机的sm2
如果有匹配的下位机,则返回一个command为01h 数据:00h(该下位机无数据需要发送)
01h(该下位机有数据需要发送)
value:81h means:允许下位机数据发送信号
value:01h means:command为01H代表该帧为响应帧
value:82h means:command为82h代表该帧为数据帧
addr 下位机地址
************变量初始化**************************/
SBB equ 30h ;帧头 总为68h
SBTA equ 31h ;目标地址
SBCMD equ 32h ;command
SBDL equ 33h ;9=>sbdl>=1 34h-3ch存放发送的数据,不在长度范围内将导致数据发送失败
SBS equ 3dh ;校验和
SBE equ 3eh ;帧尾 总为 55h
addr equ 3fh ;数据发送目标地址
RBB equ 40h ;类似发送缓冲区
RBTA equ 41h
RBCMD equ 42h
RBDL equ 43h ;9=>rbdl>=1 44h-4ch存放接收的数据
RBS equ 4dh
RBE equ 4eh
Rstatus equ 4fh ;接收状态字 代表目前接收的字节归属
RBRDY bit 00h ;接收完成标志
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
org 00h
ljmp start
org 0bh
ljmp T_0 ;T0用于判断下位机响应是否超时
org 23h
ljmp recieve
org 30h
start:
mov sp,#6fh
anl pcon,#7fh ;设置smod=0
mov scon,#90h ;串行方式2
clr sm2 ;不论收到的rb8值是多少,都可以接收到数据
setb ea ;开总中断
setb es ;开串口中断
setb ps ;串口中断优先
mov tmod,#01h ;定时器方式1
setb et0 ;开定时器中断
clr tr0 ;暂时不计时
mov r0,#0fh ;重置所有下位机
mov r1,#1h ;数据长为1 (无用的数据,兼容用)
mov 34h,#00h ;任意值
mov addr,#0ffh ;广播地址
setb TB8 ;所有mcu都可以接收到此信息
lcall write_SB
lcall Send ;发送
mov addr,#00h
next_mcu:
lcall next_addr ;取下一下位机地址
mov r0,#80h ;地址匹配命令
mov r1,#1h ;
mov 34h,#00h ;任意值
setb TB8 ;所有下位机都可以接收到此信息
lcall write_SB
lcall Send ;发送
setb tr0 ;计时开始
jnb RBRDY,$
clr tr0
mov th0,#0
mov tl0,#0
clr RBRDY
mov a,#01h
cjne a,RBCMD,next_mcu ;不是slave机响应信息则说明该机不存在,测试下一地址
mov a,#01h
cjne a,44h,next_mcu ;接收到的数据不是01h说明slave机没有需要传送的数据,测试下一mcu
permit:
mov r0,#81h ;允许下位机发送数据指令
mov r1,#1h
mov 34h,#00h
clr TB8 ;只有符合地址为addr的机器才可以接收到此信息
lcall write_SB
lcall Send
setb tr0
jnb RBRDY,$ ;等待slave mcu传送数据
clr tr0
mov th0,#0
mov tl0,#0
clr RBRDY
mov a,#82h
cjne a,RBCMD,permit ;不是slave mcu传来的数据信息,说明数据传送出错,重新发送允许传送信号
lcall recieve_ok ;通知slave mcu 数据接收成功
lcall do ;处理接收到的数据
lcall Clear_recieveBuf ;清空接收缓冲区
ljmp next_mcu ;处理下一slave mcu
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
T_0:
setb RBRDY
reti
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
recieve_ok:
mov r0,#01h ;响应帧
mov r1,#1h
mov 34h,#00h
clr TB8
lcall write_SB
lcall Send
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
do:
mov r0,#44h
mov r1,RBDL
do_loop:
mov p2,@r0
setb rs0 ;避免wait1S程序与do程序 r0 r1互相干扰
lcall wait1S
clr rs0
inc r0
djnz r1,do_loop
lcall Clear_recieveBuf
ret
next_addr: ;取下一下位机地址 子程序 支持16台地址为1-10h的下位机
inc addr
mov a,#10h
clr c
subb a,addr
jnc no_bound
mov addr,#01h
no_bound:
ret
write_SB: ;写入发送缓冲区
mov SBB,#68h
mov SBTA,addr
mov SBCMD,r0
mov SBDL,r1
mov a,SBCMD
add a,SBDL
mov r0,#34h
add_datas:
add a,@r0
inc r0
djnz r1,add_datas
mov SBS,a
mov SBE,#55h
ret
recieve: ;数据接收
jbc TI,is_Send
clr RI
mov a,#00h
cjne a,Rstatus,ignore_begin
mov RBB,sbuf
mov a,#68h
cjne a,RBB,garbage_info
mov Rstatus,#01h
reti
garbage_info:
mov Rstatus,#00h
reti
is_Send:
reti
ignore_begin:
mov a,#01H
cjne a,Rstatus,ignore_addr
mov RBTA,sbuf
mov Rstatus,#02h
reti
ignore_addr:
mov a,#02h
cjne a,Rstatus,ignore_comm
mov RBCMD,sbuf
mov Rstatus,#03h
mov RBS,RBCMD
reti
ignore_comm:
mov a,#03h
cjne a,Rstatus,ignore_DLen
mov RBDL,sbuf
mov r1,RBDL
mov r0,#44h
mov a,RBS
add a,RBDL
mov RBS,a
mov Rstatus,#04h
reti
ignore_DLen:
mov a,#04h
cjne a,Rstatus,ignore_Data
mov @r0,sbuf
mov a,RBS
add a,@r0
mov RBS,a
inc r0
djnz r1,continueRD
mov Rstatus,#05h
continueRD:
reti
ignore_Data:
mov a,#05h
cjne a,Rstatus,ignore_Sum
mov a,sbuf
cjne a,RBS,recieve_err
mov Rstatus,#06h
reti
ignore_Sum:
mov a,#06h
cjne a,Rstatus,recieve_err
mov a,sbuf
cjne a,#55h,recieve_err
mov RBE,#55h
mov Rstatus,#00h
lcall recieve_success
reti
recieve_err:
mov Rstatus,#00h
lcall recieve_error
reti
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
recieve_success:
setb RBRDY
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
recieve_error:
;接收失败 扩展用
ret
Send: ;数据发送
mov sbuf,SBB
lcall wait1ms
mov sbuf,SBTA
lcall wait1ms
mov sbuf,SBCMD
lcall wait1ms
mov sbuf,SBDL
lcall wait1ms
mov r1,SBDL
mov r0,#34h
send_datas:
mov sbuf,@r0
setb rs0
lcall wait1ms
clr rs0
inc r0
djnz r1,send_datas
send_sum:
mov sbuf,SBS
lcall wait1ms
mov sbuf,SBE
lcall wait1ms
ret
/**************************************/
Clear_SendBuf: ;清发送缓冲区
mov r0,#30h
mov r1,#10h
clear_SB:
mov @r0,#0h
inc r0
djnz r1,clear_SB
ret
/******************************************/
Clear_RecieveBuf: ;清接收缓冲区
mov r0,#40h
mov r1,#10h
clear_RB:
mov @r0,#0h
inc r0
djnz r1,clear_RB
ret
/**************************************/
wait1S:
mov r0,#250d
WT1SL1:
mov r1,#200d
WT1SL2:
mov b,#10d
djnz b,$
djnz r1,WT1SL2
djnz r0,WT1SL1
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
wait1ms:
mov r0,#25d
w1msL1:
mov b,#20d
djnz b,$
djnz r0,w1msL1
ret
/**********************************************/
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -