⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ex3modbus.c

📁 一个基于三星s3c44b0x的串口协议转换器源码
💻 C
📖 第 1 页 / 共 2 页
字号:

/***********************************************************************/	
/*			                        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 + -