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:
- Connect W5500 EVB to the router/NAT that you are using, or any other device that allows you to connect to internet
- 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
- 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
Address | LED |
0 | PA0 |
1 | PA1 |
2 | PA2 |
3 | PA3 |
Remarks
- 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.