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

📄 ex3modbus.c

📁 一个基于三星s3c44b0x的串口协议转换器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
				}
			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 + -