本帖最后由 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是我为了区分加上的)
-------------------------------------------------------------------
晕,发现自己发错了,少发一位...
|