基于STM32F107和DP83848的TCP服务器数据收发方案

基于STM32F107和DP83848的TCP服务器数据收发方案

一、系统概述

本方案基于STM32F107VCT6(带以太网MAC控制器)和DP83848C(10/100M以太网PHY芯片),通过RMII接口实现TCP服务器功能,支持多客户端连接数据收发低功耗管理。系统采用LWIP协议栈(轻量级TCP/IP)实现网络层功能,适用于工业控制、远程监测、物联网网关等场景。

二、硬件设计

1. 核心组件选型

组件 型号/规格 功能说明
主控芯片 STM32F107VCT6 带ETH MAC,256KB Flash,64KB RAM
PHY芯片 DP83848C 10/100M RMII PHY,支持自动协商
网络变压器 HR911105A RJ45集成变压器,隔离干扰
晶振 25MHz(ETH专用) 为DP83848提供时钟
电源 3.3V LDO(AMS1117) 为STM32和DP83848供电

2. 硬件连接(RMII接口)

DP83848引脚 STM32F107引脚 功能说明
TXD0 PA2 (ETH_RMII_TXD0) 发送数据0(RMII)
TXD1 PA3 (ETH_RMII_TXD1) 发送数据1(RMII)
TX_EN PA1 (ETH_RMII_TX_EN) 发送使能(RMII)
RXD0 PC4 (ETH_RMII_RXD0) 接收数据0(RMII)
RXD1 PC5 (ETH_RMII_RXD1) 接收数据1(RMII)
CRS_DV PA7 (ETH_RMII_CRS_DV) 载波侦听/数据有效(RMII)
RX_ER PG2 (ETH_RMII_RX_ER) 接收错误(可选)
REF_CLK PA8 (ETH_RMII_REF_CLK) RMII参考时钟(50MHz)
MDIO PA2 (ETH_MDIO) PHY管理数据接口
MDC PC1 (ETH_MDC) PHY管理时钟(最高2.5MHz)
RESET PB11 (GPIO) 复位(低电平有效)

三、软件设计(STM32CubeMX + LWIP)

1. STM32CubeMX配置

(1)时钟与ETH

(2)LWIP协议栈配置

(3)生成工程

选择MDK-ARM或STM32CubeIDE,生成HAL库工程,自动包含ETH和LWIP驱动。

2. 核心代码实现

(1)ETH与LWIP初始化(自动生成,略作修改)

// ethernetif.c(LWIP网络接口层)
#include "lwip/opt.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "netif/etharp.h"
#include "ethernetif.h"
#include "stm32f1xx_hal.h"

// 网络接口结构体
struct netif gnetif;

// ETH初始化
void ETH_BSP_Config(void) {
  // 使能ETH时钟
  __HAL_RCC_ETH_CLK_ENABLE();
  // 配置RMII接口(CubeMX自动生成)
  // ...
}

// LWIP初始化
void LwIP_Init(void) {
  ip4_addr_t ipaddr, netmask, gw;
  IP4_ADDR(&ipaddr, 192, 168, 1, 100);
  IP4_ADDR(&netmask, 255, 255, 255, 0);
  IP4_ADDR(&gw, 192, 168, 1, 1);
  
  // 添加网络接口
  netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &tcpip_input);
  netif_set_default(&gnetif);
  netif_set_up(&gnetif);
}

(2)TCP服务器实现(应用层)

// tcp_server.c
#include "tcp_server.h"
#include "lwip/tcp.h"
#include "lwip/err.h"
#include <string.h>

// TCP控制块
static struct tcp_pcb *tcp_server_pcb;

// 接收回调函数
static err_t TCP_Server_Recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
  if (p == NULL) { // 客户端断开连接
    tcp_close(tpcb);
    return ERR_OK;
  }
  
  // 处理接收数据(示例:回显数据)
  char *data = (char*)p->payload;
  uint16_t len = p->len;
  tcp_write(tpcb, data, len, TCP_WRITE_FLAG_COPY); // 回显
  tcp_recved(tpcb, p->tot_len); // 通知LWIP已接收数据
  pbuf_free(p); // 释放pbuf
  return ERR_OK;
}

