STM32F407单片机编程入门(二十七)以太网接口(LAN8720)详解及实战含源码

一.概要

以太网(Ethernet)。指的是由Xerox公司创建并由Xerox,Intel和DEC公司联合开发的基带局域网规范。以太网络使用CSMA/CD(载波监听多路访问及冲突检测技术)技术,并以10M/S的速率运行在多种类型的电缆上。以太网与IEEE802·3系列标准相类似。 它不是一种具体的网络,是一种技术规范。 以太网是当今现有局域网采用的最通用的通信协议标准。该标准定义了在局域网(LAN)中采用的电缆类型和信号处理方法。以太网在互联设备之间以10~100Mbps的速率传送信息包,双绞线电缆10 Base T以太网由于其低成本、高可靠性以及10Mbps的速率而成为应用最为广泛的以太网技术。

以太网是一种广泛应用于各种计算机局域网技术,被普遍用于以下场景:

‌‌工业自动化‌:以太网在工业自动化领域有着广泛的应用。它能够满足工业自动化系统对大量数据传输和实时性的需求,支持多设备连接,适应高温、高湿等恶劣环境,适用于复杂的工业环境。

‌‌企业网络‌:在企业网络中,以太网用于构建高速、稳定的内部网络,支持数据、视频和语音等多业务传输。它广泛应用于大型企业和数据中心,提供高速数据传输支持。

‌‌智能交通‌:在智能交通系统中,以太网连接交通监控设备,实现交通数据的实时传输。这有助于提高交通管理的效率和安全性。

远程监控‌:在远程监控系统中,以太网用于将监控数据传输到控制中心,提高监控效率。它广泛应用于各种远程监控场景,如‌环境监测、设备监控等。

‌数据中心‌:数据中心使用以太网连接服务器和存储设备,实现高速数据交换。‌万兆以太网在数据中心的应用尤为广泛,满足高性能计算和大数据处理的需求。

‌‌超级计算中心‌:在超级计算中心,万兆以太网设备提供高密度的端口和快速的交换性能,满足高性能计算机架构和网络的需求,促进计算机科学研究的发展。

二.单片机以太网系统基本结构

1.OSI 七层模型

‌OSI七层模型‌是国际标准化组织(ISO)定义的一个网络通信框架,旨在为不同计算机系统之间的通信提供一个标准化的方法。这个模型将网络通信过程划分为七个层次,从物理层到应用层,每一层都有其特定的功能和协议。

在这里插入图片描述

2.单片机实现以太网功能组成

一般单片机组成以太网所需部件是:单片机+MAC+PHY+RJ45。

STM32F407VET6内部自带MAC,所以要组成以太网,主要部件就是
STM32F407VET6+PHY+RJ45。
我们常见的以太网PHY芯片是DP83848和LAN8720。

在这里插入图片描述

以太网MAC‌:即媒体访问控制子层协议‌,位于OSI七层协议中的数据链路层下半部分,主要负责控制与连接物理层的物理介质。MAC协议的主要功能包括在发送数据时判断是否可以发送,如果可以发送,则给数据加上一些控制信息,最终将数据以及控制信息以规定的格式发送到物理层;在接收数据时,MAC协议首先判断输入的信息是否发生传输错误,如果没有错误,则去掉控制信息发送至逻辑链路控制层。

以太网PHY:即物理层接口收发器,是网络通信中的一个重要组成部分,它实现了OSI模型中的物理层。IEEE-802.3标准定义了以太网PHY,包括多个子层,如MII/GMII(介质独立接口)、PCS(物理编码子层)、PMA(物理介质附加子层)、PMD(物理介质相关子层)和MDI子层。这些子层共同定义了数据传送与接收所需要的电与光信号、线路状态、时钟基准、数据编码和电路等,并向数据链路层设备提供标准接口。

三.STM32F407VET6单片机以太网内部结构

在这里插入图片描述
以太网在进行数据发送时,单片机首先将数据由系统存储器以 DMA 的方式送至发送 FIFO (Tx FIFO) 进行缓冲,再通过 MAC内核发送,MAC通过RMII或者MII接口与外部PHY进行通讯。
以太网在进行数据接收时,接收 FIFO (Rx FIFO) 则存储通过线路接收的以太网帧,直到这些帧通过 DMA 传送到系统存储器。

1.MII接口介绍

介质独立接口 (MII) 定义了 10 Mbit/s 和 100 Mbit/s 的数据传输速率下 MAC 子层与 PHY 之
间的互连。

MII连接示意图
在这里插入图片描述

在这里插入图片描述

2.RMII接口介绍

精简介质独立接口 (RMII) 规范降低了 10/100 Mbit/s 下微控制器以太网外设与外部 PHY 间的引脚数。

RMII连接示意图

在这里插入图片描述

在这里插入图片描述

