Skip to content

STM32 drives w5500 to port FreeModbus to implement ModbusTCP

STM32 drives w5500 to port FreeModbus to implement ModbusTCP

praveen_k

Published February 08, 2022

54 UCC

13 VAR

Components

Hardware components

x 1


WIZnet parts

Project description

First, we download the FreeModbus source code, then put it in our own project, create a new MODBUS_TCP and PORT_TCP folder, and then copy the relevant files into it, as shown in the following figure: insert image description hereThen modify the code in porttcp: first define an array to receive data :
static UCHAR    aucTCPBuf[MB_TCP_BUF_SIZE];	   //接收???
Then initialize the socket connection in xMBTCPPortInit, and then listen to the port.
BOOL
xMBTCPPortInit( USHORT usTCPPort )
{
    
    BOOL bOkay = FALSE;
     
    // ??端口 Modbus-TCP 端口
	socket_init(SOCK_TCP_PORT,Sn_MR_TCP_TCP,local_tcp_port++,Sn_MR_ND_TCP);
	listen_tcp_socket(SOCK_TCP_PORT);
    
    bOkay = TRUE;
    return bOkay;
}
Then send the data in the xMBTCPPortSendResponse function
BOOL
xMBTCPPortSendResponse(const UCHAR * pucMBTCPFrame, USHORT usTCPLength )
{
    
	send_tcp_socket_data(SOCK_TCP_PORT,(UCHAR*)pucMBTCPFrame,usTCPLength);	
    return TRUE;
}
Then perform receive and other operations at xMBPortTCPPool
BOOL
xMBPortTCPPool( void )
{
      
	unsigned short int us_rlen;
	unsigned char i;
	i=get_tcp_socket_state(SOCK_TCP_PORT);

	if(i==SOCK_ESTABLISHED_TCP)
	{
    
		if(get_tcp_socket_irq(SOCK_TCP_PORT) & Sn_IR_CON_TCP)		//?看中?有?有?生
		{
    
			clear_tcp_socket_irq(SOCK_TCP_PORT, Sn_IR_CON_TCP); 	/*?除接收中??志位*/						         
		}
		us_rlen=get_tcp_rx_buffer_size(SOCK_TCP_PORT); 				//?取接收到的?据字?				  	         /*定?len?已接收?据的?度*/
		if(us_rlen==0)												//?有接收到?据
			return FALSE;											//返回
		else
		{
    
			recv_tcp_socket_data(SOCK_TCP_PORT,aucTCPBuf,us_rlen); 	//接收?据						   		         /*接收?自Server的?据*/
			printf("receivern");
			usTCPBufLen=us_rlen;
		}
		( void )xMBPortEventPost( EV_FRAME_RECEIVED );			//?送已接收到新?据到Modbus-TCP??机
	}
	else if(i==SOCK_CLOSED_TCP)									//如果socket??
	{
    
		socket_init(SOCK_TCP_PORT,Sn_MR_TCP_TCP,local_tcp_port++,Sn_MR_ND_TCP);//重新初始化
	}
	else if(i==SOCK_INIT_TCP)								//如果socket初始化完?,??端口
	{
    
		listen_tcp_socket(SOCK_TCP_PORT);
	}
	else if(i==SOCK_CLOSE_WAIT_TCP)							//如果socket等待??,??socket?接
	{
    
		close_tcp_socket(SOCK_TCP_PORT);
	}

	return TRUE;
}
Secondly, the functions of reading coil, writing coil, reading discrete input, writing holding register, reading holding register, and reading input register should be realized, as follows:
#define REG_INPUT_START       0x0001	//?入寄存器起始地址
#define REG_INPUT_NREGS       8			//?入寄存器?量

#define REG_HOLDING_START     0x0001	//保持寄存器起始地址
#define REG_HOLDING_NREGS     8			//保持寄存器?量

#define REG_COILS_START       0x0001	//?圈起始地址
#define REG_COILS_SIZE        16			//?圈?量

