一、W5500几个常用寄存器介绍
1. 本地网络信息配置寄存器
- GAR (网关 IP 地址寄存器):该寄存器用来设置默认网关地址。如:“192.168.0.1”
- SUBR (子网掩码寄存器):该寄存器用来设置子网掩码地址。如:“255.255.255.0”
- SHAR (源 MAC 地址寄存器):该寄存器用来设置源 MAC 地址。如:“00.08.DC.01.02.03”
- SIPR (源 IP 地址寄存器):该寄存器用来设置源 IP 地址。如:“192.168.0.2”
#define GAR0 (0x000100)
#define GAR1 (0x000200)
#define GAR2 (0x000300)
#define GAR3 (0x000400)
#define SUBR0 (0x000500)
#define SUBR1 (0x000600)
#define SUBR2 (0x000700)
#define SUBR3 (0x000800)
#define SHAR0 (0x000900)
#define SHAR1 (0x000A00)
#define SHAR2 (0x000B00)
#define SHAR3 (0x000C00)
#define SHAR4 (0x000D00)
#define SHAR5 (0x000E00)
#define SIPR0 (0x000F00)
#define SIPR1 (0x001000)
#define SIPR2 (0x001100)
#define SIPR3 (0x001200)
2. Socket 端口寄存器
- Sn_MR(Socket n 模式寄存器):该寄存器用于配置所有 SOCKET 的选项或协议类型。
#define Sn_MR_CLOSE 0x00
#define Sn_MR_TCP 0x01
#define Sn_MR_UDP 0x02
#define Sn_MR_IPRAW 0x03
#define Sn_MR_MACRAW 0x04
#define Sn_MR_PPPOE 0x05
#define Sn_MR_UCASTB 0x10
#define Sn_MR_ND 0x20
#define Sn_MR_MC 0x20
#define Sn_MR_BCASTB 0x40
#define Sn_MR_MULTI 0x80
- Sn_CR (Socket n 配置寄存器):该寄存器用于设置 Socket n 的配置命令如 OPEN 、CLOSE、CONNECT、LISTEN、END 和 RECEIVE。
#define Sn_CR_OPEN 0x01
#define Sn_CR_LISTEN 0x02
#define Sn_CR_CONNECT 0x04
#define Sn_CR_DISCON 0x08
#define Sn_CR_CLOSE 0x10
#define Sn_CR_SEND 0x20
#define Sn_CR_SEND_MAC 0x21
#define Sn_CR_SEND_KEEP 0x22
#define Sn_CR_RECV 0x40
- Sn_SR (Socket n 状态寄存器):Sn_SR 指示了 Socket n 的状态,并根据 Sn_CR 或者一些 TCP 模式下的特殊控制包,如 SYN,FIN 包而改变。
#define SOCK_CLOSED 0x00
#define SOCK_INIT 0x13
#define SOCK_LISTEN 0x14
#define SOCK_SYNSENT 0x15
#define SOCK_SYNRECV 0x16
#define SOCK_ESTABLISHED 0x17
#define SOCK_FIN_WAIT 0x18
#define SOCK_CLOSING 0x1A
#define SOCK_TIME_WAIT 0x1B
#define SOCK_CLOSE_WAIT 0x1C
#define SOCK_LAST_ACK 0x1D
#define SOCK_UDP 0x22
#define SOCK_IPRAW 0x32
#define SOCK_MACRAW 0x42
#define SOCK_PPPOE 0x5F
- Sn_PORT (Socket n 源端口寄存器):该寄存器配置了 Socket n 的源端口号。当 Socket n 工作在 TCP 或 UDP 模式下,该寄存器生效。
#define Sn_PORT0(ch) (0x000408 + (ch<<5))
#define Sn_PORT1(ch) (0x000508 + (ch<<5))
- Sn_DIPR (Socket 目标 IP 地址寄存器):Sn_DIPR 配置或指示的为 Socket n 的目标主机 IP 地址,在 TCP/UDP 模式下生效。
- Sn_DPORT (Socket n 目标端口寄存器):Sn_DPORT 配置或指示了 Socket n 的目标主机端口号,在 TCP/UDP 模式下生效。
二、TCP客户端的实现
1.实现功能
- 实现一个TCP客户端,发起跟服务器的TCP连接请求,连接成功后先向服务器发送数据,然后接收服务器回发的数据之后通过串口打印。
2.实现思路
- 在编写TCP客户端应用程序时,可以通过查询socket状态寄存器(Sn_SR)的状态来实现TCP连接。
3.实现代码
void W5500_SetNetwork(void)
{
uint8_t ip[4];
W5500_GPIO_Configuration();
W5500_NVIC_Configuration();
Reset_W5500();
W5500_SPI_Init();
setSHAR(MAC);
setSUBR(Mask);
setGAR(Gateway);
setSIPR(Local_IP);
sysinit(txsize, rxsize);
setRTR(2000);
setRCR(3);
getSIPR (ip);
printf("IP : %d.%d.%d.%d\r\n", ip[0],ip[1],ip[2],ip[3]);
getSUBR(ip);
printf("SN : %d.%d.%d.%d\r\n", ip[0],ip[1],ip[2],ip[3]);
getGAR(ip);
printf("GW : %d.%d.%d.%d\r\n", ip[0],ip[1],ip[2],ip[3]);
}
uint16_t local_port = 5000;
uint8_t recv_buf[2080];
uint8_t send_buf[2080];
void TCP_Client(uint8_t sn, uint8_t *server_ip, uint8_t server_port)
{
uint8_t recv_len;
switch(getSn_SR(sn))
{
case SOCK_CLOSED:
printf("- TCP Client Start!\r\n");
socket(sn, Sn_MR_TCP, local_port, Sn_MR_ND);
printf("- Socket %d open success.", sn);
break;
case SOCK_INIT:
printf("- Try to connect %d.%d.%d.%d:%d...\r\n",
server_ip[0], server_ip[1], server_ip[2], server_ip[3], server_port);
connect(sn, server_ip, server_port);
break;
case SOCK_ESTABLISHED:
if(getSn_IR(sn) & Sn_IR_CON)
{
printf("- Socket %d:Connected to - %d.%d.%d.%d : %d\r\n",
sn, server_ip[0], server_ip[1], server_ip[2], server_ip[3], server_port);
setSn_IR(sn, Sn_IR_CON);
}
recv_len = getSn_RX_RSR(sn);
if(recv_len > 0)
{
recv(sn, recv_buf, recv_len);
printf("- Socket[%d]: Recv data: [%s]\r\n", sn, recv_buf);
}
strcpy((char*)send_buf, "Hello, Server!");
send(sn, send_buf, strlen((char*)send_buf));
printf("- Socket[%d]: Send data: [%s]\r\n", sn, send_buf);
break;
case SOCK_CLOSE_WAIT:
close(sn);
break;
}
}
uint8_t server_ip[4] = {192, 168, 1, 121};
uint16_t server_port = 8080;
- 在main()函数while(1)循环中调用
TCP_Client
int main()
{
W5500_SetNetwork();
...
while(1)
{
TCP_Client(0, server_ip, server_port);
}
...
}
4.验证结果
- 串口助手打印结果
- 在网络调试助手建立TCP服务器,端口8080
#include <stdio.h>
#pragma import(__use_no_semihosting)
void _sys_exit(int x)
{
x = x;
}
struct __FILE
{
int handle;
};
FILE __stdout;
int fputc(int ch, FILE *stream)
{
while((USART1->SR & 0X40) == 0);
USART1->DR = (uint8_t) ch;
return ch;
}
5.常见问题
- 串口打印没有输出(print重定向问题)
- 串口输出有数据,就是连接不上服务器(本地网络配置没有初始化)
- 测试时需用网线交叉线(一端568A,一端568B)将开发板与电脑互连
|