GD32F103芯片驱动W5500芯片进行以太网通信

[复制链接]
1441|5
 楼主| 2228398717 发表于 2022-8-28 20:18 | 显示全部楼层 |阅读模式
本帖最后由 2228398717 于 2022-8-28 20:50 编辑

一、测试平台:凌跃智能奋斗者开发板
14.jpg 13.jpg 12.jpg 二、测试芯片:
GD32F103ZET6
三、测试目的:
以太网通信,利用GD芯片驱动W5500芯片与电脑主机进行网络通信
四、测试方法:
使用网线将开发板和电脑主机网口直连到一起,或者通过路由器连接到一起,电脑的IP地址修改成为固定的IP:192.168.239.112,默认网关修改成为:192.168.239.1,开发板的IP地址修改为192.168.239.88,开发板下载程序并复位,在电脑dos窗口ping  192.168.239.88,可以正常ping通,同时串口助手可以相关的配置信息。
五、程序说明
一、系统时钟配置
1、在本例程中,将系统时钟设置为72Mhz
  1. //#define __SYSTEM_CLOCK_HXTAL                    (uint32_t)(__HXTAL)
  2. //#define __SYSTEM_CLOCK_24M_PLL_HXTAL            (uint32_t)(24000000)
  3. //#define __SYSTEM_CLOCK_36M_PLL_HXTAL            (uint32_t)(36000000)
  4. //#define __SYSTEM_CLOCK_48M_PLL_HXTAL            (uint32_t)(48000000)
  5. //#define __SYSTEM_CLOCK_56M_PLL_HXTAL            (uint32_t)(56000000)
  6. #define __SYSTEM_CLOCK_72M_PLL_HXTAL            (uint32_t)(72000000)
  7. //#define __SYSTEM_CLOCK_96M_PLL_HXTAL            (uint32_t)(96000000)
  8. //#define __SYSTEM_CLOCK_108M_PLL_HXTAL           (uint32_t)(108000000)
2、配置串口,监控网络配置信息,只写了比较重要的核心部分,还有一些代码根据自己需要写
  1. void USART0_Config(void)
  2. {
  3.     rcu_periph_clock_enable(RCU_GPIOA);    // 使能GPIO时钟

  4.     rcu_periph_clock_enable(RCU_USART0);   // 使能串口时钟
  5.         
  6.           gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);  // 发送引脚初始化 TX

  7.     gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);  // 接收引脚初始化  RX

  8.     usart_deinit(USART0);    // 串口复位
  9.     usart_word_length_set(USART0, USART_WL_8BIT);  // 字长
  10.     usart_stop_bit_set(USART0, USART_STB_1BIT);    // 停止位
  11.     usart_parity_config(USART0, USART_PM_NONE);
  12.     usart_baudrate_set(USART0, 115200U);     // 波特率
  13.     usart_receive_config(USART0, USART_RECEIVE_ENABLE);     // 接收使能
  14.           usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);   // 发送使能
  15.           usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE);
  16.     usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE);
  17.     usart_enable(USART0);           // 串口使能
  18. }
3、初始化IIC协议,用于驱动EEPROM,存储数据,IIC协议内容比较多,这里接不一一列举了。
  1. /************************************************************
  2. * 函数:       i2c_CfgGpio(void)
  3. * 说明:       引脚初始化
  4. * 输入:       无
  5. * 输出:       无
  6. * 返回值:     无
  7. * 作者        凌智君
  8. * 其他:       无
  9. ************************************************************/
  10. void i2c_CfgGpio(void)
  11. {                                             
  12.          rcu_periph_clock_enable(RCC_I2C_PORT);   // 初始化 GPIOB 时钟
  13.          gpio_init(GPIO_PORT_I2C, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, I2C_SCL_PIN | I2C_SDA_PIN); // 初始化 PB6 PB7 为输出模式
  14.          /* 给一个停止信号, 复位I2C总线上的所有设备到待机模式 */
  15.          i2c_Stop();
  16. }
