📄 ex3modbus.c
字号:
}
else
bytes=OrgModBusYx(RegAddr,RegCount);
break;
case READ_OUTPUT_REGISTERS:
case READ_INPUT_REGISTERS:
RegCount=Modp->FromBuff[Modp->SynBytes+3]<<8|Modp->FromBuff[Modp->SynBytes+4];
#ifdef DEBUG_MODBUS
printf("Modp->RegCount:0x%04x\n",RegCount);
#endif
if(RegAddr>=Lib.TotalYcNum)
bytes=OrgModBusYc(RegAddr,0);
else if(RegAddr+RegCount>Lib.TotalYcNum)
{
#ifdef DEBUG_MODBUS
printf("waring:RegAddr+RegCount>Lib.TotalYcNum!\n");
#endif
count=Lib.TotalYcNum-RegAddr;
bytes=OrgModBusYc(RegAddr,count);
}
else
bytes=OrgModBusYc(RegAddr,RegCount);
break;
case FORCE_SINGLE_COIL:
if(Modp->FromBuff[Modp->SynBytes+3]==0xFF&&Modp->FromBuff[Modp->SynBytes+4]==0x00)
yxstate=0x01;
else if(Modp->FromBuff[Modp->SynBytes+3]==0x0&&Modp->FromBuff[Modp->SynBytes+4]==0x00)
yxstate=0x0;
else return -ERR_SET_SINGLE_COIL;
PresetModPara(RegAddr,1,&yxstate,1);
return -RCV_SET_PKT_OK;
break;
case PRESET_SINGLE_REGISTER:
PresetModPara(RegAddr,1,&Modp->FromBuff[Modp->SynBytes+3],2);
return -RCV_SET_PKT_OK;
break;
case FORCE_MULTIPLE_COILS:
case PRESET_MULTIPLE_REGISTERS:
RegCount=Modp->FromBuff[Modp->SynBytes+3]<<8|Modp->FromBuff[Modp->SynBytes+4];
PresetModPara(RegAddr,RegCount,&Modp->FromBuff[Modp->SynBytes+6],Modp->FromBuff[Modp->SynBytes+5]);
return -RCV_SET_PKT_OK;
break;
default:break;
}
totalbytes=OrgModPkt(UartNo,bytes);
delay(5000000);
Modp->SendBytes=SendUart(UartNo,Modp->ToBuff,totalbytes);
if(Modp->SendBytes==totalbytes)
Processed=ON;
return Processed;
}
/***********************************************************************/
/* FunName: OrgModPkt
/* InPut : UartNo,nbytes
/* Output : totalbytes
/* Function : organize and send modbus' package
/* By : zhanghong
/* Time : 2006-12-3
/***********************************************************************/
WORD OrgModPkt(WORD UartNo, WORD nbytes)
{
BYTE i;
WORD CheckSum,totalbytes,Crc16,mark=OFF;
struct ModS *Modp;
Modp=&Mod;
Modp->ToBuff[Modp->SynBytes-1]=MODBUS_ADDR;
Modp->ToBuff[Modp->SynBytes]=Lib.ModBusCmd;
if(Modp->Cmd==READ_OUTPUT_STATUS||Modp->Cmd==READ_INPUT_STATUS
||Modp->Cmd==READ_OUTPUT_REGISTERS||Modp->Cmd==READ_INPUT_REGISTERS)
{
Modp->ToBuff[Modp->SynBytes+1]=nbytes;
nbytes=nbytes+3;
}
CheckSum=CalModBusCrc16(&Modp->ToBuff[Modp->SynBytes-1],nbytes);
Crc16=WordSwap((BYTE *)&CheckSum);
#ifdef DEBUG_MODBUS
printf("ModBus OrgCrc is %04x\n",Crc16);
#endif
Modp->ToBuff[nbytes]=*(BYTE *)&Crc16;
Modp->ToBuff[nbytes+1]=*((BYTE *)&Crc16+1);
totalbytes=nbytes+2;
#ifdef DEBUG_MODBUS
{
printf("OrgModPkt is:");
for(i=0;i<totalbytes;i++)
printf("%02x",Modp->ToBuff[i]);
printf("\n");
}
#endif
return(totalbytes);
}
/***********************************************************************/
/* FunName: PresetModPara
/* InPut : RegAddr,RegCount,&p,ByteCount
/* Output : void
/* Function : set yx to modbus
/* By : zhanghong
/* Time : 2006-11-27
/***********************************************************************/
void PresetModPara(WORD RegAddr,WORD RegCount,BYTE *p,WORD ByteCount)
{
BYTE i,*pb;
WORD mark;
Lib.Isdown=ON; //ModBus is setting para
memlongcpy(Lib.RcvModBuff, p, ByteCount);
#ifdef DEBUG_MODBUS
printf("mod:PresetModPara--RegAddr:%04x,RegCount,%04x,cmd:%02x\n",RegAddr,RegCount,Lib.ModBusCmd);
printf("mod:PresetModPara--data:");
pb=Lib.RcvModBuff;
for(i=0;i<ByteCount;i++)
printf("%02x",*pb++);
printf("\n");
#endif
Lib.RcvModeBytes=ByteCount;
if(Lib.ModBusCmd==FORCE_SINGLE_COIL|Lib.ModBusCmd==FORCE_MULTIPLE_COILS)
Lib.pYxDown=Lib.RcvModBuff;
else Lib.pYcDown=Lib.RcvModBuff;
Lib.DownRegAddr=RegAddr;
Lib.DownRegCount=RegCount;
}
/***********************************************************************/
/* FunName: OrgModSinRet
/* InPut : &RegAddr,&Regvalue
/* Output : bytecount
/* Function : org ret after succeded in set node' single-para
/* By : zhanghong
/* Time : 2006-12-5
/***********************************************************************/
WORD OrgModSinRet(BYTE *RegAddr,BYTE *Regvalue)
{
struct ModS *Modp;
Modp=&Mod;
Modp->ToBuff[Modp->SynBytes+1]=RegAddr[1];
Modp->ToBuff[Modp->SynBytes+2]=RegAddr[0];
if(Modp->Cmd==FORCE_SINGLE_COIL)
{
Regvalue[0]?(Modp->ToBuff[Modp->SynBytes+3]=0xFF):(Modp->ToBuff[Modp->SynBytes+3]=0x0);
Modp->ToBuff[Modp->SynBytes+4]=0x0;
}
else
{
Modp->ToBuff[Modp->SynBytes+3]=Regvalue[0];
Modp->ToBuff[Modp->SynBytes+4]=Regvalue[1];
}
return 6;
}
/***********************************************************************/
/* FunName: OrgModMultiRet
/* InPut : &RegAddr,&RegCount
/* Output : bytecount
/* Function : org ret after succeded in set node' multi-para
/* By : zhanghong
/* Time : 2006-12-5
/***********************************************************************/
WORD OrgModMultiRet(BYTE *RegAddr,BYTE *RegCount)
{
struct ModS *Modp;
Modp=&Mod;
Modp->ToBuff[Modp->SynBytes+1]=RegAddr[1];
Modp->ToBuff[Modp->SynBytes+2]=RegAddr[0];
Modp->ToBuff[Modp->SynBytes+3]=RegCount[1];
Modp->ToBuff[Modp->SynBytes+4]=RegCount[0];
return 6;
}
/***********************************************************************/
/* FunName: OrgModBusYx
/* InPut : RegAddr,RegCount
/* Output : bytecount
/* Function : org yx to modbus
/* By : zhanghong
/* Time : 2006-11-25
/***********************************************************************/
WORD OrgModBusYx(WORD RegAddr,WORD RegCount)
{
BYTE startbit,i,j,offleft,offright,*pb;
WORD bytecount,startbyte;
struct ModS *Modp;
Modp=&Mod;
(Modp->Cmd==READ_INPUT_STATUS)?(pb=Lib.YxInBuff):(pb=Lib.YxOutBuff);
#ifdef DEBUG_MODBUS
printf("mod:actual->RegAddr:0x%04x,actual->RegCount:0x%04x\n",RegAddr,RegCount);
#endif
startbyte=RegAddr/8;
startbit=RegAddr%8;
offleft=(8-startbit)%8;
offright=startbit%8;
bytecount=(RegCount+7)/8;
#ifdef DEBUG_MODBUS
{
printf("startbyte is:%i,startbit is:%i,offleft is:%i,offright is:%i\n",startbyte,startbit,offleft,offright);
if(Modp->Cmd==READ_INPUT_STATUS)
printf("Lib.YxInBuff is :");
else
printf("Lib.YxOutBuff is :");
for(i=0;i<4;i++)
printf("%02x",pb[i]);
printf("\n");
}
#endif
for(i=0;i<bytecount;i++)
{
if(offleft)
Modp->ToBuff[i+3]=(pb[startbyte+i]>>offright)|(pb[startbyte+i+1]<<offleft);
else
Modp->ToBuff[i+3]=pb[startbyte+i];
}
if(startbit)
{
j=pow(2,RegCount%8)-1;
Modp->ToBuff[bytecount+2]&=j;
}
#ifdef DEBUG_MODBUS
{
printf("OrgModBusYx is: ");
for(i=0;i<bytecount;i++)
printf("%02x",Modp->ToBuff[i+3]);
printf("\n");
}
#endif
return(bytecount); //add addr,cmd,bytescount
}
/***********************************************************************/
/* FunName: OrgModBusYc
/* InPut : RegAddr,RegCount
/* Output : bytecount
/* Function : org yc to modbus
/* By : zhanghong
/* Time : 2006-11-28
/***********************************************************************/
WORD OrgModBusYc(WORD RegAddr,WORD RegCount)
{
BYTE i,*pb;
WORD bytecount,startbyte;
struct ModS *Modp;
Modp=&Mod;
(Modp->Cmd==READ_INPUT_REGISTERS)?(pb=Lib.YcInBuff):(pb=Lib.YcOutBuff);
#ifdef DEBUG_MODBUS
printf("mod:actual->RegAddr:0x%04x,actual->RegCount:0x%04x\n",RegAddr,RegCount);
#endif
startbyte=RegAddr*2;
bytecount=RegCount*2;
#ifdef DEBUG_MODBUS
{
if(Modp->Cmd==READ_INPUT_REGISTERS)
printf("Lib.YcInBuff is :");
else
printf("Lib.YcOutBuff is :");
for(i=0;i<20;i++)
printf("%02x",pb[i]);
printf("\n");
}
#endif
for(i=0;i<RegCount;i++)
{
Modp->ToBuff[i*2+3]=pb[startbyte+i*2];
Modp->ToBuff[i*2+4]=pb[startbyte+i*2+1];
#ifdef DEBUG_MODBUS
printf("OrgModBusYc%x is: %x\n",i,Modp->ToBuff[i*2+3]<<8|Modp->ToBuff[i*2+4]);
#endif
}
return(bytecount); //add addr,cmd,bytescount
}
/***********************************************************************/
/* FunName: ReadNoByteFromModBus
/* InPut : UartNo
/* Output : void
/* Function : Read no byte from uart used for modbus
/* By : zhanghong
/* Time : 2006-11-25
/***********************************************************************/
void ReadNoByteFromModBus(WORD UartNo)
{
time_t CurTime,Dltt1,Dltt2;
WORD UnitNo;
struct ModS *Modp;
Modp=&Mod;
mytime(&CurTime);
Dltt1=DiffTime(&CurTime,&Modp->LastRecvDataTime);
Dltt2=DiffTime(&CurTime,&Modp->OnePktSendTime);
if(Dltt1>LIMIT_MODBUS_T)
{
mytime(&Modp->LastRecvDataTime);
Lib.ModBusStat=STOPPED;
}
if(Dltt2>=LIMIT_MODBUS_T1){ /*overtime or a part packet*/
Modp->PktIsTimeOut=ON;
if(++Modp->ErrTimes>LIMIT_MODBUS_ERR_TIMES){
Lib.ModBusStat=FAULT;
Modp->ErrTimes=0;
}
}
}
/***********************************************************************/
/* FunName: ClearModBuff
/* InPut : UartNo
/* Output : void
/* Function : Clear Modbus's buff
/* By : zhanghong
/* Time : 2006-11-25
/***********************************************************************/
void ClearModBuff(WORD UartNo)
{
struct ModS *Modp;
Modp=&Mod;
Modp->SyncFull=OFF;
Modp->HeadFull=OFF;
Modp->DataFull=OFF;
Modp->SearchSyncNum=0;
Modp->RecvSyncNum=0;
Modp->RecvByteNum=0;
Modp->SendPktStat=OFF;
}
/***********************************************************************/
/* FunName: ModBusBuffInit
/* InPut : UartNo
/* Output : void
/* Function : Init Modbus's buff in EX3init in mian.c
/* By : zhanghong
/* Time : 2006-11-25
/***********************************************************************/
void ModBusBuffInit(WORD UartNo)
{
struct ModS *Modp;
Modp=&Mod;
Modp->Cmd=0;
Modp->ErrTimes=0;
Modp->OrgPktStat=OFF;
Modp->ReadNeed=ON;
Modp->RecvData=OFF;
Modp->SyncFull=OFF;
Modp->HeadFull=OFF;
Modp->DataFull=OFF;
Modp->PktIsTimeOut=OFF;
Modp->SendPktStat=OFF;
Modp->SearchSyncNum=0;
Modp->RecvSyncNum=0;
Modp->RecvByteNum=0;
Modp->OrgBytes=0;
Modp->SendBytes=0;
Modp->StatReceived=OFF;
Modp->SynCode[0]=MODBUS_ADDR;
Modp->SynBytes=1; //just is addr
Modp->HeadBytes=5;
Modp->RcvDataBytes=0;
//Modp->PktBytes=MODBUS_FRAME_LENGTH;
mytime(&Modp->LastRecvDataTime);
ClearModBuff(UartNo);
}
/***********************************************************************/
/* FunName: CalModBusCrc16
/* InPut : Buf[],nbytes
/* Output : void
/* Function : CRC function
/* By : zhanghong
/* Time : 2006-11-25
/***********************************************************************/
WORD CalModBusCrc16(BYTE Buf[],WORD nbytes)
{
BYTE i ,jj,CH,CL;
WORD Crc16;
CH = 0xff;
CL = 0xff;
for(i=0;i<nbytes;i++)
{
jj = CH ^ Buf[i];
CH = CL ^ AUCHCRCHI[jj];
CL = AUCHCRCLO[jj];
}
Crc16=CH*256+CL;
return(Crc16);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -