STM32407+LAN8720A+LWIP 实现TCP Client
硬件
一、配置CubeMax工程

二、配置系统时钟
因为LAN8720使用的是外部25MHz的晶振,所以不需要单片机输出时钟

三、配置ETH和LWIP参数




四、更改代码
LAN8720A在初始化的时候需要复位,因此在ethernetif.c的 static void low_level_init(struct netif *netif) 函数中添加LAN8720A 的复位程序

再mian函数主循环中添加一下代码,然后编译运行,正常的话,再路由器中能看到程序中设置的MAC地址,以及分配的IP,此时能够ping通
MX_LWIP_Process();
成功了?NoNoNO,如果你启动的时候没有接网线,等启动之后,再插上网线,你会发现,板子死活都不会找dhcp服务器要IP, 结果就是失联。。重大缺陷,不能忍!幸亏LWIP协议栈早就想到了这种情况,LWIP_NETIF_LINK_CALLBACK是干嘛的?就是在连接状态改变的时候,调用一个回调函数,来做相应的处理
在main函数的住循环中加入
extern struct netif *netif_default;
ethernetif_set_link(netif_default);
这个函数会查询当前的连接状态,当状态改变的时候,调用回调函数,在ethernetif.c里我们可以找到这个回调函数,
void ethernetif_update_config(struct netif *netif)
果然有很多处理,那为什么还是不能打开dhcp呢?来看看这个函数的末尾,调用了这个函数
ethernetif_notify_conn_changed()
这个函数,而这个函数看看注释就知道,是需要咱自己来实现的,所以我们加入以下的代码
/**
* @brief This function notify user about link status changement.
* @param netif: the network interface
* @retval None
*/
__weak void ethernetif_notify_conn_changed(struct netif *netif)
{
/* NOTE : This is function could be implemented in user file
when the callback is needed,
*/
if(netif_is_link_up(netif) && !netif_is_up(netif))
{
netif_set_up(netif);
extern err_t dhcp_start(struct netif *netif);
dhcp_start(netif);
}
}
重编译下载,拔掉网线,开机,再插上网线,获得了IP, 大功告成!
五、添加API文件
从库中示例代码中把LwIP/LwIP_TCP_Echo_Client/Src/tcp_echoclient.c 和 tcp_echoclient.h 拷贝到工程中,然后添加发送函数
err_t tcp_client_usersent(struct tcp_pcb *tpcb, uint8_t *buff,uint16_t size)
{
err_t ret_err;
struct echoclient *es;
es=tpcb->callback_arg;
if(es!=NULL) //连接处于空闲时可以发送数据
{
es->p_tx=pbuf_alloc(PBUF_TRANSPORT, size,PBUF_POOL); //申请内存
pbuf_take(es->p_tx,(char*)buff,size); //将tcp_client_sentbuf[]中的数据拷贝到es->p_tx中
tcp_echoclient_send(tpcb,es); //将tcp_client_sentbu[]里面复制给pbuf的数据发送出去
if(es->p_tx)pbuf_free(es->p_tx); //释放内存
ret_err=ERR_OK;
}else
{
tcp_abort(tpcb); //终止连接,删除pcb控制块
ret_err=ERR_ABRT;
}
return ret_err;
}
在 tcp_echoclient.h中需要添加连接到的服务器的IP地址和端口
#include "err.h"
#include "tcp.h"
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void tcp_echoclient_connect(void);
err_t tcp_client_usersent(struct tcp_pcb *tpcb, uint8_t *buff,uint16_t size); #define DEST_IP_ADDR0 192
#define DEST_IP_ADDR1 168
#define DEST_IP_ADDR2 000
#define DEST_IP_ADDR3 108 #define DEST_PORT 9001
通过以上更改,就可以使用 tcp_client_usersent()函数进行发送数据了
/**
* @brief 发送数据包
* @retval None
*/
void UCP_DataAnswer(void)
{
tcp_client_usersent(echoclient_pcb, ToSendBuf, 23);
tcp_client_usersent(echoclient_pcb, DeSendBuf, 23);
}
上面已经能正常发送数据了,如果我把网线拔下来,在插上去又怎么样呢,试试?所有在main函数的主循环中增加断线重连的代码
/* USER CODE BEGIN WHILE */
while ()
{
HAL_GPIO_TogglePin(ALARM_GPIO_Port, ALARM_Pin);
MX_LWIP_Process(); // LwIP Initialization
ethernetif_set_link(netif_default); // This function sets the netif link status. // 拔掉网线后,由于服务端单向断开连接,客户端会进入FIN_WAIT_2等待状态
if(echoclient_pcb->state == CLOSED || echoclient_pcb->state == FIN_WAIT_2)
{
tcp_abort(echoclient_pcb);
tcp_echoclient_connect(); // 断线重连
}
参考博客:https://blog.csdn.net/hustwf/article/details/80040578
STM32407+LAN8720A+LWIP 实现TCP Client的更多相关文章
- STM32F407移植contiki2.6后使用LWIP库实现tcp client
最近在做智能家居,物联网项目,用到了C下的contiki移植 经过一阵调试,终于在 STM32F407移植contiki2.6后使用LWIP库实现tcp client. 一路艰辛谁人知道....唯有留 ...
- (转)lwip TCP client & FreeRTOS 打开TCP 的 保活机制 LWIP_TCP_KEEPALIVE==1
参考大神教程:http://blog.sina.com.cn/s/blog_62a85b950101aw8x.html 老衲五木 :http://blog.sina.com.cn/s/blog_6 ...
- lwip TCP client & FreeRTOS 打开TCP 的 保活机制 LWIP_TCP_KEEPALIVE==1
参考大神教程:http://blog.sina.com.cn/s/blog_62a85b950101aw8x.html 老衲五木 :http://blog.sina.com.cn/s/blog_6 ...
- stm32+lwip(三):TCP测试
我是卓波,很高兴你来看我的博客. 系列文章: stm32+lwip(一):使用STM32CubeMX生成项目 stm32+lwip(二):UDP测试 stm32+lwip(三):TCP测试 stm32 ...
- Stm32CubeMx lwip+freeRTOS TCP 服务
如何添加lwip参照上一篇 stm32CubeMx lwip + freeRTOS 今天讲一下,如何添加TCP服务 LwIP 提供了三种编程接口,分别为 RAW/Callback API.NETC ...
- [原]一个简单的Linux TCP Client所涉及到的头文件
今天在Linux环境下写了一个最简单的TCP Client程序,没想到Linux环境下的头文件竟然这么分散,让我这样的菜鸟很是郁闷啊.编译成功的代码如下: #include <iostream& ...
- W5500EVB TCP Client模式设置说明
W5500EVB是WIZnet为了方便用户更好了解.使用W5500这款网络芯片所开发的评估板,该板採用了 STM32F103RCT6+W5500 的设计.基于 ARM 的 Cortex-M3 平台.那 ...
- 六,ESP8266 TCP Client
今天不知道是不是让我姐挺失望.......很多时候都不知道自己努力的方向对不对,,以后能不能带给家人最美好的期盼...... Init.lua 没啥改变,,就改了一下加载Client.lua gpio ...
- Modbus库开发笔记之四:Modbus TCP Client开发
这一次我们封装Modbus TCP Client应用.同样的我们也不是做具体的应用,而是实现TCP客户端的基本功能.我们将TCP客户端的功能封装为函数,以便在开发具体应用时调用. 对于TCP客户端我们 ...
随机推荐
- -1-2 java 面向对象基本概念 封装继承多态 变量 this super static 静态变量 匿名对象 值传递 初始化过程 代码块 final关键字 抽象类 接口 区别 多态 包 访问权限 内部类 匿名内部类 == 与 equal
java是纯粹的面向对象的语言 也就是万事万物皆是对象 程序是对象的集合,他们通过发送消息来相互通信 每个对象都有自己的由其他的对象所构建的存储,也就是对象可以包含对象 每个对象都有它的类型 也就是 ...
- Perl系列文章
0.Perl书籍推荐 Perl书籍下载 密码:kkqx 下面是一些我学习Perl过程中读过完整的或部分章节的觉得好的书. 入门级别1:<Perl语言入门>即小骆驼 入门级别2:<In ...
- rpm和yum软件管理(week2_day5)--技术流ken
rpm简介 这是一个数据库管理工具,可以通过读取数据库,判断软件是否已经安装,如果已经安装可以读取出来所有文件的所在位置等,并可以实现删除这些文件. rpm:RPM is Redhat Package ...
- C#列表页面后台代码
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI ...
- (摘)使用 .NET Core 实现依赖关系注入
为什么使用依赖关系注入? 使用 .NET,通过 new 运算符(即,new MyService 或任何想要实例化的对象类型)调用构造函数即可轻松实现对象实例化.遗憾的是,此类调用会强制实施客户端(或应 ...
- Spring Boot 整合 elasticsearch
一.简介 我们的应用经常需要添加检索功能,开源的 ElasticSearch 是目前全文搜索引擎的 首选.他可以快速的存储.搜索和分析海量数据.Spring Boot通过整合Spring Data E ...
- Lucene.Net3.0.3+盘古分词器学习使用
一.Lucene.Net介绍 Lucene.net是Lucene的.net移植版本,是一个开源的全文检索引擎开发包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索 ...
- 微信小程序域名配置问题
最主要的:不能用ip地址,不能用localhost,域名要经过备案等 这些在 https://developers.weixin.qq.com/miniprogram/dev/framework/ab ...
- Dynamics 365使用代码发送邮件给指定邮箱地址
摘要: 微软动态CRM专家罗勇 ,回复303或者20190213可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . 当然,首先要 ...
- windows下QT打包
1.找到对应的MinGW命令,打开 2.进入exe目录 3.执行windeployqt XX.exe