对比以上两种连接方式,RMII通过减少信号线数量和提高时钟频率,提供了一种在保持或提高数据传输速率的同时简化硬件设计的解决方案。这种接口在需要平衡成本、性能和复杂性的应用中特别有用‌,所以在STM32开发中,最常见的是RMII连接方式。

四.LWIP TCP/IP协议栈介绍

TCP/IP 协议栈是一系列网络协议的总和,它允许不同电子设备在因特网上进行通信。该协议采用4层结构,分别是应用层、传输层、网络层和网络接口层,每一层都依赖于其下面的层,同时为其上面的层提供服务。

TCP/IP 协议栈和传统的 OSI 模型并不完全对应。TCP/IP 协议是一个简化的模型,强调了实际的协议实现和因特网的实际运作方式。
在这里插入图片描述

Light weight IP(LWIP)是轻量化的 TCP/IP 协议,是瑞典计算机科学院(SICS)的 Adam Dunkels 开发的一个小型开源的 TCP/IP 协议栈。 LwIP 的设计初衷是:用少量的资源消耗(RAM)实现一个较为完整的 TCP/IP 协议栈, 在保持 TCP 协议主要功能的基础上减少对 RAM 的占用。
LwIP既可以移植到操作系统上运行,也可以在无操作系统的情况下独立运行。它只需十几KB的RAM和40K左右的ROM就可以运行,这使LwIP协议栈适合在低端的嵌入式系统中使用。

LwIP是符合 TCP/IP 模型架构,规定了数据的格式、传输、路由和接收,以实现端到端的通信。

应用层:lwIP提供了TCP/IP协议栈的实现,包括HTTP,MQTT等协议
传输层:lwIP实现了TCP和UDP协议
网络层:lwIP实现了IP协议
网络接口层:lwIP并没有实现,这一层由硬件来实现
在这里插入图片描述

五.PHY收发器LAN8720介绍

‌LAN8720A是一款低功耗的10/100M以太网PHY芯片,符合EEE802.3-2005标准,支持通过RMII接口与以太网MAC层通信。‌ 它内置了10-BASE-T/100BASE-TX全双工传输模块,支持10Mbps和100Mbps的传输速度。LAN8720A具有自协商功能,能够与目的主机自动选择最佳连接方式(速度和双工模式),并支持HP Auto-MDIX自动翻转功能,无需更换网线即可实现直连或交叉连接。此外,它还支持通过SMI串行管理接口和MAC接口进行配置和管理。
在这里插入图片描述

1.LAN8720内部框图

在这里插入图片描述

2.LAN8720应用电路

在这里插入图片描述

3.LAN8720以太网模块

LAN8720以太网模块是把PHY,RJ45都放在一块小板子上,只要开发板与模块通过RMII连接,就能组成以太网系统。
在这里插入图片描述

模块参考原理图

在这里插入图片描述

六.CubeMX配置一个LWIP的TCP/IP通讯协议实验

硬件准备:

STLINK接STM32F407VET6开发板,STLINK接电脑USB口。LAN8720模块接到开发板上,网线接模块的RJ45口跟电脑。
在这里插入图片描述

开发板以太网接口定义:
在这里插入图片描述

打开STM32CubeMX软件,新建工程
在这里插入图片描述
Part Number处输入STM32F407VE,再双击就创建新的工程
在这里插入图片描述

配置下载口引脚
在这里插入图片描述

配置外部晶振引脚
在这里插入图片描述

配置以太网RMII接口
在这里插入图片描述
配置中断
在这里插入图片描述
在这里插入图片描述
PHY选择DP83848
在这里插入图片描述
使能FreeRTOS
在这里插入图片描述

LWIP配置,IP地址,掩码,网关配置
在这里插入图片描述

配置系统主频168Mhz,使用外部晶振
在这里插入图片描述

配置工程文件名,保存路径,KEIL5工程输出方式
在这里插入图片描述

生成工程
在这里插入图片描述

用Keil5打开工程
在这里插入图片描述

添加代码

在这里插入图片描述

在这里插入图片描述

主要代码如下:

#define BOARD_IP  			 192,168,1,12   		//开发板ip 
#define BOARD_NETMASK   	 255,255,255,0   		//开发板子网掩码
#define BOARD_WG		   	 192,168,1,1   			//开发板子网关
#define BOARD_MAC_ADDR       0,0,0,0,0,1			//开发板MAC地址

