27,373
社区成员
发帖
与我相关
我的任务
分享
unsigned char ModbusMaster(unsigned char *buf,unsigned char bufsize,unsigned int Address,unsigned int Count,unsigned char *target)
//主站处理函数,用于处理从站返回来的数据 通讯缓冲区,缓冲区大小,寄存器起始地址,数量,寄存器组(当功能码为读类指令时,需要指定 寄存器起始地址,数量,寄存器组 以便于存放)
//返回值为0时表示成功,否则有错误
{
unsigned char result=0xFF;
unsigned int i;
switch(buf[1])
{
case 0x01:
case 0x02:
if(CheckCRC(buf,bufsize,5+buf[2]))//CRC检查
{
for(i=0;i<Count;i++) ModbusWritebit(Address+i,ModbusReadbit(i,buf+3),target);
result=0;
}
break;
case 0x03:
case 0x04:
case 0x17:
if(target && CheckCRC(buf,bufsize,5+buf[2]))//CRC检查
{
if(Count<=buf[2]/2)
{
FillData(buf+3,target+Address*2,Count);
result=0;
}
}
break;
case 0x05:
case 0x06:
case 0x0F:
case 0x10:
case 0x16:
if(CheckCRC(buf,bufsize,8)) result=0;//CRC检查
break;
case 0x81:
case 0x82:
case 0x83:
case 0x84:
case 0x85:
case 0x86:
case 0x8F:
case 0x90:
case 0x96:
case 0x97:
if(CheckCRC(buf,bufsize,5)) result=buf[2];//CRC检查
break;
default:
break;
}
return result;
}
//---------------------------------------------------------------代码分割线---------------------------------------------------------------//
nsigned char ModbusRead(unsigned char ID,unsigned char FC,unsigned int Address,unsigned int Count,unsigned char *buf,unsigned char bufsize)
//主站读指令打包 设备地址,功能码,寄存器地址,数量,通讯缓冲区,缓冲区大小
//返回值为需要发送的字节数
{
unsigned char result=0;
if((FC<5)&&(bufsize>=8))
{
result=8;
buf[0]=ID;
buf[1]=FC;
ToUINT(buf+2)=Address;
ToUINT(buf+4)=Count;
}
if(result) ToUINT(buf+result-2)=CRC16(buf,result-2);
return result;
}
//---------------------------------------------------------------代码分割线---------------------------------------------------------------//
unsigned char ModbusWrite(unsigned char ID,unsigned char FC,unsigned int Address,unsigned int Count,unsigned int addr,unsigned char *source,unsigned char *buf,unsigned char bufsize)
//主站写指令打包 设备地址,功能码,寄存器地址,数量,本地寄存器地址,本地寄存器组,通讯缓冲区,缓冲区大小
//返回值为需要发送的字节数
{
unsigned char result=0;
unsigned int i;
if(bufsize>=8)
{
buf[0]=ID;
buf[1]=FC;
ToUINT(buf+2)=Address;
switch(FC)
{
case 0x05:
ToUINT(buf+4)=(ModbusReadbit(addr,source))?0xFF00:0x0000;
result=8;
break;
case 0x06:
ToUINT(buf+4)=ModbusReadWORD(addr,source);
result=8;
break;
case 0x0F:
ToUINT(buf+4)=Count;
buf[6]=(Count%8)?Count/8+1:Count/8;
if(bufsize>=buf[6])
{
for(i=0;i<Count;i++)
{
if(i%8==0) buf[7+i/8]=0;
ModbusWritebit(i,ModbusReadbit(addr+i,source),buf+7);
}
result=9+buf[6];
}
break;
case 0x10:
ToUINT(buf+4)=Count;
buf[6]=Count*2;
if(bufsize>=9+buf[6])
{
FillData(source+addr*2,buf+7,Count);
result=9+buf[6];
}
break;
default:
break;
}
if(result) ToUINT(buf+result-2)=CRC16(buf,result-2);
}
return result;
}