4、初始化驱动W5500的芯片引脚,同样只写核心部分。
  1. void gpio_for_w5500_config(void)
  2. {
  3.                 spi_parameter_struct spi_init_struct;
  4.         
  5.           rcu_periph_clock_enable(WIZ_SPIx_RESET_CLK);   // 使能时钟
  6.         
  7.           rcu_periph_clock_enable(WIZ_SPIx_INT_CLK);   // 使能时钟
  8.         
  9.           rcu_periph_clock_enable(WIZ_SPIx_GPIO_CLK);
  10.         
  11.           rcu_periph_clock_enable(WIZ_SPIx_SCS_CLK);
  12.         
  13.     rcu_periph_clock_enable(RCU_SPI1);    // 初始化SPI1时钟  
  14.         
  15.          /*!< Configure SPI_FLASH_SPI pins: SCK */
  16.           gpio_init(WIZ_SPIx_GPIO_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, WIZ_SPIx_SCLK);
  17.          /*!< Configure SPI_FLASH_SPI pins: MISO */
  18.           gpio_init(WIZ_SPIx_GPIO_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, WIZ_SPIx_MISO);
  19.          /*!< Configure SPI_FLASH_SPI pins: MOSI */
  20.           gpio_init(WIZ_SPIx_GPIO_PORT, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, WIZ_SPIx_MOSI);
  21.         
  22.          /*!< Configure SPI_FLASH_SPI_CS_PIN pin: SPI_FLASH Card CS pin */
  23.           gpio_init(WIZ_SPIx_SCS_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, WIZ_SPIx_SCS);
  24.         
  25.          /* SPI configuration */
  26.           spi_init_struct.trans_mode           = SPI_TRANSMODE_FULLDUPLEX;
  27.     spi_init_struct.device_mode          = SPI_MASTER;
  28.     spi_init_struct.frame_size           = SPI_FRAMESIZE_8BIT;
  29.                 spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
  30.                 spi_init_struct.nss                  = SPI_NSS_SOFT;
  31.                 spi_init_struct.prescale             = SPI_PSC_4;   
  32.                 spi_init_struct.endian               = SPI_ENDIAN_MSB;
  33.                
  34. //    SPI_InitStructure.SPI_CRCPolynomial = 7;   // GD 芯片没有定义
  35.                
  36.     spi_init(SPI1, &spi_init_struct);
  37.           spi_enable(SPI1);   // 使能SPI1
  38.                
  39.                 /*定义RESET引脚*/
  40.                 gpio_init(WIZ_SPIx_RESET_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, WIZ_RESET);
  41.                 gpio_bit_set(WIZ_SPIx_RESET_PORT, WIZ_RESET);
  42.                
  43.                 /*定义INT引脚*/        
  44.                 gpio_init(WIZ_SPIx_INT_PORT, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, WIZ_INT);
  45. }
  1. #define WIZ_SPIx_GPIO_PORT      GPIOB                                                                                    /* GPIO端口                     */
  2. #define WIZ_SPIx_GPIO_CLK       RCU_GPIOB                                /* GPIO端口时钟                 */
  3. #define WIZ_SPIx                SPI1                               /* 定义W5500所用的SPI接口       */
  4. #define WIZ_SPIx_CLK_CMD        RCC_APB1PeriphClockCmd
  5. #define WIZ_SPIx_CLK            RCU_SPI1                          /* 定义W5500所用的SPI接口时钟   */
  6. #define WIZ_SPIx_SCLK           GPIO_PIN_13                                                             /* 定义W5500的时钟管脚          */
  7. #define WIZ_SPIx_MISO           GPIO_PIN_14                                                             /* 定义W5500的MISO管脚          */
  8. #define WIZ_SPIx_MOSI           GPIO_PIN_15                                                             /* 定义W5500的MOSI管脚          */


  9. #define WIZ_SPIx_SCS          GPIO_PIN_9                                                               /* 定义W5500的片选管脚          */
  10. #define WIZ_SPIx_SCS_PORT     GPIOG                                                                                       /* GPIO端口                     */
  11. #define WIZ_SPIx_SCS_CLK      RCU_GPIOG                                   /* GPIO端口时钟                 */

  12. #define WIZ_RESET             GPIO_PIN_15                                                                          /* 定义W5500的RESET管脚         */
  13. #define WIZ_SPIx_RESET_PORT   GPIOG                                                                                       /* GPIO端口                     */
  14. #define WIZ_SPIx_RESET_CLK    RCU_GPIOG                                  /* GPIO端口时钟                 */

  15. #define WIZ_INT               GPIO_PIN_8                                                                          /* 定义W5500的INT管脚           */
  16. #define WIZ_SPIx_INT_PORT     GPIOG                                                                                      /* GPIO端口                     */
  17. #define WIZ_SPIx_INT_CLK      RCU_GPIOG                                  /* GPIO端口时钟                 */
5、复位W5500
  1. /************************************************************
  2. * 函数:       reset_w5500(void)
  3. * 说明:       W5500复位设置函数
  4. * 输入:       无
  5. * 输出:       无
  6. * 返回值:     无
  7. * 作者        凌智君
  8. * 其他:       无
  9. ************************************************************/
  10. void reset_w5500(void)
  11. {
  12.         gpio_bit_reset(WIZ_SPIx_RESET_PORT, WIZ_RESET);
  13.         delay_1us(2);  
  14.         gpio_bit_set(WIZ_SPIx_RESET_PORT, WIZ_RESET);
  15.         delay_1ms(1600);
  16. }