#define REG_DISCRETE_START    0x0001	//??寄存器其?地址
#define REG_DISCRETE_SIZE     16			//??寄存器?量
//?入寄存器?容
uint16_t usRegInputBuf[REG_INPUT_NREGS] = {
    0x1000,0x1001,0x1002,0x1003,0x1004,0x1005,0x1006,0x1007};
//保持寄存器?容		
uint16_t usRegHoldingBuf[REG_HOLDING_NREGS] = {
    0x2000,0x2001,0x2002,0x2003,0x2004,0x2005,0x2006,0x2007};					
//?圈??
uint8_t ucRegCoilsBuf[REG_COILS_SIZE] = {
    0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00};
//?散寄存器?容
uint8_t ucRegDiscreteBuf[REG_DISCRETE_SIZE] = {
    0x01,0x01,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x01}; 

/****************************************************************************
* 名	  ?:eMBRegInputCB 
* 功    能:?取?入寄存器,??功能?是 04 eMBFuncReadInputRegister
* 入口??:pucRegBuffer: ?据?存?,用于??主机   
*						usAddress: 寄存器地址
*						usNRegs: 要?取的寄存器??
* 出口??:
* 注	  意:上位机??的 ?格式是: SlaveAddr(1 Byte)+FuncCode(1 Byte)
*								+StartAddrHiByte(1 Byte)+StartAddrLoByte(1 Byte)
*								+LenAddrHiByte(1 Byte)+LenAddrLoByte(1 Byte)+
*								+CRCAddrHiByte(1 Byte)+CRCAddrLoByte(1 Byte)
*							3 ?
****************************************************************************/
eMBErrorCode
eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{
    
    eMBErrorCode    eStatus = MB_ENOERR;
    int             iRegIndex;

    if( ( usAddress >= REG_INPUT_START )
        && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
    {
    
        iRegIndex = ( int )( usAddress - REG_INPUT_START );
        while( usNRegs > 0 )
        {
    
            *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] >> 8 );
            *pucRegBuffer++ = ( UCHAR )( usRegInputBuf[iRegIndex] & 0xFF );
            iRegIndex++;
            usNRegs--;
        }
    }
    else
    {
    
        eStatus = MB_ENOREG;
    }

    return eStatus;
}

/****************************************************************************
* 名	  ?:eMBRegHoldingCB 
* 功    能:??功能?有:06 ?保持寄存器 eMBFuncWriteHoldingRegister 
*													16 ?多?保持寄存器 eMBFuncWriteMultipleHoldingRegister
*													03 ?保持寄存器 eMBFuncReadHoldingRegister
*													23 ??多?保持寄存器 eMBFuncReadWriteMultipleHoldingRegister
* 入口??:pucRegBuffer: ?据?存?,用于??主机   
*						usAddress: 寄存器地址
*						usNRegs: 要??的寄存器??
*						eMode: 功能?
* 出口??:
* 注	  意:4 ?
****************************************************************************/
eMBErrorCode
eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
{
    
	eMBErrorCode    eStatus = MB_ENOERR;
	int             iRegIndex;


	if((usAddress >= REG_HOLDING_START)&&
		((usAddress+usNRegs) <= (REG_HOLDING_START + REG_HOLDING_NREGS)))
	{
    
		iRegIndex = (int)(usAddress - REG_HOLDING_START);
		switch(eMode)
		{
                                           
			case MB_REG_READ://? MB_REG_READ = 0
				while(usNRegs > 0)
				{
    
					*pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] >> 8);            
					*pucRegBuffer++ = (u8)(usRegHoldingBuf[iRegIndex] & 0xFF); 
					iRegIndex++;
					usNRegs--;					
				}                            
			break;
			case MB_REG_WRITE://? MB_REG_WRITE = 0
				while(usNRegs > 0)
				{
             
					usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
					usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
					iRegIndex++;
					usNRegs--;
				}
			break;				
		}
	}
	else//??
	{
    
		eStatus = MB_ENOREG;
	}	
	
	return eStatus;
}