#define TCP_LOCAL_PORT     		8887 
#define TCP_SERVER_PORT    		8888
#define TCP_SERVER_IP   		192,168,1,11//服务器IP
/***********************************************************************
函数名称:void TCP_Client_Send_Data(unsigned char *buff)
功    能:TC[客户端发送数据函数
输入参数:
输出参数:
编写时间:2013.4.25
编 写 人:
注    意:for(cpcb = tcp_active_pcbs;cpcb != NULL; cpcb = cpcb->next) 
***********************************************************************/
err_t TCP_Client_Send_Data(struct tcp_pcb *cpcb,unsigned char *buff,unsigned int length)
{
	err_t err;

	err = tcp_write(cpcb,buff,length,TCP_WRITE_FLAG_COPY);	//发送数据
	tcp_output(cpcb);
	//tcp_close(tcp_client_pcb);				//发送完数据关闭连接,根据具体情况选择使用	
	return err;					
}
extern union tcp_listen_pcbs_t tcp_listen_pcbs;
extern struct tcp_pcb *tcp_active_pcbs;  /* List of all TCP PCBs that are in a
/***********************************************************************
函数名称:Check_TCP_Connect(void)
功    能:检查连接
输入参数:
输出参数:
编写时间:2013.4.25
编 写 人:
注    意:for(cpcb = tcp_active_pcbs;cpcb != NULL; cpcb = cpcb->next) 
***********************************************************************/\
struct tcp_pcb *Check_TCP_Connect(void)
{
	struct tcp_pcb *cpcb = 0;
	connect_flag = 0;
	for(cpcb = tcp_active_pcbs;cpcb != NULL; cpcb = cpcb->next)
	{
	//	if(cpcb->local_port == TCP_LOCAL_PORT && cpcb->remote_port == TCP_SERVER_PORT)		//如果TCP_LOCAL_PORT端口指定的连接没有断开
		if(cpcb -> state == ESTABLISHED)  //如果得到应答,则证明已经连接上
		{
			connect_flag = 1;  						//连接标志
			break;							   	
		}
	}

	if(connect_flag == 0)  	// TCP_LOCAL_PORT指定的端口未连接或已断开
	{
		TCP_Client_Init(TCP_LOCAL_PORT,TCP_SERVER_PORT,TCP_SERVER_IP); //重新连接
		cpcb = 0;
	}
	return cpcb;	
}
/***********************************************************************
函数名称:err_t RS232_TCP_Connected(void *arg,struct tcp_pcb *pcb,err_t err)
功    能:完成RS232到TCP的数据发送
输入参数:
输出参数:
编写时间:2013.4.25
编 写 人:
注    意:这是一个回调函数,当TCP客户端请求的连接建立时被调用
***********************************************************************/
err_t TCP_Connected(void *arg,struct tcp_pcb *pcb,err_t err)
{
	//tcp_client_pcb = pcb;
	return ERR_OK;
}
/***********************************************************************
函数名称:TCP_Client_Recv(void *arg, struct tcp_pcb *pcb,struct pbuf *p,err_t err)
功    能:tcp客户端接收数据回调函数
输入参数:
输出参数:
编写时间:2013.4.25
编 写 人:
注    意:这是一个回调函数,当TCP服务器发来数据时调用
***********************************************************************/

err_t  TCP_Client_Recv(void *arg, struct tcp_pcb *pcb,struct pbuf *p,err_t err)
{
	struct pbuf *p_temp = p;
	
	if(p_temp != NULL)
	{	
		tcp_recved(pcb, p_temp->tot_len);//获取数据长度 tot_len:tcp数据块的长度
		while(p_temp != NULL)	
		{				
			/******将数据原样返回*******************/
			tcp_write(pcb,p_temp->payload,p_temp->len,TCP_WRITE_FLAG_COPY); 	// payload为TCP数据块的起始位置       
			tcp_output(pcb);
			p_temp = p_temp->next;
		}		
	}
	else
	{
		tcp_close(pcb); 											/* 作为TCP服务器不应主动关闭这个连接? */
	}
	/* 释放该TCP段 */
	pbuf_free(p); 	
	err = ERR_OK;
	return err;
}
/***********************************************************************
函数名称:TCP_Client_Init(u16_t local_port,u16_t remote_port,unsigned char a,unsigned char b,unsigned char c,unsigned char d)
功    能:tcp客户端初始化
输入参数:local_port本地端口号;remote_port:目标端口号;a,b,c,d:服务器ip
输出参数:
编写时间:2013.4.25
编 写 人:
注    意:
***********************************************************************/
void TCP_Client_Init(u16_t local_port,u16_t remote_port,unsigned char a,unsigned char b,unsigned char c,unsigned char d)
{

	 ip4_addr_t ipaddr,LocalAddress;
	err_t err;
	IP4_ADDR(&ipaddr,a,b,c,d);           //服务器IP地址
	tcp_client_pcb = tcp_new(); /* 建立通信的TCP控制块(Clipcb) */
	if (!tcp_client_pcb)
	{
		return ;
	}	

//IP4_ADDR(&LocalAddress,192,168,10,11);           //服务器IP地址	
	err = tcp_bind(tcp_client_pcb,IP_ADDR_ANY,local_port); /* 绑定本地IP地址和端口号 ,本地ip地址在LwIP_Init()中已经初始化*/
	if(err != ERR_OK)
	{
		return ;
	}    
	tcp_connect(tcp_client_pcb,&ipaddr,remote_port,TCP_Connected);//注册回调函数
	tcp_recv(tcp_client_pcb,TCP_Client_Recv); 				/* 设置tcp接收回调函数 */
}

	unsigned char tcp_data[] = "tcp 客户端实验!\n";
	struct tcp_pcb *pcb;
