ST意法半导体
直播中

发生的方式

9年用户 1325经验值
擅长:处理器/DSP
私信 关注
[问答]

STM32F107 DP83848 lwip通信做客户端无法同PC端建立联系的原因?

  移植的网上的程序,PC端使用调试助手做服务端,查看可以ping通但是无法建立联系,请问大佬们是什么原因
#include "lwip/netif.h"#include "lwip/ip.h"#include "lwip/tcp.h"#include "lwip/init.h"#include "netif/etharp.h"#include "lwip/udp.h"#include "lwip/pbuf.h"#include #include #include "main.h"static void client_err(void *arg, err_t err)       //³öÏÖ´íÎóʱµ÷ÓÃÕâ¸öº¯Êý£¬´òÓ¡´íÎóÐÅÏ¢£¬²¢³¢ÊÔÖØÐÂÁ¬½Ó{  printf("Á¬½Ó´íÎó!!n");    printf("³¢ÊÔÖØÁ¬!!n");  //Á¬½Óʧ°ÜµÄʱºòÊÍ·ÅTCP¿ØÖÆ¿éµÄÄÚ´æ    printf("¹Ø±ÕÁ¬½Ó£¬ÊÍ·ÅTCP¿ØÖÆ¿éÄÚ´æn");  //tcp_close(client_PCB);  //ÖØÐÂÁ¬½Ó    printf("ÖØÐ³õʼ»¯¿Í»§¶Ën");    TCP_Client_Init();}static err_t client_send(void *arg, struct tcp_pcb *tpcb)   //·¢Ëͺ¯Êý£¬µ÷ÓÃÁËtcp_writeº¯Êý{  uint8_t send_buf[]= "ÎÒÊǿͻ§¶Ën";  //·¢ËÍÊý¾Ýµ½·þÎñÆ÷  tcp_write(tpcb, send_buf, sizeof(send_buf), 1);   return ERR_OK;}static err_t client_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err){  if (p != NULL)   {          /* ½ÓÊÕÊý¾Ý*/    tcp_recved(tpcb, p->tot_len);    /* ·µ»Ø½ÓÊÕµ½µÄÊý¾Ý*/      tcp_write(tpcb, p->payload, p->tot_len, 1);    memset(p->payload, 0 , p->tot_len);    pbuf_free(p);  }   else if (err == ERR_OK)   {    //·þÎñÆ÷¶Ï¿ªÁ¬½Ó    printf("·þÎñÆ÷¶Ï¿ªÁ¬½Ó!n");    tcp_close(tpcb);    //ÖØÐÂÁ¬½Ó    TCP_Client_Init();  }  return ERR_OK;}static err_t client_connected(void *arg, struct tcp_pcb *pcb, err_t err){  printf("connected ok!n");  //×¢²áÒ»¸öÖÜÆÚÐԻص÷º¯Êý  tcp_poll(pcb,client_send,2);  //×¢²áÒ»¸ö½ÓÊÕº¯Êý  tcp_recv(pcb,client_recv);  return ERR_OK;}void TCP_Client_Init(void){          struct tcp_pcb *client_pcb = NULL;   //ÕâÒ»¾äÒ»¶¨Òª·ÅÔÚÀïÃæ£¬·ñÔò»áûÓà ip4_addr_t server_ip;     //ÒòΪ¿Í»§¶ËÒªÖ÷¶¯Á¬½Ó·þÎñÆ÷£¬ËùÒÔÒªÖªµÀ·þÎñÆ÷µÄIPµØÖ·  /* ´´½¨Ò»¸öTCP¿ØÖƿ頠*/  client_pcb = tcp_new();       IP4_ADDR(&server_ip, DEST_IP_ADDR0,DEST_IP_ADDR1,DEST_IP_ADDR2,DEST_IP_ADDR3);//ºÏ²¢IPµØÖ·  printf("¿Í»§¶Ë¿ªÊ¼Á¬½Ó!n");  //¿ªÊ¼Á¬½Ó  tcp_connect(client_pcb, &server_ip, TCP_CLIENT_PORT, client_connected);    ip_set_option(client_pcb, SOF_KEEPALIVE);    printf("ÒѾ­µ÷ÓÃÁËtcp_connectº¯Êýn");  //×¢²áÒì³£´¦Àí  tcp_err(client_pcb, client_err);    printf("ÒѾ­×¢²áÒì³£´¦Àíº¯Êýn");}

