W5500 TCP客户端开发 | 01 - 准备工作以及W5500库socket接口说明

一、硬件介绍

  • W5500 芯片是一款集成全硬件 TCP/IP 协议栈的嵌入式以太网控制器,W5500内嵌的8个独立硬件 Socket 可以进行8路独立通信,该8路Socket的通信效率互不影响,可以通过操作Socket以实现网络的通信。

W5500 最主要的几个引脚对应开发板的SPI引脚

  • MISO:(Master Input Slave Output)主机输入从机输出
  • MOSI:(Master Output Slave Input)主机输出从机输入
  • SCLK:(Serial Clock)时钟信号,由主设备产生
  • SCS: (Chip Select)从设备使能信号,由主设备控制
  • RSTn: 复位引脚
  • INTn:中断引脚

STM32 SPI配置(这里使用的是STM32F103CBT6的SPI1)

	//全双工模式
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; 
	//作为主机使用
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
	//数据位长度为8
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
	//空闲状态下时钟线是low
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
	//CPHA置低数据锁存在第一个时钟边沿
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
	//软件设置NSS功能
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;	
	//设置时钟频率													
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
	//先输出高字节
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
	//CRC校验设置
	SPI_InitStructure.SPI_CRCPolynomial = 7;

	SPI_Init(SPI1, &SPI_InitStructure);
	SPI_Cmd(SPI1, ENABLE);

二、网络环境

本实验是通过交叉线(一端568A,一端568B)将开发板与电脑互连,并用网络助手监测TCP的连接情况。此次例程是需要注意的是要将电脑配置为固定的ip地址。配置过程如下图所示

  • 打开网络连接设置,更改适配器
    在这里插入图片描述

  • 打开属性
    在这里插入图片描述

  • 双击Internet协议版本4
    在这里插入图片描述

  • 更改IP地址为固定地址

打开网络状态调试助手,则直接搜到本地IP地址,创建一个TCP Server。
网络调试助手(点击直接下载)

三、W5500的官方驱动库提供的Socket API

本文只介绍TCP客户端开发中需要用到的代码,代码实现在:socket.c以及socket.h

1. socket

功能:初始化socket并打开对应的socket

参数说明:

  • sn:所需要打开的socket
  • protocol:协议类型
  • port:相应的端口号
  • flag:特殊的socket模式
uint8_t socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag)
{
   uint8_t ret;
   if (
        ((protocol&0x0F) == Sn_MR_TCP)    ||
        ((protocol&0x0F) == Sn_MR_UDP)    ||
        ((protocol&0x0F) == Sn_MR_IPRAW)  ||
        ((protocol&0x0F) == Sn_MR_MACRAW) ||
        ((protocol&0x0F) == Sn_MR_PPPOE)
      )
   {
      close(sn);
      IINCHIP_WRITE(Sn_MR(sn) ,protocol | flag);
      if (port != 0) {
         IINCHIP_WRITE( Sn_PORT0(sn) ,(uint8_t)((port & 0xff00) >> 8));
         IINCHIP_WRITE( Sn_PORT1(sn) ,(uint8_t)(port & 0x00ff));
      } else {
         local_port++; // if don't set the source port, set local_port number.
         IINCHIP_WRITE(Sn_PORT0(sn) ,(uint8_t)((local_port & 0xff00) >> 8));
         IINCHIP_WRITE(Sn_PORT1(sn) ,(uint8_t)(local_port & 0x00ff));
      }
      IINCHIP_WRITE( Sn_CR(sn) ,Sn_CR_OPEN); // run sockinit Sn_CR

      /* wait to process the command... */
      while( IINCHIP_READ(Sn_CR(sn)) )
         ;
      /* ------- */
      ret = 1;
   }
   else
   {
      ret = 0;
   }
   return ret;
}

2. connect

功能: 客户端模式下为通道建立连接服务器。这个函数一直等待,直到连接建立。

参数说明:

  • sn:socket编号
  • addr:目标IP地址(需要连接的服务器IP地址)
  • port:目标端口(服务器端口)