6、定义并配置奋斗者开发板的MAC地址等信息。
  1. /*定义MAC地址,如果多块W5500网络适配板在同一现场工作,请使用不同的MAC地址*/
  2. uint8 mac[6]={0x00,0x08,0xdc,0x11,0x11,0x11};
  1. /************************************************************
  2. * 函数:       reset_w5500(void)
  3. * 说明:       配置W5500的MAC地址
  4. * 输入:       无
  5. * 输出:       无
  6. * 返回值:     无
  7. * 作者        凌智君
  8. * 其他:       无
  9. ************************************************************/
  10. void set_w5500_mac(void)
  11. {
  12.         memcpy(ConfigMsg.mac, mac, 6);
  13.         setSHAR(ConfigMsg.mac);        /**/
  14.         memcpy(DHCP_GET.mac, mac, 6);
  15. }
7、定义并配置开发板的IP信息,注意和电脑在同一网段
  1. /*定义默认IP信息*/
  2. uint8 local_ip[4]  ={192,168,239,88};                                                                                /*定义W5500默认IP地址*/
  3. uint8 subnet[4]    ={255,255,255,0};                                                                                /*定义W5500默认子网掩码*/
  4. uint8 gateway[4]   ={169,168,239,1};                                                                                        /*定义W5500默认网关*/
  5. uint8 dns_server[4]={114,114,114,114};                                                                        /*定义W5500默认DNS*/

  6. uint16 local_port=5000;                                                                       /*定义本地端口*/
  1. void set_w5500_ip(void)
  2. {        
  3.                
  4.    /*复制定义的配置信息到配置结构体*/
  5.         memcpy(ConfigMsg.mac, mac, 6);
  6.         memcpy(ConfigMsg.lip,local_ip,4);
  7.         memcpy(ConfigMsg.sub,subnet,4);
  8.         memcpy(ConfigMsg.gw,gateway,4);
  9.         memcpy(ConfigMsg.dns,dns_server,4);
  10.         if(ip_from==IP_FROM_DEFINE)        
  11.                 printf(" 使用定义的IP信息配置W5500\r\n");
  12.         
  13.         /*使用EEPROM存储的IP参数*/        
  14.         if(ip_from==IP_FROM_EEPROM)
  15.         {
  16.    
  17.                 /*从EEPROM中读取IP配置信息*/
  18.                 read_config_from_eeprom();               
  19.                
  20.                 /*如果读取EEPROM中MAC信息,如果已配置,则可使用*/               
  21.                 if( *(EEPROM_MSG.mac)==0x00&& *(EEPROM_MSG.mac+1)==0x08&&*(EEPROM_MSG.mac+2)==0xdc)               
  22.                 {
  23.                         printf(" IP from EEPROM\r\n");
  24.                         /*复制EEPROM配置信息到配置的结构体变量*/
  25.                         memcpy(ConfigMsg.lip,EEPROM_MSG.lip, 4);                                
  26.                         memcpy(ConfigMsg.sub,EEPROM_MSG.sub, 4);
  27.                         memcpy(ConfigMsg.gw, EEPROM_MSG.gw, 4);
  28.                 }
  29.                 else
  30.                 {
  31.                         printf(" EEPROM未配置,使用定义的IP信息配置W5500,并写入EEPROM\r\n");
  32.                         write_config_to_eeprom();        /*使用默认的IP信息,并初始化EEPROM中数据*/
  33.                 }                        
  34.         }

  35.         /*使用DHCP获取IP参数,需调用DHCP子函数*/               
  36.         if(ip_from==IP_FROM_DHCP)                                                               
  37.         {
  38.                 /*复制DHCP获取的配置信息到配置结构体*/
  39.                 if(dhcp_ok==1)
  40.                 {
  41.                         printf(" IP from DHCP\r\n");                 
  42.                         memcpy(ConfigMsg.lip,DHCP_GET.lip, 4);
  43.                         memcpy(ConfigMsg.sub,DHCP_GET.sub, 4);
  44.                         memcpy(ConfigMsg.gw,DHCP_GET.gw, 4);
  45.                         memcpy(ConfigMsg.dns,DHCP_GET.dns,4);
  46.                 }
  47.                 else
  48.                 {
  49.                         printf(" DHCP子程序未运行,或者不成功\r\n");
  50.                         printf(" 使用定义的IP信息配置W5500\r\n");
  51.                 }
  52.         }
  53.                
  54.         /*以下配置信息,根据需要选用*/        
  55.         ConfigMsg.sw_ver[0]=FW_VER_HIGH;
  56.         ConfigMsg.sw_ver[1]=FW_VER_LOW;        

  57.         /*将IP配置信息写入W5500相应寄存器*/        
  58.         setSUBR(ConfigMsg.sub);
  59.         setGAR(ConfigMsg.gw);
  60.         setSIPR(ConfigMsg.lip);
  61.         
  62.         getSIPR (local_ip);                        
  63.         printf(" W5500 IP地址   : %d.%d.%d.%d\r\n", local_ip[0],local_ip[1],local_ip[2],local_ip[3]);
  64.         getSUBR(subnet);
  65.         printf(" W5500 子网掩码 : %d.%d.%d.%d\r\n", subnet[0],subnet[1],subnet[2],subnet[3]);
  66.         getGAR(gateway);
  67.         printf(" W5500 网关     : %d.%d.%d.%d\r\n", gateway[0],gateway[1],gateway[2],gateway[3]);
  68. }