回帖(1)

杨勇

2025-3-8 17:34:30

在STM32F107上使用DP83848和lwIP进行网络通信时,虽然能够ping通,但无法与PC端建立TCP连接,可能的原因有很多。以下是一些常见的问题和排查步骤:


1. 网络配置问题



  • IP地址、子网掩码、网关:确保STM32和PC在同一个子网内,IP地址、子网掩码和网关配置正确。

  • MAC地址:确保DP83848的MAC地址是唯一的,并且正确配置。


2. lwIP配置问题



  • 内存配置:检查lwipopts.h文件中的内存配置,确保有足够的内存用于TCP连接。默认配置可能不足以支持复杂的网络操作。

  • TCP/IP协议栈初始化:确保lwip_init()函数在系统启动时被正确调用,并且网络接口(netif)已经正确初始化。


3. TCP客户端代码问题



  • TCP连接建立:检查TCP客户端代码,确保在连接PC端时,tcp_connect()函数被正确调用,并且回调函数(如tcp_recvtcp_sent等)已正确设置。

  • 错误处理:在client_err回调函数中,打印出错误信息,帮助定位问题。常见的错误包括ERR_CONN(连接失败)、ERR_TIMEOUT(超时)等。


4. 防火墙和端口问题



  • PC端防火墙:确保PC端的防火墙没有阻止来自STM32的连接请求。

  • 端口号:确保PC端调试助手监听的是正确的端口号,并且STM32客户端尝试连接的端口号与之一致。


5. 硬件问题



  • DP83848初始化:确保DP83848已正确初始化,并且能够正常发送和接收数据包。

  • PHY状态:检查PHY的状态寄存器,确保PHY处于正常工作状态。


6. 调试信息



  • 打印调试信息:在关键步骤(如连接建立、数据发送等)添加调试信息,帮助定位问题。

  • 抓包工具:使用Wireshark等抓包工具,捕获网络流量,分析STM32和PC之间的通信是否正常。


7. 代码示例


以下是一个简单的TCP客户端代码示例,供参考:


   #include "lwip/tcp.h"
   #include "lwip/ip.h"
   #include "lwip/init.h"
   #include "netif/etharp.h"
   #include "lwip/udp.h"
   #include "lwip/pbuf.h"
   #include "main.h"

   static struct tcp_pcb *tcp_client_pcb;
   static ip_addr_t server_ip;

   static err_t tcp_client_connected(void *arg, struct tcp_pcb *pcb, err_t err)
   {
       if (err == ERR_OK) {
           // 连接成功,可以发送数据
           char *data = "Hello, Server!";
           tcp_write(pcb, data, strlen(data), TCP_WRITE_FLAG_COPY);
           tcp_output(pcb);
       } else {
           // 连接失败
           printf("Connection failed: %dn", err);
       }
       return ERR_OK;
   }

   static void tcp_client_err(void *arg, err_t err)
   {
       if (err != ERR_OK) {
           printf("TCP client error: %dn", err);
       }
   }

   void tcp_client_init(void)
   {
       tcp_client_pcb = tcp_new();
       if (tcp_client_pcb != NULL) {
           IP4_ADDR(&server_ip, 192, 168, 1, 100); // 设置服务器IP地址
           tcp_connect(tcp_client_pcb, &server_ip, 1234, tcp_client_connected);
           tcp_err(tcp_client_pcb, tcp_client_err);
       }
   }

   int main(void)
   {
       lwip_init();
       // 初始化网络接口等
       tcp_client_init();
       while (1) {
           // 主循环
       }
       return 0;
   }

8. 进一步调试



  • lwIP调试:启用lwIP的调试输出,查看是否有错误信息或警告。

  • 硬件调试:使用逻辑分析仪或示波器检查DP83848的通信信号,确保硬件连接正常。


通过以上步骤,应该能够逐步定位并解决问题。如果问题仍然存在,建议进一步检查硬件连接和lwIP的配置。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分