单片机多机通信(课程设计)[1]

  • 格式:docx
  • 大小:26.79 KB
  • 文档页数:15

一﹑数据通信协议

1.帧格式:

总字节数 + 命令 + 地址 + 内容 + 校验

2.帧格式说明:

总字节数:4 位

命令:4 位

地址:1 字节

校验:1 字节

内容:实际传送的数据,最大为13字节

3.总字节数说明:总字节数4位,一帧数据最大16个字节,最小3个字节

4.命令格式说明:

0000:寻址命令,此时地址表示从机的ID

0001:应答寻址命令

0010:主机向从机写数据命令

0011:主机向从机读数据命令

0100:从机应答主机的读/写命令

此时是片内寻址命令。地址表示从机内存的起始地址,主机读/写数据的起始地址,地址的增长方向由主机决定,寻址范围:0

~ 255

0101:从机向主机写数据命令

0110:从机向主机读数据命令

0111:主机响应从机读/写

此时是片内寻址命令。地址表示主机内存的起始地址,从机读/写数的起始地址,地址的增长方向由从机决定,寻址范围:0 ~

255

1000:

1001:

1010:

1011:

1100:

1101:

此时是片外寻址命令,地址增为2个字节,寻址范围:0 ~ 64K

此命令是未开发命令

1110:帧错误 1111:通信结束命令

5.地址格式说明:

当片内寻址命令时,地址是一个字节,寻址片内范围:0 ~ 255

当片外寻址命令时,地址是两个字节,寻址范围:0 ~ 64K

6.内容格式说明:

是传输的数据,总大小有帧大小以及命令格式决定

7.校验格式说明:

校验是存储帧中数字1的个数

二、主机通信程序流程图

三、从机通信程序流程图 N Y Y N Y N N Y 开始

主机初始化

置M为计数标志

M = 0?

发送地址帧,M = M-1

收到从机应答帧

解析应答帧

帧校验正确?

重设M的值

M = 0 ?

发送数据帧M = M-1 通信失败

通信失败 N

Y Y N

解析应答帧

解析应答帧

帧校验正确? 收到应答帧 等待从机应答帧

返回 通信结束

N

Y N

Y Y N

Y

N Y N Y N Y N 从机初始化

等待主机广播

收到地址帧

解析地址帧

校验正确?

地址匹配?

回复应答帧

值SM2 = 0

置M为计数器

M = 0 ?

接受一帧数据 收到一帧数据

解析帧数据

校验正确?

处理接受的一帧数据 是数据帧?

重置M的值

通信失败 结束帧

准备接受下一帧

四、主机通信功能模块

1、主机初始化模块

设置缓冲区16个字节(既是发送,又是接收缓冲区)

设置计数值M

设置堆栈指针

2、帧设置模块

设置帧的通信方式(总字节数、命令、地址、内容、校验)

计算校验方式即设置校验字节

3、接受帧模块

送数据到指定的缓冲区

4、发送帧模块

设置发送缓冲区

5、解析帧模块

解析帧大小

解析帧命令

解析地址

五、从机通信功能模块

1、主机初始化模块

设置缓冲区16个字节(既是发送,又是接收缓冲区)

设置计数值M

设置堆栈指针

2、帧设置模块

设置帧的通信方式(总字节数、命令、地址、内容、校验)

计算校验方式即设置校验字节

3、接受帧模块

设置接收缓冲区

4、发送帧模块

根据解析格式发送数据

5、解析帧模块

解析帧大小

解析帧命令

解析地址

/*

多机通信中的主机通信程序

将以地址04H开始的数据发送到从机缓冲区中

*/

org 0000h

ljmp start

org 0024h ;0014h~0023h,16字节为数据缓冲区

start:

mov sp,#03h ;0004h~0013h为堆栈区

mov r2,#6 ;计数值N

mov 07h,#255

clr es ;关闭串口中断

sloop1:call set_frame

mov a,r2

jz error

call send_frame

dec r2

call receive_frame

mov a,07h

jz sloop1 ;没有收到应答帧

call analy_frame ;有收到应答帧

cjne r6,#01h,sloop1 ;没有收到从机地址应答帧

mov r2,#6 ;重设N的值

sloop2:call send_frame ;发送数据帧

mov a,r2

jz error

dec r2

call receive_frame

mov a,07h

jz sloop2 ;没有收到应答帧

call analy_frame ;有收到应答帧

cjne r6,#04h,error;没有收到数据应答帧,失败

jmp mreturn

error:

sjmp $

mreturn:

ljmp start

/*

函数名称:set_frame

入口参数:r0(帧缓冲区首址)、r1(帧数据区首址)

r7(帧大小)、r6(帧命令)

r5(地址)、r4(校验)、r3(帧数据大小)

出口参数:r0(帧缓冲区首址)、r1(帧数据区首址)

r7(帧大小)、r6(帧命令)

r5(地址)、r4(校验)、r3(帧数据大小)

功能:设置帧

*/

set_frame:

mov r0,#14h

mov a,r7 ;设置帧的大小

swap a

mov @r0,a

mov a,r6 ;设置帧命令

orl a,@r0

mov @r0,a

inc r0

mov a,r5

mov @r0,a ;设置地址(从机地址或内存地址)

cjne r3,#0,sloop

jmp sreturn

sloop:

inc r0

mov a,@r1

mov @r0,a

djnz r3,sloop

sreturn:

call check_frame ;此处应该增加一个校验函数

ret

/*

函数名称:send_frame

入口参数:r0(帧缓冲区首址)、

r7(帧大小)、r3(帧数据大小)

出口参数:无

功能:发送帧

*/

send_frame:

loop2:

mov a,@r0

mov sbuf,a

jnb ti,$

inc r0

djnz r7,loop2

clr ti

ret

/*

函数名称:receive

入口参数:r0(帧缓冲区首址)、07h(表示接受时限)

07h = 0表示主机等待超时,接收失败

出口参数:r0(帧缓冲区首址)、07h

函数功能:*/

receive_frame:

wait:

jb ri,rec

djnz 07h,wait

jmp rreturn

rec:

mov a,sbuf

mov @r0,a

swap a ;计算接收帧的大小

anl a,#0eh

mov r7,a

clr ri

loop3: ;接收帧的数据

jnb ri,$

inc r0

mov @r0,sbuf

djnz r7,loop3

call analy_frame

rreturn:

ret

/*

函数名称:check_frame

出口参数:r0(帧缓冲区首址)

入口参数:r0(帧缓冲区首址)

r4(校验)

功能:帧校验函数,累加帧中1个数

*/

check_frame:

mov r4,#00h

mov a,@r0

anl a,#0f0h

swap a

mov r7,a

mov a,#01h

check: ;累加帧中1的个数

anl a,@r0

jz cloop

inc r4

cloop:

rl a

djnz r7,check