void StartDefaultTask(void const * argument)
{
  /* init code for LWIP */
  MX_LWIP_Init();
	/* Infinite loop */
	TCP_Client_Init(TCP_LOCAL_PORT,TCP_SERVER_PORT,TCP_SERVER_IP); //tcp客户端初始化

  
  /* USER CODE BEGIN StartDefaultTask */
  /* Infinite loop */
  for(;;)
  {
    osDelay(1000);
		HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_13|GPIO_PIN_14);
		pcb = Check_TCP_Connect();
		if(pcb != 0)
		{	
			TCP_Client_Send_Data(pcb,tcp_data,sizeof(tcp_data));	//该函数为主动向服务器发送函数,
		}

		/* handle periodic timers for LwIP */
	//	LwIP_Periodic_Handle(LocalTime);
  }
  /* USER CODE END StartDefaultTask */
}

实验效果:

禁用无线,启动以太网,打开TCP调试助手,配置为服务器监听模式,监听端口8888,板子上电不久,在TCP调试助手上就能看到192.168.1.12的IP地址的板子连接上来,并发送数据。
在这里插入图片描述

七.CubeMX工程源代码下载

通过网盘分享的文件:30.LAN8720以太网通讯实验.zip
链接: https://pan.baidu.com/s/1FIXLazqFihbv-RX8pACLMA 提取码: i6pm
如果链接失效,可以联系博主给最新链接
程序下载下来之后解压就行

八.小结

STM32F407开发板加上LAN8720模块可以通过网络连接,实现远程控制、数据传输等功能。

STM32F407单片机设计以太网接口数据采集板AD硬件原理图+PCB+封装库文件,2层板设计,大小为100*100mm,包括完整的原理图和PCB及封装库文件,可以做为你的设计参考。 主要器件型号如下: Library Component Count : 36 Name Description ---------------------------------------------------------------------------------------------------- CAP NP CAP NP_2_Dup1 CAP NP_Dup2 CAP,MLCC,10uF,+/-10%,X5R,6.3V,SMD0805 CRYSTAL_1 CRYSTAL_2 Cap 无极性电容 Cap Pol 极性电解电容 DS Surface mount schottky diode SOD-323(0805) Package DS1128-09-S8B8X Diode 二极管 FET P MOS HFD4/12-S 双路继电器 Header 2 Header, 2-Pin Header 2X2 Header, 2-Pin, Dual row Header 9 Header, 9-Pin Inductor 电感 LED0 Typical INFRARED GaAs LED MAX485 NPN-S9014-贴片 NPN-S9014-贴片 RES-2 RESISTOR RESISTOR_1 RES,thick film,47KOhm,+/-5%,1/16W,SMD0402 RESISTOR_Dup2 通用厚膜电阻,75K,+/-1%,R0402,1/16W. Res 贴片电阻 1% Res1 Resistor Res2 Resistor Res3 Resistor TLP281 TLV62569DBVR dc-dc可调电源 TRANSMITOR100 T_FLASH_A XL1509 dp83620_1 stm32f4xxz1_0 绿色端子6P 贴片按键 封装库列表: Component Count : 58 Component Name ----------------------------------------------- 1N4001-M1二极管 2.2uH 贴片电感 10uF贴片电解电容50V 0603A 0603a - duplicate 0603LED 1210 1808贴片电容 3225晶振 BAT54C BATTERY CAN_2 dp83620以太网芯片 EC20 HDR1X2 HDR1X4 HDR1X5 HDR2X2 HDR2X4_CEN HDR2X5 HDR2X9 HDR2X10 HR911105A key_3 keya LED3528 m35768 MC29302 MICRO_USB microSIMauto MICROUSB PCBComponent_1 PCBComponent_1 - duplicate PCBComponent_1 - duplicate1 QFN24 QFP144 RJ45插孔 RTL8201F s8550 SDCARD SIP4 SMB SMB_L4.6-W3.6-LS5.3-RD SO-8 SOT-23-5 SOT223 SSOP-20 TLP281 TSOP44 TVS58Y W25Q16 xtal YINPIN 轻触开关6*6*4.5 贴片磁珠0603 贴片电阻1812 整流桥ABS210 整流桥HD01
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值