/****************************************************************************
* 名	  ?:eMBRegCoilsCB 
* 功    能:??功能?有:01 ??圈 eMBFuncReadCoils
*						  05 ??圈 eMBFuncWriteCoil
*						  15 ?多??圈 eMBFuncWriteMultipleCoils
* 入口??:pucRegBuffer: ?据?存?,用于??主机   
*						usAddress: ?圈地址
*						usNCoils: 要??的?圈??
*						eMode: 功能?
* 出口??:
* 注	  意:如??器 
*						0 ?
****************************************************************************/
eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
{
    
	eMBErrorCode    eStatus = MB_ENOERR;
	int             iRegIndex;
	u8 i;
	USHORT readNumber=usNCoils;
	USHORT coilValue=0x0000;
	if((usAddress >= REG_COILS_START)&&
	((usAddress+usNCoils) <= (REG_COILS_START + REG_COILS_SIZE)))
	{
    
		iRegIndex = (int)(usAddress + usNCoils-REG_COILS_START);
		switch(eMode)
		{
                                           
			case MB_REG_READ://? MB_REG_READ = 0
				for(i=0;i<usNCoils;i++)
				{
    
					readNumber--;
					iRegIndex--;
					coilValue|=ucRegCoilsBuf[iRegIndex]<<readNumber;
				}
				if(usNCoils<=8)
				{
    
					* pucRegBuffer=coilValue;
				}
				else
				{
    
					* pucRegBuffer++ = (coilValue)&0x00ff;
					* pucRegBuffer++ = (coilValue>>8)&0x00ff;
				}
			break;                            
			case MB_REG_WRITE://? MB_REG_WRITE = 1
				while(usNCoils > 0)
				{
             
					// 			usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
					//           usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
						iRegIndex++;
						usNCoils--;
				}
			break;
		}
	}
	else//??
	{
    
		eStatus = MB_ENOREG;
	}	

	return eStatus;
}
/****************************************************************************
* 名	  ?:eMBRegDiscreteCB 
* 功    能:?取?散寄存器,??功能?有:02 ??散寄存器 eMBFuncReadDiscreteInputs
* 入口??:pucRegBuffer: ?据?存?,用于??主机   
*						usAddress: 寄存器地址
*						usNDiscrete: 要?取的寄存器??
* 出口??:
* 注	  意:1 ?
****************************************************************************/
eMBErrorCode
eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
{
    
	eMBErrorCode    eStatus = MB_ENOERR;
	int             iRegIndex;
	u8 i;
	USHORT readNumber=usNDiscrete;
	USHORT coilValue=0x0000;
	iRegIndex = (int)(usAddress + usNDiscrete-REG_DISCRETE_START);
	if((usAddress >= REG_DISCRETE_START)&&
	((usAddress+usNDiscrete) <= (REG_DISCRETE_START + REG_DISCRETE_SIZE)))
	{
    
		for(i=0;i<usNDiscrete;i++)
		{
    
			readNumber--;
			iRegIndex--;
			coilValue|=ucRegDiscreteBuf[iRegIndex]<<readNumber;
		}
		if(usNDiscrete<=8)
		{
    
			* pucRegBuffer=coilValue;
		}
		else
		{
    
			* pucRegBuffer++ = (coilValue)&0x00ff;
			* pucRegBuffer++ = (coilValue>>8)&0x00ff;
		}
	}
	else
	{
    
		eStatus = MB_ENOREG;
	}
    return eStatus;
}


Complete code download?STM32 driver w5500 transplanting FreeModbus to realize ModbusTCP complete code download
Copyright statement: This article is an original article by the blogger and follows the?CC 4.0 BY-SA?copyright agreement. Please attach the original source link and this statement for reprinting.

Documents

  • STM32 driver w5500 transplanting FreeModbus to realize ModbusTCP complete code download

Comments

Similar projects you might like

Comments