---
title: "STM32 drives w5500 to port FreeModbus to implement ModbusTCP"
url: "https://maker.wiznet.io/praveen_k/projects/STM32-drives-w5500-to-port-FreeModbus-to-implement-ModbusTCP/"
markdown_url: "https://maker.wiznet.io/praveen_k/projects/STM32-drives-w5500-to-port-FreeModbus-to-implement-ModbusTCP/md"
type: "UCC: User Created Content"
author: "praveen_k"
original_author: "praveen_k"
original_url: "https://cxymm.net/article/qq_15181569/105042842"
published: "2022-02-08"
language: "en"
hardware: ["WIZnet W5500", "STM32"]
likes: 0
views: 427
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# STM32 drives w5500 to port FreeModbus to implement ModbusTCP

> STM32 drives w5500 to port FreeModbus to implement ModbusTCP

Original author: praveen_k (source: https://cxymm.net/article/qq_15181569/105042842)

## Components

- **WIZnet W5500** x 1 ([docs](https://docs.wiznet.io/Product/Chip/Ethernet/W5500))
- **STM32** x 1

WIZnet parts: W5500 ([Datasheet](https://docs.wiznet.io/Product/Chip/Ethernet/W5500/datasheet?utm_source=maker&utm_medium=project&utm_campaign=w5500), [product hub](https://maker.wiznet.io/products/w5500/))

## Documents and links

- [STM32 driver w5500 transplanting FreeModbus to realize ModbusTCP complete code download](https://download.csdn.net/download/qq_15181569/12264015) (code)

## Article

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 here](https://img-blog.csdnimg.cn/20200323102539294.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE1MTgxNTY5,size_16,color_FFFFFF,t_70#pic_center)Then modify the code in porttcp: first define an array to receive data :

```java
static UCHAR    aucTCPBuf[MB_TCP_BUF_SIZE];	   //接收???
```

Then initialize the socket connection in xMBTCPPortInit, and then listen to the port.

```java
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

```java
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

```java
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:

```c
#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](https://download.csdn.net/download/qq_15181569/12264015)

Copyright statement: This article is an original article by the blogger and follows the?[CC 4.0 BY-SA](https://creativecommons.org/licenses/by-sa/4.0/)?copyright agreement. Please attach the original source link and this statement for reprinting.

---

Source: https://maker.wiznet.io/praveen_k/projects/STM32-drives-w5500-to-port-FreeModbus-to-implement-ModbusTCP/
