?? ex3modbus.c
字號:
/***********************************************************************/
/* FILE: Ex3ModBus.c
/***********************************************************************/
#include <time.h>
#include <math.h>
#include "Ex3.h"
#include "console.h"
#include "Ex3Comm.h"
#include "EX3ModBus.h"
extern struct LibS Lib;
struct ModS Mod;
/***********************************************************************/
/* FunName: FromToModBus
/* InPut : UartNo
/* Output : void
/* Function : The entry of this function
/* By : zhanghong
/* Time : 2006-11-25
/***********************************************************************/
void FromToModBus(WORD UartNo)
{
WORD bytes,totalbytes,Processed,Check;
time_t Curtime;
struct ModS *Modp;
Modp=&Mod;
//after modbus having setted para
if(Lib.Isdown==ON)
{
if(Lib.SetNodeOk==ON) //node ret is ok
{
switch(Lib.ModBusCmd)
{
case FORCE_SINGLE_COIL:
case PRESET_SINGLE_REGISTER:
bytes=OrgModSinRet((BYTE *)&Lib.DownRegAddr, Lib.RcvModBuff);
break;
case FORCE_MULTIPLE_COILS:
case PRESET_MULTIPLE_REGISTERS:
bytes=OrgModMultiRet((BYTE *)&Lib.DownRegAddr, (BYTE *)&Lib.DownRegCount);
break;
default: break;
}
totalbytes=OrgModPkt(UartNo, bytes);
delay(5000000);
Modp->SendBytes=SendUart(UartNo,Modp->ToBuff,totalbytes);
//clear info in Libs
Lib.ModBusCmd=0;
Lib.Isdown=OFF;
Lib.SetNodeOk=OFF;
Lib.DownRegAddr=0;
Lib.DownRegCount=0;
Lib.ModBusCmd=0;
Lib.pYcDown=NULL;
Lib.pYxDown=NULL;
}
else
{
mytime(&Curtime);
}
}
//receive pkt from modbus
if(Modp->SyncFull==OFF)FindModSync(UartNo);
if(Modp->SyncFull==ON&&Modp->HeadFull==OFF)ReadModHead(UartNo);
if(Modp->HeadFull==ON&&Modp->DataFull==OFF)ReadModData(UartNo);
if(Modp->DataFull==ON)
{
//Check=CheckModPkt(UartNo);
//if(Check==ON)
bytes=FromModProc(UartNo); //process the data has been received
switch(Processed)
{
case ON:
Modp->ErrTimes=0;
break;
case -RCV_SET_PKT_OK:
Lib.WaitNodeSet=ON;
Modp->ErrTimes=0;
break;
case -ERR_SET_SINGLE_COIL:
case OFF:
Modp->ErrTimes++;
break;
default: break;
}
ClearModBuff(UartNo);
Modp->RecvData=OFF;
}
}
/***********************************************************************/
/* FunName: FindScadaSync
/* InPut : UartNo
/* Output : void
/* Function : Find sync bytes from recvuart used for ModBus
/* By : zhanghong
/* Time : 2006-11-25
/***********************************************************************/
void FindModSync(WORD UartNo)
{
WORD nbytes;
time_t CurTime;
BYTE sync,i;
struct ModS *Modp;
Modp=&Mod;
mytime(&CurTime);
//printf("findmodsysnc is running\n");
for (i=0;i<30;i++)
{
nbytes=RecvUart(UartNo,&sync,1);
if (nbytes==0)
ReadNoByteFromModBus(UartNo);
else
{
#ifdef DEBUG_MODBUS
printf("mod:s=%02x ",sync);
#endif
Modp->LastRecvDataTime=CurTime;
Modp->RecvData=ON;
Modp->SearchSyncNum++;
if(sync==Modp->SynCode[Modp->RecvSyncNum]&&Modp->RecvSyncNum<Modp->SynBytes)
Modp->RecvSyncNum++;
else
{
if(Modp->RecvSyncNum==Modp->SynBytes)
{
HaveFoundModSync();
Modp->FromBuff[Modp->SynBytes+0]=sync;
#ifdef DEBUG_MODBUS
printf("ModBus Find...........sync\n");
#endif
break; /*exit for loop*/
}
else
SearchModSyncFault();
}
}
}
}
/***********************************************************************/
/* FunName: HaveFoundmodSync
/* InPut : void
/* Output : void
/* Function : Clear states used for sync after sync is full
/* By : zhanghong
/* Time : 2006-11-25
/***********************************************************************/
void HaveFoundModSync(void)
{
int i;
struct ModS *Modp;
Modp=&Mod;
Modp->RecvSyncNum=0;
Modp->SearchSyncNum=0;
Modp->SyncFull=ON;
for(i=0;i<Modp->SynBytes;i++)
Modp->FromBuff[i]=Modp->SynCode[i];
Modp->RecvByteNum=Modp->SynBytes+1;
}
/***********************************************************************/
/* FunName: ReadModHead
/* InPut : UartNo
/* Output : void
/* Function : read head package from the uart used for modbus
/* By : zhanghong
/* Time : 2006-12-5
/***********************************************************************/
void ReadModHead(WORD UartNo)
{
WORD nbytes,i,HeadBytes;
BYTE *p;
struct ModS *Modp;
Modp=&Mod;
HeadBytes=Modp->HeadBytes;
if(Modp->RecvByteNum>=HeadBytes)
{
Modp->HeadFull=ON;//may HeadBytes is 0
return;
}
nbytes=HeadBytes-(Modp->RecvByteNum-Modp->SynBytes);
p=&Modp->FromBuff[Modp->RecvByteNum];
nbytes=uintmin(nbytes,sizeof(Modp->FromBuff)-Modp->RecvByteNum);
nbytes=RecvUart(UartNo,p,nbytes);
#ifdef DEBUG_MODBUS
{
printf("Mod:h=");
for(i=0;i<nbytes;i++)
printf("%02x",p[i]);
printf("\n");
}
#endif
if (nbytes==0)
ReadNoByteFromModBus(UartNo);
else
{
Modp->RecvData=ON;
mytime(&Modp->LastRecvDataTime);
Modp->RecvByteNum+=nbytes;
}
if(Modp->RecvByteNum>=HeadBytes)
{
Modp->HeadFull=ON;
Modp->Cmd=Modp->FromBuff[Modp->SynBytes];
switch(Modp->Cmd)
{
case READ_OUTPUT_STATUS:
case READ_INPUT_STATUS:
case READ_OUTPUT_REGISTERS:
case READ_INPUT_REGISTERS:
case FORCE_SINGLE_COIL:
case PRESET_SINGLE_REGISTER:
Modp->PktBytes=Modp->SynBytes+Modp->HeadBytes+2;
break;
case FORCE_MULTIPLE_COILS:
Modp->RcvDataBytes=((Modp->FromBuff[Modp->SynBytes+3]<<8|Modp->FromBuff[Modp->SynBytes+4])+7)/8;
Modp->PktBytes=Modp->SynBytes+Modp->HeadBytes+1+Modp->RcvDataBytes+2;
break;
case PRESET_MULTIPLE_REGISTERS:
Modp->RcvDataBytes=((Modp->FromBuff[Modp->SynBytes+3]<<8|Modp->FromBuff[Modp->SynBytes+4]))*2;
Modp->PktBytes=Modp->SynBytes+Modp->HeadBytes+1+Modp->RcvDataBytes+2;
break;
default: break;
}
}
#ifdef DEBUG_MODBUS
printf("Modp->HeadFull==ON,Modp->Cmd:%02x,Modp->RcvDataBytes:%02i,Modp->PktBytes:%02i\n",Modp->Cmd,Modp->RcvDataBytes,Modp->PktBytes);
#endif
}
/***********************************************************************/
/* FunName: SearchModSyncFault
/* InPut : void
/* Output : void
/* Function : Clear states used for sync after having faulted in
/* receiving syn
/* By : zhanghong
/* Time : 2006-11-25
/***********************************************************************/
void SearchModSyncFault(void)
{
struct ModS *Modp;
Modp=&Mod;
if(Modp->SearchSyncNum>LIMIT_SEARCH_SYN_NUM)
{
ModiModStat(FAULT);
Modp->SearchSyncNum=0;
Modp->RecvSyncNum=0;
}
}
/***********************************************************************/
/* FunName: ModiModStat
/* InPut : Stat
/* Output : void
/* Function : Modify the state of modBus
/* By : zhanghong
/* Time : 2006-11-25
/***********************************************************************/
void ModiModStat(BYTE Stat)
{
Lib.ModBusStat=Stat;
}
/***********************************************************************/
/* FunName: ReadModData
/* InPut : UartNo
/* Output : void
/* Function : Modify the state of modBus
/* By : zhanghong
/* Time : 2006-11-25
/***********************************************************************/
void ReadModData(WORD UartNo)
{
WORD nbytes,i;
BYTE *p;
struct ModS *Modp;
Modp=&Mod;
nbytes=Modp->PktBytes-Modp->RecvByteNum;
if (nbytes>sizeof(Modp->FromBuff))
{
ClearModBuff(UartNo);
return;
}
p=&Modp->FromBuff[Modp->RecvByteNum];
nbytes=RecvUart(UartNo,p,nbytes);
if (nbytes==0)
ReadNoByteFromModBus(UartNo);
else
{
#ifdef DEBUG_MODBUS
{
printf("Mod:d=");
for(i=0;i<nbytes;i++)
printf("%02x",p[i]);
printf("\n");
}
#endif
Modp->RecvByteNum+=nbytes;
Modp->RecvData=ON;
mytime(&Modp->LastRecvDataTime);
if(Modp->RecvByteNum==Modp->PktBytes)
Modp->DataFull=ON;
}
#ifdef DEBUG_MODBUS
if(Modp->DataFull==ON)printf("mod:data full\n");
#endif
}
/***********************************************************************/
/* FunName: CheckModPkt
/* InPut : UartNo
/* Output : CheckRight
/* Function : Check crc of the received data
/* By : zhanghong
/* Time : 2006-11-27
/***********************************************************************/
WORD CheckModPkt(WORD UartNo)
{
WORD CheckSum,CheckRight,nbytes,i,UpUnitNo,Addr;
WORD Crc16;
struct ModS *Modp;
Modp=&Mod;
Addr=Modp->FromBuff[0];
//UpUnitNo=0;
//Modp->UpUnitNo=UpUnitNo;
#ifdef DEBUG_MODBUS
printf("~~~~~~~~~~check:");
#endif
nbytes=Modp->PktBytes;
CheckSum=CalModBusCrc16(&Modp->FromBuff[0],nbytes-2);
Crc16=WordSwap((BYTE *)&CheckSum); //in pkt,crc_high byte,crc_low byte
if(Crc16!=*(WORD *)&Modp->FromBuff[nbytes-2])
{
CheckRight=OFF;
Modp->ErrTimes++;
if(Modp->ErrTimes>LIMIT_MOD_ERR_TIMES)
Lib.ModBusStat=FAULT;
Modp->ErrTimes=0;
}
else
CheckRight=ON;
#ifdef DEBUG_MODBUS
printf("check end,CheckRight=%d,crc is %04x\n",CheckRight,Crc16);
#endif
return(CheckRight);
}
/***********************************************************************/
/* FunName: FromModProc
/* InPut : UartNo
/* Output : Processed
/* Function : Process the data has been received
/* By : zhanghong
/* Time : 2006-11-25
/***********************************************************************/
WORD FromModProc(WORD UartNo)
{
WORD bytes,totalbytes,RegAddr,RegCount,count,Processed=OFF;
BYTE yxstate;
struct ModS *Modp;
Modp=&Mod;
Lib.ModBusStat=NORMAL;
Lib.ModBusCmd=Modp->Cmd;
RegAddr=Modp->FromBuff[Modp->SynBytes+1]<<8|Modp->FromBuff[Modp->SynBytes+2];
#ifdef DEBUG_MODBUS
printf("Modp->RegAddr:0x%04x\n",RegAddr);
#endif
switch(Modp->Cmd)
{
case READ_OUTPUT_STATUS:
case READ_INPUT_STATUS:
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.TotalYxNum)
bytes=OrgModBusYx(RegAddr,0);
else if(RegAddr+RegCount>Lib.TotalYxNum)
{
#ifdef DEBUG_MODBUS
printf("waring:RegAddr+RegCount>Lib.TotalYxNum!\n");
#endif
count=Lib.TotalYxNum-RegAddr;
bytes=OrgModBusYx(RegAddr,count);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -