前言:需要了解的知识点有W5500,SPI,socket套接字流程,TCP/IP
我是通过给的源码来分析知识点的,这样子感觉目标明确一点,模块是在某宝买的,大概15块左右。
(之前用的是另一个模组串口转以太网的,但是不方便的地方就是不能通过屏幕的方式直接修改ip,或者是模式,而且在速度上因为串口转以太网模组要经过一个mcu,速度上比不过spi,所以就有了这篇博文)
先从寄存器和内存构成开始梳理
W5500有1个通用寄存器,8个Socket寄存器区,以及对应每个Socket的收/发缓存区。(每个区域均通过SPI数据帧的区域选择位BSB[4:0]来选取),下图显示了区域选择位选择的区域以及收/发缓存区可用的偏移地址范围。每个Socket的发送缓存区都在一个16KB的物理发送内存中,初始化分配为2KB。每个Socket的接收缓存区都在一个16KB的物理接收内存中,初始化分配为2KB,无论给每个 Socket 分配多大的收/ 发缓存,都必须在 16 位的偏移地址范围内(从0×0000 到 0xFFFF)。
W5500有一个16KB的发送内存用于Socket的发送缓存,以及一个16KB的接收内存用于Socket的接收缓存区。16KB的发送内存初始化被分配为每个2KB的发送缓存区。初 始化分配的 2KB Socket 发送缓存 , 可以通过使用 Socket 发送缓存大小寄存器(Sn_TXBUF_SIZE)重新分配。(具体介绍看下面Socket端口寄存器介绍)
16KB 的读取内存的分派方式与 16KB 的发送内存一样。 16KB 的接收内存初始化被分配 为每个Socket 2KB 接收缓存区(2KB X 8 = 16KB)。初始化分配的 2KB Socket 接收缓存,可 以通过使用Socket 接收缓存大小寄存器(Sn_XBUF_SIZE)重新分配。
。。。。。。。。。(太多了还是看手册吧)
下面介绍通用寄存器的一小部分。
2. GAR (网关 IP 地址寄存器)
(子网掩码,源IP,MAC都是差不多的)
7. IR(中断寄存器)
中断寄存器(IR)指明了中断的状态。 IR 的每一位都是‘0’,直到被主机写为‘1’.如果 IR 不等于‘0×00’, INTn 引脚将会被拉低。直到其变为‘0×00’时, INTn 才会被 拉高
8. IMR (中断屏蔽寄存器) [R/W][0x0016][0x00]
中断屏蔽寄存器(IMR)用来屏蔽中断源。每个中断屏蔽位对应中断寄存器(IR)中的 一个位。如果中断屏蔽位被置“1”时,无论何时 IR 对应的位也置”1”,中断即会产生。换而言之, 当 IMR 中屏蔽位被清“0”。即使对应的 IR 中断位置“1”,也不会产生中断。
(建议去看手册,实在是太长了,不然我就要抄书了)
12. Sn_RXBUF_SIZE(Socket n 接收缓存大小寄存器) [R/W] [0x001E] [0x02]
Sn_RXBUF_SIZE 配置了 Socket n 的接收缓存大小。 Socket n 接收缓存区大小可以配置 为 1, 2,
4, 8 和 16Kbytes。如果配置为其他大小,则 W5500 不能正常的从对方主机接 收数据。即使 Socket n 的 接收 缓存 大 小初始 默认为 2Kbytes 。 用户仍 然可 以 使用Sn_RXBUF_SIZE 重新定义。但是所有 Socket 接收缓存(Sn_RXBUF_SIZE)的总大小不能 超过16Kbytes。否则,将会使得接收异常。当 所 有 的 Sn_RXBUF_SIZE 配 置 完 成 后 , 就 会 按 照 Socket 0 到 7 的 顺 序 依 次将16Kbytes 的接收内存分配给各个 Socket 作为接收缓存使用。不论 Socket n 的接收缓存配置的大小如何,都可以被 16 位的偏移地址寻址找到。(寻 址范围:0×0000 到 0xFFFF)
例子:Socket 0 RX Buffer Size = 8KB
13. Sn_TXBUF_SIZE (Socket n 发送缓存大小寄存器) [R/W] [0x001F] [0x02]
与接收缓存大小寄存器同理
15. Sn_TX_RD (Socket n 发送读指针寄存器) [R] [0x0022-0x0023] [0x0000]
Sn_TX_RD 寄存器可以通过 OPEN 配置命令进行初始化。
如果是TCP模式,该寄存器将会在TCP连接期间,重新进行初始化。该寄存器初始化之后,会根据SEND配置命令自增。SEND配置命令传输的是Socket n发送缓存中,当前Sn_TX_RD到Sn_TX_WR之间保存的数据。在传输完保存的数据之后。SEND配置命令会使得Sn_TX_RD等于Sn_TX_WR。
16. Sn_TX_WR (Socket n 发送写指针寄存器) [R/W] [0x0024-0x0025] [0x0000]
Sn_TX_WD寄存器可以通过OPEN配置命令进行初始化。
在TCP模式下该寄存器会在TCP连接期间重新初始化。该寄存器需要读取或者更新如下:
18. Sn_RX_RD (Socket n 接收读指针寄存器) [R/W] [0x0028-0x0029] [0x0000]
Sn_RX_RD寄存器可以通过OPEN配置命令进行初始化。请确保该寄存器按照以下步骤读取并更新:
19. Sn_RX_WR (Socket n 接收写指针寄存器) [R] [0x002A-0x002B] [0x0000]
Sn_RX_WR 寄存器可以通过 OPEN 配置命令进行初始化。并且随着数据接收自动增加。 如果
Sn_RX_WR 的值增长到超过最大值 0xFFFF(即超过 0×10000 并产生进位) ,那么
将自动忽略进位,并自动更新为低 16 位的值。
W5500提供了SPI(串行外部接口)作为外设主机接口,共有SCSn,SCLK,MOSI,MISO 4路信号。
W5500与MCU的连接方式如下图,由于主要有两种工作模式,所以连接方式上也有点差异
SPI协议定义了四种工作模式。每种模式的区别就是根据SCLK的极性及相位的不同定义的。
W5500支持SPI模式0及模式3 MOSI 和 MISO 信号无论是接收或发送,均遵从从最高标志位(MSB)到最低标志位(LSB)的传输序列
W5500与外设主机通信受到SPI数据帧控制
W5500的帧分为3段:地址段,控制段,数据段
地址段:为W5500寄存器或TX/RX内存指定了16位的偏移地址。SPI 数据帧的数据段(2/4/N 字节)通过偏移地址自增(每传输 1 字节偏移地址加 1) 支持连续数据读/写
控制段:指定了地址段设定的偏移区域的归属,读写访问模式以及SPI工作模式(可变长度模式/固定长度模式)
BSB[4:0]:区域选择位
RWB:读/写访问模式 0:读 1:写
OM[1:0]:SPI工作模式
数据段:可以设定为任意长度(N-字节, 1≤N)或者是固定的长度: 1 字节, 2 字节 或 4 字节;如果SPI 工作模式设置为可变数据长度模式(VDM), SPI 的 SCSn 信号需要由外部 主机通过 SPI 帧控制
在可变数据长度模式下,SCSn控制SPI帧的开始和停止
SCSn 信号拉低(高电平到低电平),即代表 W5500 的 SPI 帧开始(地址段);
SCSn 信号拉高(低电平到高电平),即代表 W5500 的 SPI 帧结束(数据段的随机 N 字节数据结尾);
#ifndef _W5500_H_
#define _W5500_H_
/***************** Common Register *****************/
#define MR 0x0000
#define RST 0x80 /*1:内部寄存器将被初始化置位*/
#define WOL 0x20 /*0:关闭网络唤醒 1:开启网络唤醒*/
#define PB 0x10 /*0:关闭ping 1:开启ping*/
#define PPP 0x08 /*0:关闭PPPoE 1:开启PPPoE*/
#define FARP 0x02 /*0:关闭强迫ARP模式 1:开启强迫ARP模式*/
#define GAR 0x0001 /*网关IP地址寄存器,占用4字节*/
#define SUBR 0x0005 /*子网掩码寄存器*/
#define SHAR 0x0009 /*源MAC地址寄存器*/
#define SIPR 0x000f /*源IP地址寄存器*/
#define INTLEVEL 0x0013 /*低电平中断定时器寄存器*/
#define IR 0x0015 /*中断寄存器*/
#define CONFLICT 0x80 /*IP冲突:在收到ARP请求时,发现发送方IP与本地IP冲突,该位被置1*/
#define UNREACH 0x40 /*ICMP目标不可达,该位被置1*/
#define PPPOE 0x20 /*PPPoE连接关闭,PPPoE模式下连接断开,该位生效*/
#define MP 0x10 /*当网络唤醒模式启用并通过UDP接收到网络唤醒包时,该位生效*/
#define IMR 0x0016 /*中断屏蔽寄存器 0:关闭 1:开启*/
#define IM_IR7 0x80 /*IP冲突中断屏蔽*/
#define IM_IR6 0x40 /*目的地址不能抵达中断屏蔽*/
#define IM_IR5 0x20 /*PPPoE关闭中断屏蔽*/
#define IM_IR4 0x10 /*Magic Packet中断屏蔽*/
#define SIR 0x0017 /*Socket 中断寄存器*/
#define S7_INT 0x80
#define S6_INT 0x40
#define S5_INT 0x20
#define S4_INT 0x10
#define S3_INT 0x08
#define S2_INT 0x04
#define S1_INT 0x02
#define S0_INT 0x01
#define SIMR 0x0018 /*Socket 中断屏蔽寄存器*/
#define S7_IMR 0x80 /*与SIR相对应,SIMR 为‘1’,SIR的对应位为‘1’时,中断将被触发*/
#define S6_IMR 0x40 /*SIMR的一位为‘0’,那么即使 SIR 对应 位为’1’,中断将不会被触发*/
#define S5_IMR 0x20
#define S4_IMR 0x10
#define S3_IMR 0x08
#define S2_IMR 0x04
#define S1_IMR 0x02
#define S0_IMR 0x01
#define RTR 0x0019 /*重试时间值寄存器*/
#define RCR 0x001b /*重试计数寄存器*/
#define PTIMER 0x001c /*PPP 连接控制协议请求定时寄存器*/
#define PMAGIC 0x001d /*PPP 连接控制协议幻数寄存器*/
#define PHA 0x001e /*PPPoE 模式下目标 MAC 寄存器*/
#define PSID 0x0024 /*PPPoE 模式下会话 ID 寄存器*/
#define PMRU 0x0026 /*PPPoE 模式下最大接收单元*/
#define UIPR 0x0028 /*无法抵达 IP 地址寄存器*/
#define UPORT 0x002c /*无法抵达端口寄存器*/
#define PHYCFGR 0x002e /*W5500 PHY 配置寄存器*/
#define RST_PHY 0x80 /*当该位为0时,内部PHY重启*/
#define OPMODE 0x40 /*配置PHY工作模式*/
#define DPX 0x04 /*工作模式配置位*/
#define SPD 0x02 /*双工模式配置位*/
#define LINK 0x01 /*速度状态*/
#define VERR 0x0039 /*W5500 芯片版本寄存器*/
/********************* Socket Register *******************/
#define Sn_MR 0x0000 /*Socket n 模式寄存器*/
#define MULTI_MFEN 0x80 /*UDP多播模式 0:关闭多播 1:开启多播 在MACRAW模式下开启MAC地址过滤0:关闭 1:开启*/
#define BCASTB 0x40 /*MACRAW和UDP模式下的网络阻塞 0:关闭广播阻塞 1:开启广播阻塞*/
#define ND_MC_MMB 0x20 /*使用无延时ACK 0:关闭 1:开启......*/
#define UCASTB_MIP6B 0x10
#define MR_CLOSE 0x00
#define MR_TCP 0x01 /*协议*/
#define MR_UDP 0x02
#define MR_MACRAW 0x04
#define Sn_CR 0x0001 /*Socket n 配置寄存器*/
#define OPEN 0x01 /*0001 TCP 0010 UDP*/
#define LISTEN 0x02
#define CONNECT 0x04
#define DISCON 0x08
#define CLOSE 0x10
#define SEND 0x20
#define SEND_MAC 0x21
#define SEND_KEEP 0x22
#define RECV 0x40
#define Sn_IR 0x0002 /*(Socket n 中断寄存器*/
#define IR_SEND_OK 0x10
#define IR_TIMEOUT 0x08
#define IR_RECV 0x04
#define IR_DISCON 0x02
#define IR_CON 0x01
#define Sn_SR 0x0003 /*Socket n 状态寄存器*/
#define SOCK_CLOSED 0x00
#define SOCK_INIT 0x13
#define SOCK_LISTEN 0x14
#define SOCK_ESTABLISHED 0x17
#define SOCK_CLOSE_WAIT 0x1c
#define SOCK_UDP 0x22
#define SOCK_MACRAW 0x02
#define SOCK_SYNSEND 0x15
#define SOCK_SYNRECV 0x16
#define SOCK_FIN_WAI 0x18
#define SOCK_CLOSING 0x1a
#define SOCK_TIME_WAIT 0x1b
#define SOCK_LAST_ACK 0x1d
#define Sn_PORT 0x0004 /*Socket n 源端口寄存器*/
#define Sn_DHAR 0x0006 /*Socket n 目的 MAC 地址寄存器*/
#define Sn_DIPR 0x000c /*Socket 目标 IP 地址寄存器*/
#define Sn_DPORTR 0x0010 /*Socket n 目标端口寄存器*/
#define Sn_MSSR 0x0012 /*Socket n-th 最大分段寄存器*/
#define Sn_TOS 0x0015 /*Socket IP 服务类型寄存器*/
#define Sn_TTL 0x0016 /*Socket IP 生存时间寄存器*/
#define Sn_RXBUF_SIZE 0x001e /*Socket n 发送缓存大小寄存器*/
#define Sn_TXBUF_SIZE 0x001f
#define Sn_TX_FSR 0x0020 /*Socket n 空闲发送缓存寄存器*/
#define Sn_TX_RD 0x0022 /*Socket n 发送读指针寄存器*/
#define Sn_TX_WR 0x0024 /*Socket n 发送写指针寄存器*/
#define Sn_RX_RSR 0x0026 /*Socket n 空闲接收缓存寄存器*/
#define Sn_RX_RD 0x0028 /*Socket n 接收读指针寄存器*/
#define Sn_RX_WR 0x002a /*Socket n 接收写指针寄存器*/
#define Sn_IMR 0x002c /*Socket n 中断屏蔽寄存器*/
#define IMR_SENDOK 0x10
#define IMR_TIMEOUT 0x08
#define IMR_RECV 0x04
#define IMR_DISCON 0x02
#define IMR_CON 0x01
#define Sn_FRAG 0x002d /*Socket n 分段寄存器*/
#define Sn_KPALVTR 0x002f /*Socket 在线时间寄存器*/
/*******************************************************************/
/************************ SPI Control Byte *************************/
/*******************************************************************/
/* Operation mode bits */
#define VDM 0x00
#define FDM1 0x01
#define FDM2 0x02
#define FDM4 0x03
/* Read_Write control bit */
#define RWB_READ 0x00
#define RWB_WRITE 0x04
/* Block select bits */
#define COMMON_R 0x00
/* Socket 0 */
#define S0_REG 0x08
#define S0_TX_BUF 0x10
#define S0_RX_BUF 0x18
/* Socket 1 */
#define S1_REG 0x28
#define S1_TX_BUF 0x30
#define S1_RX_BUF 0x38
/* Socket 2 */
#define S2_REG 0x48
#define S2_TX_BUF 0x50
#define S2_RX_BUF 0x58
/* Socket 3 */
#define S3_REG 0x68
#define S3_TX_BUF 0x70
#define S3_RX_BUF 0x78
/* Socket 4 */
#define S4_REG 0x88
#define S4_TX_BUF 0x90
#define S4_RX_BUF 0x98
/* Socket 5 */
#define S5_REG 0xa8
#define S5_TX_BUF 0xb0
#define S5_RX_BUF 0xb8
/* Socket 6 */
#define S6_REG 0xc8
#define S6_TX_BUF 0xd0
#define S6_RX_BUF 0xd8
/* Socket 7 */
#define S7_REG 0xe8
#define S7_TX_BUF 0xf0
#define S7_RX_BUF 0xf8
#define TRUE 0xff
#define FALSE 0x00
#define S_RX_SIZE 2048 /*定义Socket接收缓冲区的大小,可以根据W5500_RMSR的设置修改 */
#define S_TX_SIZE 2048 /*定义Socket发送缓冲区的大小,可以根据W5500_TMSR的设置修改 */
/***************----- W5500 GPIO定义 -----***************/
#define W5500_SCS GPIO_Pin_4 //定义W5500的CS引脚
#define W5500_SCS_PORT GPIOA
#define W5500_RST GPIO_Pin_5 //定义W5500的RST引脚
#define W5500_RST_PORT GPIOC
#define W5500_INT GPIO_Pin_4 //定义W5500的INT引脚
#define W5500_INT_PORT GPIOC
/***************----- 网络参数变量定义 -----***************/
extern unsigned char Gateway_IP[4]; //网关IP地址
extern unsigned char Sub_Mask[4]; //子网掩码
extern unsigned char Phy_Addr[6]; //物理地址(MAC)
extern unsigned char IP_Addr[4]; //本机IP地址
extern unsigned char S0_Port[2]; //端口0的端口号(5000)
extern unsigned char S0_DIP[4]; //端口0目的IP地址
extern unsigned char S0_DPort[2]; //端口0目的端口号(6000)
extern unsigned char UDP_DIPR[4]; //UDP(广播)模式,目的主机IP地址
extern unsigned char UDP_DPORT[2]; //UDP(广播)模式,目的主机端口号
/***************----- 端口的运行模式 -----***************/
extern unsigned char S0_Mode; //端口0的运行模式,0:TCP服务器模式,1:TCP客户端模式,2:UDP(广播)模式
#define TCP_SERVER 0x00 //TCP服务器模式
#define TCP_CLIENT 0x01 //TCP客户端模式
#define UDP_MODE 0x02 //UDP(广播)模式
/***************----- 端口的运行状态 -----***************/
extern unsigned char S0_State; //端口0状态记录,1:端口完成初始化,2端口完成连接(可以正常传输数据)
#define S_INIT 0x01 //端口完成初始化
#define S_CONN 0x02 //端口完成连接,可以正常传输数据
/***************----- 端口收发数据的状态 -----***************/
extern unsigned char S0_Data; //端口0接收和发送数据的状态,1:端口接收到数据,2:端口发送数据完成
#define S_RECEIVE 0x01 //端口接收到一个数据包
#define S_TRANSMITOK 0x02 //端口发送一个数据包完成
/***************----- 端口数据缓冲区 -----***************/
extern unsigned char Rx_Buffer[2048]; //端口接收数据缓冲区
extern unsigned char Tx_Buffer[2048]; //端口发送数据缓冲区
extern unsigned char W5500_Interrupt; //W5500中断标志(0:无中断,1:有中断)
typedef unsigned char SOCKET; //自定义端口号数据类型
extern void Delay(unsigned int d); //延时函数(ms)
extern void W5500_GPIO_Configuration(void); //W5500 GPIO初始化配置
extern void W5500_NVIC_Configuration(void); //W5500 接收引脚中断优先级设置
extern void SPI_Configuration(void); //W5500 SPI初始化配置(STM32 SPI1)
extern void W5500_Hardware_Reset(void); //硬件复位W5500
extern void W5500_Init(void); //初始化W5500寄存器函数
extern unsigned char Detect_Gateway(void); //检查网关服务器
extern void Socket_Init(SOCKET s); //指定Socket(0~7)初始化
extern unsigned char Socket_Connect(SOCKET s); //设置指定Socket(0~7)为客户端与远程服务器连接
extern unsigned char Socket_Listen(SOCKET s); //设置指定Socket(0~7)作为服务器等待远程主机的连接
extern unsigned char Socket_UDP(SOCKET s); //设置指定Socket(0~7)为UDP模式
extern unsigned short Read_SOCK_Data_Buffer(SOCKET s, unsigned char *dat_ptr);//指定Socket(0~7)接收数据处理
extern void Write_SOCK_Data_Buffer(SOCKET s, unsigned char *dat_ptr, unsigned short size); //指定Socket(0~7)发送数据处理
extern void W5500_Interrupt_Process(void); //W5500中断处理程序框架
#endif