STM32 + CubeMX + 硬件SPI + W5500 +TcpClient

  这篇文章记录一下STM32+W5500+TCP_Client的调试过程,实现TCP客户端数据的接收与发送。

目录

  • 一、W5500模块介绍
  • 二、Stm32CubeMx配置
  • 三、Keil代码编写
  • 1、添加W5500驱动代码到工程(添加方法不赘述,驱动代码可以在官网找)
  • 2、在工程中增加代码
  • (1)MyTcpClient.h
  • (2)MyTcpClient.c
  • 3、修改CubeMx已生成的代码
  • (1)main.c
  • 四、硬件连接
  • 五、运行效果
  • 一、W5500模块介绍

    建议看这位博主的文章,很详细:
    https://blog.csdn.net/lin_strong/article/details/82222068

    二、Stm32CubeMx配置

    1、RCC开启外部高速时钟(略)
    2、配置STLink调试口(略)
    3、配置串口方便调试输出(略)
    4、配置工程名、生成路径,之后生成工程(略)
    (1-4步的基础配置可以参考前面的文章《STM32基础工程模板创建》)
    5、SPI 配置,配置PA4为CS片选引脚

    6、配置PB4为W5500的RST引脚,PB5为INT引脚

    三、Keil代码编写

    1、添加W5500驱动代码到工程(添加方法不赘述,驱动代码可以在官网找)

    2、在工程中增加代码

    (1)MyTcpClient.h

    #ifndef MYTCPCLIENT_H
    #define MYTCPCLIENT_H
    #include "main.h"
    #include "w5500.h"
    #include "socket.h"
    #include "wizchip_conf.h"
    #include "spi.h"
    #include <string.h>  // memcmp
    #define SOCK_TCPS  0
    extern  uint8_t buff[128];   //定义缓冲区   
    extern uint8_t TCP_send_buff[128];   //定义UDP发送缓冲区                                            
    extern uint8_t remote_ip[4]; //远程IP地址
    extern uint16_t remote_port; //远程端口号
    
    void TcpClientInit(void);
    void do_tcp_client(void);
    void Analysis(uint8_t *buf);
    #endif // MYTCPCLIENT_H
    
    
    

    (2)MyTcpClient.c

    #include "MyTcpClient.h"
    #include "main.h"
    #include "w5500.h"
    #include "socket.h"
    #include "wizchip_conf.h"
    #include "spi.h"
    #include <string.h>  // memcmp
    
    uint8_t buff[128];  
    uint8_t TCP_send_buff[128]; 
                                                        
    uint8_t remote_ip[4] = {192, 168, 1, 2}; //远程IP地址
    uint16_t remote_port = 5002; //远程端口号
    
    //片选
    void W5500_Select(void) {
        HAL_GPIO_WritePin(W5500_CS_GPIO_Port, W5500_CS_Pin, GPIO_PIN_RESET);
    }
    void W5500_Unselect(void) {
        HAL_GPIO_WritePin(W5500_CS_GPIO_Port, W5500_CS_Pin, GPIO_PIN_SET);
    }
    void W5500_Restart(void) {
        HAL_GPIO_WritePin(W5500_RST_GPIO_Port, W5500_RST_Pin, GPIO_PIN_RESET);
        HAL_Delay(1);  // delay 1ms
        HAL_GPIO_WritePin(W5500_RST_GPIO_Port, W5500_RST_Pin, GPIO_PIN_SET);
        HAL_Delay(1600);  // delay 1600ms
    }
    
    void W5500_ReadBuff(uint8_t* buff, uint16_t len) {
        HAL_SPI_Receive(&hspi1, buff, len, HAL_MAX_DELAY);
    }
    
    void W5500_WriteBuff(uint8_t* buff, uint16_t len) {
        HAL_SPI_Transmit(&hspi1, buff, len, HAL_MAX_DELAY);
    }
    
    uint8_t W5500_ReadByte(void) {
        uint8_t byte;
        W5500_ReadBuff(&byte, sizeof(byte));
        return byte;
    }
    
    void W5500_WriteByte(uint8_t byte) {
        W5500_WriteBuff(&byte, sizeof(byte));
    }
    
    //配置W5500网络信息
    wiz_NetInfo gSetNetInfo = {
      .mac  = {0x00, 0x08, 0xdc, 0x11, 0x11, 0x11},
      .ip   = {192, 168, 1, 10},
      .sn   = {255, 255, 255, 0},
      .gw   = {192, 168, 1, 1},
      .dns  = {144, 144, 144, 144},
      .dhcp = NETINFO_STATIC};
    
    wiz_NetInfo gGetNetInfo;
    
    enum Status
    {
      Failed = 0,
      Success = 1
    };
    
    /**
     * @brief valid the result of set net info
     * @return 1: Success
     *         0: Failed
    */
    uint8_t validSetNetInfoResult(wiz_NetInfo* _set, wiz_NetInfo* _get)
    {
      return (!memcmp(_set, _get, sizeof(wiz_NetInfo)));  // if same, memcmp return 0
    }
    
    
    void TcpClientInit(void)
    {
    	reg_wizchip_cris_cbfunc(SPI_CrisEnter, SPI_CrisExit);	//注册临界区函数
      reg_wizchip_cs_cbfunc(W5500_Select, W5500_Unselect);
      reg_wizchip_spi_cbfunc(W5500_ReadByte, W5500_WriteByte);
    
      W5500_Restart();  // hardware restart through RESET pin
    
      ctlnetwork(CN_SET_NETINFO, (void*)&gSetNetInfo);  // set net info
      // maybe need delay
      ctlnetwork(CN_GET_NETINFO, (void*)&gGetNetInfo);  // get net info
    
      // W5500 has 8 channel, 32k buffer, 2 means 2KBytes
      uint8_t buffer_size_8channel_tx_rx[16] = {2, 2, 2, 2, 2, 2, 2, 2,  // 8 channel tx
                                                2, 2, 2, 2, 2, 2, 2, 2}; // 8 channel rx
      if(ctlwizchip(CW_INIT_WIZCHIP,(void*)buffer_size_8channel_tx_rx))
      {
        // failed
        
      }
    
      uint8_t sta = getSn_SR(SOCK_TCPS);
      if(sta == SOCK_CLOSED)
      {
        socket(SOCK_TCPS, Sn_MR_TCP, 5001, 0x00);
      }
      HAL_Delay(100);
    
    }
    
    
    void do_tcp_client(void)
    {
    	uint16_t len=0;
    	switch(getSn_SR(SOCK_TCPS))														// 获取socket0的状态
    	{
    		case SOCK_INIT:															// Socket处于初始化完成(打开)状态	
    				connect(SOCK_TCPS,remote_ip,remote_port);
    		break;
    		case SOCK_ESTABLISHED:											// Socket处于连接建立状态
    				if(getSn_IR(SOCK_TCPS) & Sn_IR_CON)   					
    				{
    					setSn_IR(SOCK_TCPS, Sn_IR_CON);								// Sn_IR的CON位置1,通知W5500连接已建立
    				}
    				// 数据回环测试程序:数据从上位机服务器发给W5500,W5500接收到数据后再回给服务器
    				len=getSn_RX_RSR(SOCK_TCPS);										// len=Socket0接收缓存中已接收和保存的数据大小					
    				if(len)
    				{
    					recv(SOCK_TCPS,buff,len);		
    					send(SOCK_TCPS,buff,len);							
    				}											
    		break;
    		case SOCK_CLOSE_WAIT:												  // Socket处于等待关闭状态
    			disconnect(SOCK_TCPS);	
    		break;
    		case SOCK_CLOSED:														// Socket处于关闭状态
    				socket(SOCK_TCPS,Sn_MR_TCP,5001,0x00);		// 打开Socket0,打开一个本地端口
    		break;
    	}
    }
    
    
    //分析数据
    void Analysis(uint8_t *buf)
    {
    
    }
    
    
    

    3、修改CubeMx已生成的代码

    (1)main.c

    #include <stdio.h>
    #include "MyTcpClient.h"
    
    int main(void)
    {
      HAL_Init();
      SystemClock_Config();
      MX_GPIO_Init();
      MX_USART1_UART_Init();
      MX_SPI1_Init();
      UDPinit();
      while (1)
      {
    	do_tcp_client();
      }
    }
    
    

    四、硬件连接

    STM32开发板 W5500模块
    5V 5V
    GND GND
    PA4 SCS
    PA6 MISO
    PA5 SCK
    PA7 MOSI
    PB4 RST
    PB5 INT

    五、运行效果

    (1)、将W5500和电脑通过网线直连
    (2)、将电脑IP配置为192.168.1.2
    (3)、ping 192.168.1.10(W5500的IP),能ping通。再使用网络调试助手给192.186.1.10的5001端口发送数据,之后网络调试助手能收到返回的数据。

    作者:Lin201230

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32 + CubeMX + 硬件SPI + W5500 +TcpClient

    发表回复