8、初始化Socket发送和接收缓存
  1. void socket_buf_init( uint8 * tx_size, uint8 * rx_size  )
  2. {
  3.   int16 i;
  4.   int16 ssum=0,rsum=0;

  5.   for (i = 0 ; i < MAX_SOCK_NUM; i++)       // Set the size, masking and base address of Tx & Rx memory by each channel
  6.   {
  7.           IINCHIP_WRITE( (Sn_TXMEM_SIZE(i)), tx_size[i]);
  8.           IINCHIP_WRITE( (Sn_RXMEM_SIZE(i)), rx_size[i]);
  9.          
  10. #ifdef __DEF_IINCHIP_DBG__
  11.          printf("tx_size[%d]: %d, Sn_TXMEM_SIZE = %d\r\n",i, tx_size[i], IINCHIP_READ(Sn_TXMEM_SIZE(i)));
  12.          printf("rx_size[%d]: %d, Sn_RXMEM_SIZE = %d\r\n",i, rx_size[i], IINCHIP_READ(Sn_RXMEM_SIZE(i)));
  13. #endif
  14.     SSIZE[i] = (int16)(0);
  15.     RSIZE[i] = (int16)(0);
  16.         
  17.     if (ssum <= 16384)
  18.     {
  19.                         SSIZE[i] = (int16)tx_size[i]*(1024);
  20.     }

  21.                 if (rsum <= 16384)
  22.                 {
  23.                         RSIZE[i]=(int16)rx_size[i]*(1024);
  24.     }
  25.                         ssum += SSIZE[i];
  26.                         rsum += RSIZE[i];

  27.   }
  28. }
9、输出配置信息
  1. printf(" 网络已完成初始化……\r\n");
  2.         
  3.          printf(" 在Dos命令行中输入cmd,之后输入ping %d.%d.%d.%d \r\n",ConfigMsg.lip[0],ConfigMsg.lip[1],ConfigMsg.lip[2],ConfigMsg.lip[3]);
10、主函数
  1. /************************************************************
  2. * 函数:       System_Init(void)
  3. * 说明:       系统初始化
  4. * 输入:       无
  5. * 输出:       无
  6. * 返回值:     无
  7. * 作者        凌智君
  8. * 其他:       无
  9. ************************************************************/
  10. void System_Init(void)
  11. {
  12.          systick_config();    // 系统主频72MHZ,采用外部晶振
  13.         
  14.          USART0_Config();     // 串口初始化
  15.         
  16.    i2c_CfgGpio();       // 初始化IIC引脚
  17.          
  18.          printf("  凌跃奋斗者全功能板 网络初始化 Demo V1.0 \r\n");        

  19.    gpio_for_w5500_config();                                                /*初始化MCU相关引脚*/
  20.         
  21.          reset_w5500();                                                                                        /*硬复位W5500*/
  22.         
  23.    set_w5500_mac();                                                                                /*配置MAC地址*/
  24.         
  25.          set_w5500_ip();                                                                                /*配置IP地址*/
  26.         
  27.          socket_buf_init(txsize, rxsize);                /*初始化8个Socket的发送接收缓存大小*/
  28.         
  29.          printf(" 网络已完成初始化……\r\n");
  30.         
  31.          printf(" 在Dos命令行中输入cmd,之后输入ping %d.%d.%d.%d \r\n",ConfigMsg.lip[0],ConfigMsg.lip[1],ConfigMsg.lip[2],ConfigMsg.lip[3]);
  32.         
  33. }


因为W5500以太网通信涉及的函数太多,这里只列举了一些比较核心的几个函数,方便大家参考学习。代码都是买完开发板,凌智君指导调试的,测试没有问题。

84211630b5fbbd2bbc.png
sparrow054 发表于 2022-9-5 21:43 | 显示全部楼层
还是双WiFi的?

评论

一个以太网接口,一个2401,一个ESP8266  发表于 2022-9-14 18:26
andygirl 发表于 2022-9-6 21:42 | 显示全部楼层
真不错啊
caigang13 发表于 2022-9-6 23:51 来自手机 | 显示全部楼层
这个开发板有点贵吧

评论

还好吧,500来块钱  发表于 2022-9-14 18:27
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

4

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部