我在Simple serial point-to-point communication protocol查看答案,但对我的问题并没有给予足够的帮助。我也在尝试在计算机和8位微控制器之间进行数据通信,最后我想通过无线电模块将一个微控制器与另外40个微控制器进行通信。基本上一个被指定为主人,其余的是奴隶。
速度是一个问题
手头的问题是速度。因为每个数据包的通信需要在主设备和每个从设备之间来回至少4次。
假设数据的波特率为9600bps。那是每秒960个字节。
如果我使用16字节数据包,则:40(从设备)乘以16(字节)乘以2(路径)= 640.将其除以960,这意味着超过1/2秒。不好。
如果我使用8字节数据包,那么:40(从设备)乘以8(字节)乘以2(路径)= 320.将其除以960,这意味着1/3秒。一切都是这样。
但问题是我需要观察我的波特率,因为过高的波特率可能意味着在较远距离丢失数据,但你可以看到8到16字节数据包之间的速度差异。
数据包格式理念
在我的设计中,我可能需要传输数百万的数字,以便使用24位符合我的想法。但这是我最初的想法:
Byte 1: Recipient address 0-255
Byte 2: Sender address 0-255
Byte 3: Command
Byte 4-6: Data
Byte 7-8: 16-bit fletcher checksum of above data
我不介意调整上述格式,只要我有至少6位来识别发送方和接收方(因为我只处理40个单元),以及数据包含的命令应至少为4个字节。
我应该如何修改我的数据包构思,以便即使在接收过程中刚开启的设备也可以与下一组数据同步?有没有办法从每个数据字节中剥离一点?
答案 0 :(得分:2)
依靠支票金额!我的数据包将包含:
每个接收器都应该有一个最后七个接收字节的滑动窗口。移入一个字节时,应检查该窗口是否有效:
特别是最后一个应该安全地拒绝接收器跳转到同步的数据包。
如果您的命令代码少于32个,则每个数据包可能会减少到6个字节:40 [发送者]时间40 [接收者]时间32 [命令]评估为51200,这将适合16位而不是24位。
不要忘记关闭奇偶校验位!
更新2017-12-09:这是一个接收功能:
typedef uint8_t U8;
void ByteReceived(U8 Byte)
{
static U8 Buf[7]; //Bytes received so far
static U8 BufBC=0;
Buf[BufBC++] = Byte;
if (BufBC<7) return; //Msg incomplete
/*** Seven Byte Message received ***/
//Check Addresses
U8 Adr;
Adr = Buf[0] ^ 0x55; if (Adr >= 40) goto Fail;
Adr = Buf[1] ^ 0xAA; if (Adr >= 40) goto Fail;
if (Buf[2] > ???) goto Fail; //Check Cmd
if (CalcCRC8(Buf, 6) != Buf[6]) goto Fail;
Evaluate(...);
BufBC=0; //empty Buf[]
return;
Fail:
//Seven Byte Msg invalid -> chop off first byte, could use memmove()
Buf[0] = Buf[1];
Buf[1] = Buf[2];
Buf[2] = Buf[3];
Buf[3] = Buf[4];
Buf[4] = Buf[5];
Buf[5] = Buf[6];
BufBC = 6;
}