##1. modebus poll和modbus slave决定收发帧格式
参考博客

《Modbus软件开发实战》第63页—4.2.4借助工具软件观察和理解

####首先定义从机的发送帧

打开model slave

nmodbus slave 使用demo_数据


具体修改是直接在编辑框输入,右击格式设置为Hex(16进制),注意这里每一行代表2个字节

编辑框右击设置属性,点击 slave defi…(F8)

nmodbus slave 使用demo_数据_02


address 起始地址 Quantity 代表从起始位置连续的个数 这里为从0-5

View 显示方式

以上设置后之后点击上方Connencton进行发送

nmodbus slave 使用demo_编辑框_03


串口设置那一栏代表从com1发送到com2

至此发送机完毕,然后MFC程序中的代码可参照上述去写

然后主机测试

打开modbus poll 编辑框设置和slave保持一致 设置Alias 不用设置后面的值,那是接受过来的数据

nmodbus slave 使用demo_字符串_04


设置读取起始位置和长度

nmodbus slave 使用demo_字符串_05


连接

nmodbus slave 使用demo_编辑框_06


就可以看到发过来的数据

nmodbus slave 使用demo_字符串_07


##2.MFC程序设计

查看所要发送的格式

在modbus poll中打开display->Comm…然后可以看到收过来的数据

nmodbus slave 使用demo_字符串_08


Rx是收过来的数据

具体为

nmodbus slave 使用demo_编辑框_09


回传帧解析

nmodbus slave 使用demo_数据_10

设计发送帧

根据上文可以知道发送的数据为
Rx:2798-01 03 0C 00 00 00 0D 00 18 00 09 00 45 00 02 1F F4
其中01为地址为 03为功能码 0C为数据位长度 后面至02都为数据位(每两组代表一个指示)
代码实现时,全部把这些都带上就行
例如

CByteArray  arraySend;
	//设备地址(2)+摄像头(2)+小时(2)+分钟(2)+秒(2)+宽度(2)+高度(2)+校验(2) = 16个字节
		int datalen = 12;
		BYTE bytSend[17];//发送字符串 
		bytSend[0] = addr;
		bytSend[1] = 0x03;//功能位
		bytSend[2] = datalen;//数据长度
		//数据
		bytSend[3] = ((camera & 0xff00) >> 8);//发送高八位  摄像头
		bytSend[4] = (camera & 0xff);//发送低八位
		bytSend[5] = ((hour & 0xff00) >> 8);//发送高八位
		bytSend[6] = (hour & 0xff);//发送低八位
		bytSend[7] = ((minute & 0xff00) >> 8);
		bytSend[8] = (minute & 0xff);
		bytSend[9] = ((sceond & 0xff00) >> 8);
		bytSend[10] = (sceond & 0xff);
		bytSend[11] = ((width & 0xff00) >> 8);
		bytSend[12] = (width & 0xff);
		bytSend[13] = ((hight & 0xff00) >> 8);
		bytSend[14] = (hight & 0xff);
		USHORT CRC = MBCRC16((UCHAR *)bytSend, 15);//CRC校验
		bytSend[15] = (CHAR)(CRC & 0xFF);
		bytSend[16] = (CHAR)((CRC & 0xFF00) >> 8);
		arraySend.RemoveAll();
		arraySend.SetSize(17);
		for (int i = 0; i < 17; i++)
		{
			arraySend.SetAt(i, bytSend[i]);   //数据存在arraySend里面了   
		}

		m_ctrlComm.put_Output(COleVariant(arraySend));

发送时改为自动发送
就完成了要求,即符合modbus的串口通信

第一个询问码说明:
01 03 00 00 00 06 C5 C8
01为设备地址,一个子节
03为功能码,一个字节
00 00 为寄存器起始地址,两个字节
00 06 为寄存器长度,两个字节
C5 C8为校检位
相应的
返回帧
01 03 0C 00 00 00 0D 00 19 00 09 00 49 00 02 A6 F6
01为设备地址,一个字节
03为功能码,一个字节
0C为有效字节为,12, 一个字节,表示后12位为有效数据
00 00为摄像头参数 两个字节
00 0D为小时 两个字节
00 19为分钟 两个字节
00 09为秒 两个字节
00 49为宽度 两个字节
00 02为高度两个字节
A6 F6为校检位