通过CUBEMX配置,驱动LAN8720A芯片实现和电脑通过TCP通讯。

配置ETH

首先通过CUBEMX配置ETH的引脚,选择模式为RMII

根据原理图上的引脚进行对应的配置,还有一个是LAN8720A的复位引脚,我所使用的是PJ12

根据自己硬件连接去进行配置相应的引脚。

配置LWIP

关闭DHCP 根据自己电脑的ip地址和网关 进行手动配置静态ip,

这里PHY芯片选择LAN8742

这里选择freertosCMSIS_V1

然后生成代码

在lwip.c文件里在这里添加复位代码

在任务中初始化LWIP

然后编译烧录 此时应该是可以ping通状态

单片机作为服务器和客户端

新建一个.C文件 加入工程中,将以下代码复制进去

通过修改宏定义 TCP_MODE来切换服务器和客户端模式 TCP_MODE =2时为服务器模式 为3是客户端模式 自行修改相应的ip和端口号 去进行TCP连接。
 

 #include "tcpecho.h"
 #include "lwip/opt.h"
 #include "lwip/sys.h"
 #include "lwip/api.h"
 #include <lwip/sockets.h>

#define TCP_MODE 2		

 #if TCP_MODE ==2
 
/* socket_tcp_server.c */
#define SERVER_PORT 3333 // 端口号
#define BUFF_SIZE 1024
#define SERVER_IP "192.168.1.10"
static char ReadBuff[BUFF_SIZE];
uint8_t send_buf[]= "This is a TCP Client test...\n";

/* TCP服务器端(server)任务 */
void vTCPServer_Task(void *thread_param)
{ 
    int sfd, cfd;
    int read_len;                                // 读的数据长度
    struct sockaddr_in server_addr, client_addr; // 服务器和客户端的结构体
    socklen_t client_addr_len;
    // 创建socket
    sfd = socket(AF_INET, SOCK_STREAM, 0); // IPV4 socker连接 默认协议
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); // 从本机获取
    // 绑定socket
    bind(sfd, (struct sockaddr *)&server_addr, sizeof(server_addr)); // 文件描述符 IP地址加端口号 addr长度 返回值
    // 监听socket
    listen(sfd, 5); // 文件描述符 握手队列总和
    // 等待客户端连接
    client_addr_len = sizeof(client_addr);
    cfd = accept(sfd, (struct sockaddr *)&client_addr, &client_addr_len); // 文件描述符 IP地址加端口号 返回值
//    printf("client is connect cfd = %d\r\n", cfd);
    while (1) // 等待客户端发送数据,然后进行大小写转换,再写回客户端
    {
				
        read_len = lwip_read(cfd, ReadBuff, BUFF_SIZE);
        for (int i = 0; i < read_len; i++)
        {
            ReadBuff[i] = toupper(ReadBuff[i]); // 小写转换为大写
        }
        lwip_write(cfd, ReadBuff, read_len);
    }
}

  void
 client_init(void)
 {
     sys_thread_new("server", vTCPServer_Task, NULL, 512, 4);
 }
   #endif
 #if TCP_MODE ==3
 /* socket_tcp_client.c */
#define CLIENT_PORT 3333 // 端口号
#define BUFF_SIZE 1024
#define CLIENT_IP "192.168.1.108"

static char ReadBuff[BUFF_SIZE];

/* TCP客户端端(client)任务 */
void vTCPClient_Task(void *thread_param)
{
    int cfd;
    int read_len;                   // 读的数据长度
    struct sockaddr_in client_addr; // 服务器结构体
    // 创建socket
    cfd = socket(AF_INET, SOCK_STREAM, 0); // IPV4 socker连接 默认协议
    client_addr.sin_family = AF_INET;
    client_addr.sin_port = htons(CLIENT_PORT);
    client_addr.sin_addr.s_addr = inet_addr(CLIENT_IP); // 本机IPV4
	
    // 连接到服务器
    connect(cfd, (struct sockaddr *)&client_addr, sizeof(client_addr)); // 文件描述符 ip地址和端口号 大小
    while (1)
    {
        read_len = read(cfd, ReadBuff, BUFF_SIZE); // 等待服务器发送数据
        for (int i = 0; i < read_len; i++)
        {
            ReadBuff[i] = toupper(ReadBuff[i]); // 小写转换为大写
        }
        write(cfd, ReadBuff, read_len); // 再写回服务器
    }
}


  void
 client_init(void)
 {
     sys_thread_new("client", vTCPClient_Task, NULL, 512, 4);
 }

  #endif

 同时在.H文件里外部声明函数                   在主任务里运行函数即可

通过TCP与电脑连接上之后 发送小写字母回回复大写字母。

此时即完成了TCP通讯。

参考文档

bhttps://blog.csdn.net/qq_36347513/article/details/125931365

【STM32】HAL库-以太网外设-LAN8720A-LWIP-无操作系统_stm32 lan8720-CSDN博客

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