本帖最后由 any_014 于 2015-5-26 16:56 编辑
再做个51modbus从机设备,基本上只接受03命令吗。
自己是这么写的:
首先判断帧头标志,如果没有接收到帧头,则先判断接收到的字节是否是帧头?是的话,置个标志位;
接受下个字节时,仍做帧头标志判断,因为已经置位了,所以直接放到后面的数组里;
问题是:
帧头比如是01,发一串数,中间也有用01,那么我接收的时候,就有时正确有时错位。
比较奇怪的是:
发一串数,明明应该判断第一个字节是否帧头,可碰到的大部分是判断中间接收到的字节是否是帧头,然后把先接收到的数循环到后面去了。
看了两个51modbus的。
一个是本论坛吴鉴鹰老师帖子里的modbus例子,他是接受8个字节,然后统一处理。
另一个是先到的显控的51modbus例子,用个定时器做超时判断。
uchar Rece_buf[20];
uchar Send_buf[10];
/**********************串口接收处理****************************/
//站号 | 命令 | 首地址 | 字节数 | 校验高低
//01 | 03 | 00 00 | 00 01 | 0A 84
void Rx_Process(void)
{
uint crc_end, data_len, send_len;
SendData(0x33);
SendData(Rece_buf[0]);
SendData(Rece_buf[1]);
SendData(Rece_buf[2]);
SendData(Rece_buf[3]);
SendData(Rece_buf[4]);
SendData(Rece_buf[5]);
SendData(Rece_buf[6]);
SendData(Rece_buf[7]);
if(0x03 == Rece_buf[1])
{
SendData(0x55);
crc_end = crc16(Rece_buf, 6);
if(crc_end == (Rece_buf[6]<<8 | Rece_buf[7]))
{
begin_address = Rece_buf[2]<<8|Rece_buf[3];
data_len = Rece_buf[4]<<8|Rece_buf[5];
Send_buf[0] = Rece_buf[0];
Send_buf[1] = Rece_buf[1];
Send_buf[2] = data_len*2;
for(send_len = 0; send_len < data_len*2; send_len++)
{
if(!(send_len%2))
Send_buf[send_len+3] = temp_value / 256;
else
Send_buf[send_len+4] = temp_value % 256;
}
crc_end = crc16(Send_buf, send_len + 3);
Send_buf[send_len + 3] = crc_end % 256;
Send_buf[send_len + 4] = crc_end >> 8;
// Send_word(Send_buf, data_len*2 + 5);
}
}
}
我现在是让单片机把接收到的数据直接发回来。
电脑发送:03 00 00 00 01 0A 84 电脑接收:33 01 0A 84 03 00 00 00 01 (33是我为了区分加上的)
-------------------------------------------------------------------
晕,发现自己发错了,少发一位...
|