// 连接回调函数
static err_t TCP_Server_Accept(void *arg, struct tcp_pcb *newpcb, err_t err) {
  tcp_recv(newpcb, TCP_Server_Recv); // 绑定接收回调
  return ERR_OK;
}

// 创建TCP服务器
void TCP_Server_Init(uint16_t port) {
  tcp_server_pcb = tcp_new(); // 创建TCP控制块
  if (tcp_bind(tcp_server_pcb, IP_ADDR_ANY, port) != ERR_OK) {
    // 绑定失败
    return;
  }
  tcp_listen(tcp_server_pcb); // 监听端口
  tcp_accept(tcp_server_pcb, TCP_Server_Accept); // 绑定连接回调
}

(3)主程序逻辑

// main.c
#include "main.h"
#include "lwip.h"
#include "tcp_server.h"

int main(void) {
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_ETH_Init();
  MX_LWIP_Init(); // 初始化LWIP
  
  // 创建TCP服务器(端口8080)
  TCP_Server_Init(8080);
  
  while (1) {
    // 主循环:处理LWIP任务(CubeMX自动生成)
    MX_LWIP_Process();
  }
}

参考代码 基于STM32F107和DP83848芯片的TCP服务器收发数据 www.youwenfan.com/contentcns/101784.html

四、关键功能实现

1. 多客户端连接管理

// 多客户端管理示例
typedef struct {
  struct tcp_pcb *pcb;
  uint8_t connected;
} Client_Info;

Client_Info clients[5]; // 最大5个客户端

// 在Accept回调中分配客户端
static err_t TCP_Server_Accept(void *arg, struct tcp_pcb *newpcb, err_t err) {
  for (int i=0; i<5; i++) {
    if (!clients[i].connected) {
      clients[i].pcb = newpcb;
      clients[i].connected = 1;
      tcp_recv(newpcb, TCP_Server_Recv);
      return ERR_OK;
    }
  }
  tcp_close(newpcb); // 超过最大连接数,拒绝
  return ERR_MEM;
}

2. 数据收发优化

// 大数据发送示例(分片)
void Send_LargeData(struct tcp_pcb *tpcb, uint8_t *data, uint32_t len) {
  uint32_t offset = 0;
  while (len > 0) {
    uint16_t send_len = (len > TCP_MSS) ? TCP_MSS : len;
    tcp_write(tpcb, data+offset, send_len, TCP_WRITE_FLAG_COPY);
    offset += send_len;
    len -= send_len;
  }
  tcp_output(tpcb); // 立即发送
}

3. 低功耗设计

// 进入低功耗模式
void Enter_LowPowerMode(void) {
  // 关闭ETH时钟
  __HAL_RCC_ETH_CLK_DISABLE();
  // 进入停止模式
  HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
  // 唤醒后恢复
  SystemClock_Config();
  __HAL_RCC_ETH_CLK_ENABLE();
  ETH_BSP_Config();
}

五、测试与验证

1. 测试工具

2. 测试项目

测试项 测试方法 预期结果
服务器启动 上电后查看IP配置 正确获取IP(192.168.1.100)
客户端连接 用NetAssist连接8080端口 连接成功,显示“Connected”
数据收发 发送“Hello”,接收回显 接收数据与发送一致
多客户端连接 同时连接3个客户端 均能正常收发数据
断线重连 拔掉网线后重连 自动恢复连接(DHCP场景)

六、注意事项

1. 硬件设计

2. 软件配置

七、总结

本方案基于STM32F107和DP83848实现了TCP服务器功能,通过RMII接口连接PHY芯片,LWIP协议栈处理网络协议,支持多客户端连接高效数据收发

专注于matlab/simulink,电子电路,编程