W5500EVB as Modbus TCPS

Modbus is a communication protocol used for transmitting information between electronic devices. This sample code demonstrates how W5500EVB control on board LED by using Modbus TCPS.




Before burning the bin file into your EVB:

  1. Connect W5500 EVB to the router/NAT that you are using, or any other device that allows you to connect to internet
  2. Manually change the Network configuration:
    • Go to the definition of function set_default() (Should be inside device.c), make sure the subnet mask, local IP address, gateway and DNS are set according to the internet setting you are using with your router/NAT
  3. Rebuild the sample code and burn it into W5500EVB



Code Explanation

int main(void)
{

main

    Systick_Init(72);
    NVIC_Configuration();
    GPIO_Configuration();
    WIZ_SPI_Init();
    USART1_Init();
    at24c16_init();
    Reset_W5500();
    set_default();
    set_network();
    setkeepalive(0);
    printf("TCP Server Port: %d\r\n",local_port);
    printf("W5500 Init Complete!\r\n");
    printf("Start Modbus TCP Server Test!\r\n");
/*********************


These are all the necessary
 initialization


*********************/
/*********************
These are messages shown
in serial window for 
debugging
*********************/
    while(1)
    {
        do_Modbus();
    }
}
/******************

main loop of Modbus

******************/

do_Modbus()

Modbus

void do_Modbus(void)
{
    uint8_t state=0;
    state=getSn_SR(0);
    switch(state)
    {
/********************

Necessary Variables
declared

********************/



Socket Initialized

case SOCK_INIT:  
    listen(0);      
    if(!b_listening_printed)
    {
      b_listening_printed=1;
      printf("Listening on %d.%d.%d.%d:%d\r\n",
        lip[0],lip[1],lip[2],lip[3],
        local_port);
     }       
     break;
/******************



print the local IP 
and port



*******************/



Socket Established

case SOCK_ESTABLISHED:
    if(getSn_IR(0) & Sn_IR_CON)
    {
        uint8_t rip[4];      
        setSn_IR(0, Sn_IR_CON);				 
        printf("Connected\r\n");
        rip[0]=IINCHIP_READ( Sn_DIPR0(0));
        rip[1]=IINCHIP_READ( Sn_DIPR1(0));
        rip[2]=IINCHIP_READ( Sn_DIPR2(0));
        rip[3]=IINCHIP_READ( Sn_DIPR3(0));
        printf("RemoteIP:%d.%d.%d.%d Port:%d\r\n",
          rip[0],rip[1],rip[2],rip[3],
          IINCHIP_READ( Sn_DPORT0(0))*256+
          IINCHIP_READ(Sn_DPORT1(0)));
        if(b_listening_printed) 
            b_listening_printed=0;
    }		
    if(getSn_RX_RSR(0))
    {
        mbTCPtoEVB();
    }
    break;
/*************





Read Peer IP
and port
register address 








get socket RX recv
buf size

show below

**************/



Socket Close and Socket Wait

      case SOCK_CLOSE_WAIT:
        disconnect(0);
        break;
      case SOCK_CLOSED:
      case SOCK_FIN_WAIT:
        close(0);	  
        socket(0, Sn_MR_TCP,local_port, Sn_MR_ND);
        break;
      default:
        break;         
  }
}



mbTCPtoEVB
void mbTCPtoEVB(void)
{
  if(MBtcp2evbFrame() != FALSE){
    if((uint8)pucASCIIBufferCur[3]==0x00){
      if((uint8)pucASCIIBufferCur[4]==0xff){
        GPIO_ResetBits(GPIOA, GPIO_Pin_0);
        printf("LED 0 ON\r\n");
      }
      else if((uint8)pucASCIIBufferCur[4]==0x00){
        GPIO_SetBits(GPIOA, GPIO_Pin_0);
      }
    }
    else if(pucASCIIBufferCur[3]==0x01){
      if((uint8)pucASCIIBufferCur[4]==0xff){
        GPIO_ResetBits(GPIOA, GPIO_Pin_1);
        printf("LED 1 ON\r\n");
      }
      else if((uint8)pucASCIIBufferCur[4]==0x00){
        GPIO_SetBits(GPIOA, GPIO_Pin_1);
      }
    }
    else if(pucASCIIBufferCur[3]==0x02){
      if((uint8)pucASCIIBufferCur[4]==0xff){
        GPIO_ResetBits(GPIOA, GPIO_Pin_2);
        printf("LED 2 ON\r\n");
      }
      else if((uint8)pucASCIIBufferCur[4]==0x00){
        GPIO_SetBits(GPIOA, GPIO_Pin_2);
      }
    }
    else if(pucASCIIBufferCur[3]==0x03){
      if((uint8)pucASCIIBufferCur[4]==0xff){
        GPIO_ResetBits(GPIOA, GPIO_Pin_3);
        printf("LED 3 ON\r\n");
      }
      else if((uint8)pucASCIIBufferCur[4]==0x00){
        GPIO_SetBits(GPIOA, GPIO_Pin_3);
      }
    }
  }
}
/***************

LED0 PA0
On / Off








LED1 PA1
On / Off







LED2 PA2
On / Off







LED3 PA3
On / Off









***************/



mbTCPPackage
static bool mbTCPPackage( uint8* pucRcvAddress, uint8** ppucFrame, uint16 * pusLength )
{
  uint8  *pucMBTCPFrame;
  uint16  usLength;
  uint16  usPID;
  if( mbTCPGet( &pucMBTCPFrame, &usLength ) != FALSE )
  {
    usPID = pucMBTCPFrame[MB_TCP_PID] << 8U;    
    usPID |= pucMBTCPFrame[MB_TCP_PID + 1];
    if( usPID == MB_TCP_PROTOCOL_ID )
    {
      *pucRcvAddress = pucMBTCPFrame[MB_TCP_UID];
      mbTCPtid1 = pucMBTCPFrame[MB_TCP_TID1];
      mbTCPtid2 = pucMBTCPFrame[MB_TCP_TID2];
      *ppucFrame = &pucMBTCPFrame[MB_TCP_FUNC];
      *pusLength = usLength - MB_TCP_FUNC;
      return TRUE;
    }
  }
  return FALSE;
}

/******************



check the length of 
data stream

check Protocol 
Identifier

check Transaction
Identifier










********************/



Test process

To test Modbus TCPS, we need to download Modbus poll.

Configuration

Select Connection-Connect… Or Press F3

  • Connection: Modbus TCP/IP
  • IP address or Node name: we may check it in serial port window or in device.c file.
  • Server port: 5000 (default)

Select function-05:Write Single Coil or Press Alt +F5

AddressLED
0PA0
1PA1
2PA2
3PA3



Remarks

  1. In this sample code, Modbus TCP is implemented. We may modify the source code (the function of mbTCPPackage) to change into Modbus RTU or Modbus ASCII.