工具:正点原子的STM32F4探索者开发板。
准备:STLINK连接电脑和开发板。然后开发板上电,用一根网线连接开发板和路由器,电脑也连接到路由器上(有线或无线均可)。 然后用USB转miniUSB线连接电脑和开发板的串口1(注意接插件到串口1中间有个插针,需要用短路帽连接),然后打开串口调试助手,115200波特率,一直监视着就行。我用的sscom v5.13.1,打开网口调试助手,我也用的sscom,端口5001,一直监听着就行。
工程:用的实验4
参考:这篇文章很好,除了没有源码比较遗憾。这文章里用的是开发板写死IP,而我用的是路由器分配IP。【LWIP】stm32用CubeMX(6.4版)配置LwIP+Ping+TCPclient+TCPserver发送信息到PC(操作部分)_芜~湖~的博客-CSDN博客_stm32cubemx配置lwiphttp://t.csdn.cn/B0pcThttp://t.csdn.cn/B0pcT
下面正式开始:
1.在工程目录中新建 tcpclient.c和tcpclient.h文件,我分别在E:\KEIL_study\CUBE6.3_F407_P3_LWIP\Core\Src 和中E:\KEIL_study\CUBE6.3_F407_P3_LWIP\Core\Inc中定义的。大家可以直接使用我源码中的文件,如果自己创建那么非常要注意的一点:如果是用记事本创建的需要另存编码ANSI,否则串口打印出来是乱码。
这两个文件我基本是从参考文章里复制的,但是增加了TCP连接故障的错误码打印
tcpclinet.c代码如下:
#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 <stdio.h>
#include <string.h>
#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; //这一句一定要放在里面,否则会没用
err_t aa;
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");
//开始连接
aa = tcp_connect(client_pcb, &server_ip, TCP_CLIENT_PORT, client_connected);
ip_set_option(client_pcb, SOF_KEEPALIVE);
printf("已经调用了tcp_connect函数:%d\n",aa);
//注册异常处理
tcp_err(client_pcb, client_err);
printf("已经注册异常处理函数\n");
}
tcpclient.h:
#ifndef _TCPCLIENT_H_
#define _TCPCLIENT_H_
#define TCP_CLIENT_PORT 5001
#include "stdio.h"
void TCP_Client_Init(void);
#endif
2.把新建的c文件添加到工程,由于.h文件目录已被包含,所以无需操作
3.代码添加
3.1)main.h添加,注意里面的DEST_IP_ADDR0-3对应电脑的IP,因为要用电脑的网络助手作为TCP服务器。例如,我的电脑IP是192.168.2.192。
3.2)TIM.c中定义两个变量,用于定时5s重新初始化TCP,这个很重要,后面会讲原因
3.3)main.c中添加TCP初始化函数调用
4.编译下载即可,现象如下:
左图为串口信息,可以看到,一开始TCP连接状态是-4,这个可以查到err.h中 ERR_RTE = -4, 应该就是没有IP的意思,后面变0了说明是得到路由器给分配的IP了,然后就连接OK了,同时右侧的TCPServer窗口出现了周期的数据。
同时试了下TCPServer发送数据,结果又收到同样的反馈了,相关代码如下
5.源码:
链接:https://pan.baidu.com/s/1Ip0YKY22rUM-YpJ42gqfaw?pwd=1234
提取码:1234
https://download.csdn.net/download/Running_A/85602888