uint8_t connect(uint8_t sn, uint8_t * addr, uint16_t port)
{
    uint8_t ret;
    if							
        (
            ((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
            ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
            (port == 0x00)
        )
    {
      ret = 0;
    }
    else
    {
        ret = 1;
        IINCHIP_WRITE( Sn_DIPR0(sn), addr[0]);
        IINCHIP_WRITE( Sn_DIPR1(sn), addr[1]);
        IINCHIP_WRITE( Sn_DIPR2(sn), addr[2]);
        IINCHIP_WRITE( Sn_DIPR3(sn), addr[3]);
        IINCHIP_WRITE( Sn_DPORT0(sn), (uint8_t)((port & 0xff00) >> 8));
        IINCHIP_WRITE( Sn_DPORT1(sn), (uint8_t)(port & 0x00ff));
        
				IINCHIP_WRITE( Sn_CR(sn) ,Sn_CR_CONNECT);
				
        while ( IINCHIP_READ(Sn_CR(sn) ) ) ;	

        while ( IINCHIP_READ(Sn_SR(sn)) != SOCK_SYNSENT )
        {
            if(IINCHIP_READ(Sn_SR(sn)) == SOCK_ESTABLISHED)
            {
                break;
            }
            if (getSn_IR(sn) & Sn_IR_TIMEOUT)
            {
                IINCHIP_WRITE(Sn_IR(sn), (Sn_IR_TIMEOUT));
                ret = 0;																		
                break;
            }
        }
    }

   return ret;
}

3. send

功能:用于TCP模式发送数据

参数说明:

  • sn:socket编号
  • buf:发送数据缓冲区
  • len:发送数据缓冲区的大小
uint16_t send(uint8_t sn, const uint16_t * buf, uint16_t len)
{
  uint8_t status=0;
  uint16_t ret=0;
  uint16_t freesize=0;

  if (len > getIINCHIP_TxMAX(sn)) 
			ret = getIINCHIP_TxMAX(sn); 
  else ret = len;
  do
  {
    freesize = getSn_TX_FSR(sn);
    status = IINCHIP_READ(Sn_SR(sn));
    if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT))
    {
      ret = 0;
      break;
    }
  } 
	while (freesize < ret);
  send_data_processing(sn, (uint8_t *)buf, ret);			 
  IINCHIP_WRITE( Sn_CR(sn) ,Sn_CR_SEND);

  /* wait to process the command... */
  while( IINCHIP_READ(Sn_CR(sn) ) );

  while ( (IINCHIP_READ(Sn_IR(sn) ) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
  {
    status = IINCHIP_READ(Sn_SR(sn));
    if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT) )
    {
      printf("SEND_OK Problem!!\r\n");
      close(sn);
      return 0;
    }
  }
  IINCHIP_WRITE( Sn_IR(sn) , Sn_IR_SEND_OK);

#ifdef __DEF_IINCHIP_INT__
   putISR(sn, getISR(sn) & (~Sn_IR_SEND_OK));
#else
   IINCHIP_WRITE( Sn_IR(sn) , Sn_IR_SEND_OK);
#endif

   return ret;
}

4. recv

功能:用于TCP模式接收数据

参数说明:

  • sn:socket编号
  • buf:接收数据缓冲区
  • len:接收数据缓冲区的大小
uint16_t recv(uint8_t sn, uint8_t * buf, uint16_t len)
{
   uint16_t ret=0;
   if ( len > 0 )
   {
      recv_data_processing(sn, buf, len);
      IINCHIP_WRITE( Sn_CR(sn) ,Sn_CR_RECV);
      /* wait to process the command... */
      while( IINCHIP_READ(Sn_CR(sn) ));
      /* ------- */
      ret = len;
   }
   return ret;
}

5. close

功能:关闭socket

参数说明:

  • sn:socket编号
void close(uint8_t sn)
{
   IINCHIP_WRITE( Sn_CR(sn) ,Sn_CR_CLOSE);

   /* wait to process the command... */
   while( IINCHIP_READ(Sn_CR(sn) ) )
      ;
   /* ------- */
        /* all clear */
   IINCHIP_WRITE( Sn_IR(sn) , 0xFF);
}
  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
W5500是一种流行的以太网模块,常用于嵌入式系统中实现网络连接功能。而Modbus-TCP是一种基于以太网的通信协议,常用于工业自动化中。 编写W5500以太网模块的测试程序,实现Modbus-TCP协议通信,需要以下步骤: 1. 初始化W5500模块:在程序开始时,需要设置W5500模块的IP地址、子网掩码、默认网关等网络参数,并初始化相关寄存器。 2. 配置Modbus-TCP通信参数:设置Modbus-TCP服务器的IP地址和端口号,可以通过修改W5500模块的寄存器来实现。 3. 建立连接:使用W5500模块提供的Socket API函数,创建一个TCP套接字,并与Modbus-TCP服务器建立连接。 4. 实现Modbus-TCP报文的解析和组装:根据Modbus-TCP协议的规定,解析从服务器接收到的报文,并根据需要组装发送给服务器的报文。 5. 发送和接收数据:使用W5500模块的Socket API函数,向Modbus-TCP服务器发送请求报文,并接收响应报文。需要注意处理错误、超时等异常情况。 6. 关闭连接:通信结束时,需要关闭Socket连接,并释放相关资源。 在编写这个测试程序时,需要对W5500模块和Modbus-TCP协议有一定的了解,了解它们的工作原理和通信规范。同时,还需要使用适当的开发环境和编程语言,根据它们提供的API函数和来实现相应的功能。 总结起来,编写W5500以太网模块测试程序,实现Modbus-TCP通信需要对硬件和协议进行了解,并使用适当的开发工具和编程语言来实现相应的功能。在编写过程中,要确保正确地配置W5500模块和Modbus-TCP通信参数,并正确地处理各种异常情况,以确保可靠的通信。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值