Proteus仿真二,通过51单片机来实现虚拟串口通信,基于MODBUS_RTU协议(2)

Proteus仿真二,通过51单片机来实现虚拟串口通信,基于MODBUS_RTU协议(2)

接着上一章的内容来讲,本次主要实现的是功能码0x03的功能。前面说过了它的主要功能是读取多个寄存器。先看报文:
我在下位机的寄存器1和寄存器2给予了1,2的值,上位机同时读取到了下位机的值。
在这里插入图片描述
报文如下,
Tx:175-01 03 00 00 00 02 C4 0B
Rx:176-01 03 04 00 01 00 02 2A 32
TX表示发送,即上文机往下位机发送的报文。01 为从机地址,03为功能码,00 00表示寄存器,00 02表示寄存器的数量,C4 0B为校验码。
下位机接收到这报文后先需要做的是检验发送过来的报文的校验码是否正确,然后在进行对功能码的分析。
RX表示的是下位机发送给上位机的报文。01为从机地址,03为功能码,04为数据的个数,因为上位机是要读取2个寄存器的值,一个寄存器的值有2个字节,所以2*2=4。所以数据个数为4。00 01为寄存器0的值,00 02为寄存器1的值,2A 32为下位机的校验码。
分析完后就可以对上一章所接受到的1帧报文进行分析了。

先分析报文的校验码,从站地址和功能码。

void DisposeEvent(void)
{
	unsigned int CRCCheck;
	unsigned int ReCRC;
	if(Modbus.ReFlag!=1)
	{
		return;
	}
	CRCCheck=crc16(&Modbus.ReBuff[0],6);
	ReCRC=Modbus.ReBuff[6]<<8|Modbus.ReBuff[7];
	
	if(CRCCheck==ReCRC)
	{
		if(Modbus.ReBuff[0]==Modbus.SlaveID)
		{
			switch(Modbus.ReBuff[1])
			{
				case 0x03:Func_0x03();break;
				case 0x06:Func_0x06();break;
				case 0x10:Func_0x10();break;	
			}
			
			
		}
	}
	
	Modbus.Cnt=0;
	Modbus.ReFlag=0;

}

然后则是对功能码的处理

void Func_0x03(void)
{
	unsigned char i=0;
	unsigned char j=0;
	unsigned int cnt=0;
	unsigned int add=0;
	unsigned int CRCCheck=0;
	
	Modbus.SendBuff[i++]=Modbus.SlaveID;
	Modbus.SendBuff[i++]=0x03;
	cnt=(Modbus.ReBuff[4]<<8|Modbus.ReBuff[5])*2;
	Modbus.SendBuff[i++]=cnt;
	add=Modbus.ReBuff[2]<<8|Modbus.ReBuff[3];
	for(j=0;j<cnt/2;j++)
	{
		Modbus.SendBuff[i++]=regs[add+j]/256;
		Modbus.SendBuff[i++]=regs[add+j]%256;	
	}
	CRCCheck=crc16(Modbus.SendBuff,i);
	Modbus.SendBuff[i++]=CRCCheck/256;
	Modbus.SendBuff[i++]=CRCCheck%256;
	for(j=0;j<i;j++)
	{
		SBUF=Modbus.SendBuff[j];
		while(TI==0);
		TI=0;
	}	
}

最后则可以通过Modbus调试助手来进行检验。打开调试精灵,
在这里插入图片描述
选择COM为1,波特率为9600(改了波特率),然后读取寄存器1的值
在这里插入图片描述
读取寄存器2
在这里插入图片描述
从寄存器1读取3个寄存器
在这里插入图片描述
验证成功!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值