STM32 + CubeMX + 硬件SPI + W5500 +UDP

[复制链接]
发表于 2025-12-31 07:13:25 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
  这篇文章纪录一下STM32+W5500+UDP的调试过程,实现UDP数据的吸收与发送。


一、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)MyUDP.h

  1. #ifndef MYUDP_H
  2. #define MYUDP_H
  3. #include "MyUDP.h"
  4. #include "main.h"
  5. #include "w5500.h"
  6. #include "socket.h"
  7. #include "wizchip_conf.h"
  8. #include "spi.h"
  9. #include <string.h>  // memcmp
  10. #define SOCK_UDPS  2    //定义socket号
  11. extern  uint8_t buff[128];   //定义缓冲区   
  12. extern uint8_t UDP_send_buff[128];   //定义UDP发送缓冲区                                            
  13. extern uint8_t remote_ip[4]; //远程IP地址
  14. extern uint16_t remote_port; //远程端口号
  15. void UDPinit(void);
  16. void do_udp(void);
  17. void UDP_send(uint8_t* data,uint8_t len);
  18. void Analysis(uint8_t *buf);
  19. #endif // MYUDP_H
复制代码
(2)MyUDP.c

  1. #include "MyUDP.h"
  2. #include "main.h"
  3. #include "w5500.h"
  4. #include "socket.h"
  5. #include "wizchip_conf.h"
  6. #include "spi.h"
  7. #include <string.h>  // memcmp
  8. uint8_t buff[128];  
  9. uint8_t UDP_send_buff[128];
  10.                                                    
  11. uint8_t remote_ip[4] = {192, 168, 1, 2}; //远程IP地址
  12. uint16_t remote_port = 5002; //远程端口号
  13. //片选
  14. void W5500_Select(void) {
  15.     HAL_GPIO_WritePin(W5500_CS_GPIO_Port, W5500_CS_Pin, GPIO_PIN_RESET);
  16. }
  17. void W5500_Unselect(void) {
  18.     HAL_GPIO_WritePin(W5500_CS_GPIO_Port, W5500_CS_Pin, GPIO_PIN_SET);
  19. }
  20. void W5500_Restart(void) {
  21.     HAL_GPIO_WritePin(W5500_RST_GPIO_Port, W5500_RST_Pin, GPIO_PIN_RESET);
  22.     HAL_Delay(1);  // delay 1ms
  23.     HAL_GPIO_WritePin(W5500_RST_GPIO_Port, W5500_RST_Pin, GPIO_PIN_SET);
  24.     HAL_Delay(1600);  // delay 1600ms
  25. }
  26. void W5500_ReadBuff(uint8_t* buff, uint16_t len) {
  27.     HAL_SPI_Receive(&hspi1, buff, len, HAL_MAX_DELAY);
  28. }
  29. void W5500_WriteBuff(uint8_t* buff, uint16_t len) {
  30.     HAL_SPI_Transmit(&hspi1, buff, len, HAL_MAX_DELAY);
  31. }
  32. uint8_t W5500_ReadByte(void) {
  33.     uint8_t byte;
  34.     W5500_ReadBuff(&byte, sizeof(byte));
  35.     return byte;
  36. }
  37. void W5500_WriteByte(uint8_t byte) {
  38.     W5500_WriteBuff(&byte, sizeof(byte));
  39. }
  40. //配置W5500网络信息
  41. wiz_NetInfo gSetNetInfo = {
  42.   .mac  = {0x00, 0x08, 0xdc, 0x11, 0x11, 0x11},
  43.   .ip   = {192, 168, 1, 10},
  44.   .sn   = {255, 255, 255, 0},
  45.   .gw   = {192, 168, 1, 1},
  46.   .dns  = {144, 144, 144, 144},
  47.   .dhcp = NETINFO_STATIC};
  48. wiz_NetInfo gGetNetInfo;
  49. enum Status
  50. {
  51.   Failed = 0,
  52.   Success = 1
  53. };
  54. /**
  55. * @brief valid the result of set net info
  56. * @return 1: Success
  57. *         0: Failed
  58. */
  59. uint8_t validSetNetInfoResult(wiz_NetInfo* _set, wiz_NetInfo* _get)
  60. {
  61.   return (!memcmp(_set, _get, sizeof(wiz_NetInfo)));  // if same, memcmp return 0
  62. }
  63. void UDPinit(void)
  64. {
  65.   reg_wizchip_cs_cbfunc(W5500_Select, W5500_Unselect);
  66.   reg_wizchip_spi_cbfunc(W5500_ReadByte, W5500_WriteByte);
  67.   W5500_Restart();  // hardware restart through RESET pin
  68.   ctlnetwork(CN_SET_NETINFO, (void*)&gSetNetInfo);  // set net info
  69.   // maybe need delay
  70.   ctlnetwork(CN_GET_NETINFO, (void*)&gGetNetInfo);  // get net info
  71.   // W5500 has 8 channel, 32k buffer, 2 means 2KBytes
  72.   uint8_t buffer_size_8channel_tx_rx[16] = {2, 2, 2, 2, 2, 2, 2, 2,  // 8 channel tx
  73.                                             2, 2, 2, 2, 2, 2, 2, 2}; // 8 channel rx
  74.   if(ctlwizchip(CW_INIT_WIZCHIP,(void*)buffer_size_8channel_tx_rx))
  75.   {
  76.     // failed
  77.    
  78.   }
  79.   uint8_t sta = getSn_SR(SOCK_UDPS);
  80.   if(sta == SOCK_CLOSED)
  81.   {
  82.     socket(SOCK_UDPS, Sn_MR_UDP, 5001, 0);
  83.   }
  84.   HAL_Delay(100);
  85. }
  86. void do_udp(void)
  87. {                                                              
  88.         uint16_t len=0;       
  89.         switch(getSn_SR(SOCK_UDPS))       /*获取socket的状态*/
  90.         {
  91.                 case SOCK_CLOSED:                 /*socket处于关闭状态*/
  92.                         socket(SOCK_UDPS,Sn_MR_UDP,5001,0);    /*初始化socket*/
  93.                   break;
  94.                
  95.                 case SOCK_UDP:      /*socket初始化完成*/
  96.                         HAL_Delay(10);  
  97.                         if(getSn_IR(SOCK_UDPS) & Sn_IR_RECV) //检查是否有接收中断
  98.                         {
  99.                                 setSn_IR(SOCK_UDPS, Sn_IR_RECV);  /*清接收中断*/
  100.                         }
  101.                         if((len=getSn_RX_RSR(SOCK_UDPS))>0)  /*接收到数据*/
  102.                         {
  103.                                 recvfrom(SOCK_UDPS,buff, len, remote_ip,&remote_port);               /*W5500接收计算机发送来的数据W5500接收计算机发送来的数据,并获取发送方的IP地址和端口号*/
  104.                                 sendto(SOCK_UDPS,buff,len-8, remote_ip, remote_port);                /*W5500把接收到的数据发送*/
  105.         Analysis(buff);//分析数据
  106.         memset(buff, 0, sizeof(buff));
  107.                         }
  108.                         break;
  109.         }
  110. }
  111. void UDP_send(uint8_t* data,uint8_t len)
  112. {
  113.   sendto(SOCK_UDPS, data, len, remote_ip, remote_port);
  114.   memset(data, 0, len);
  115. }
  116. //分析数据
  117. void Analysis(uint8_t *buf)
  118. {
  119. }
复制代码
3、修改CubeMx已天生的代码

(1)main.c

  1. #include <stdio.h>
  2. #include "MyUDP.h"
  3. int main(void)
  4. {
  5.   HAL_Init();
  6.   SystemClock_Config();
  7.   MX_GPIO_Init();
  8.   MX_USART1_UART_Init();
  9.   MX_SPI1_Init();
  10.   UDPinit();
  11.   while (1)
  12.   {
  13.         do_udp();
  14.   }
  15. }
复制代码
四、硬件毗连

STM32开辟板W5500模块5V5VGNDGNDPA4SCSPA6MISOPA5SCKPA7MOSIPB4RSTPB5INT五、运行结果

(1)、将W5500和电脑通过网线直连
(2)、给电脑设置一个192.168.1.x网段的IP
(3)、ping 192.168.1.10(W5500的IP),能ping通。再利用网络调试助手给192.186.1.10的5001端口发送数据,之后网络调试助手能收到返回的数据。

回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表