IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> W5500以太网控制器芯片(二):ioLibrary库实现TCP客户端 -> 正文阅读

[网络协议]W5500以太网控制器芯片(二):ioLibrary库实现TCP客户端

#W5500以太网控制芯片相关文章链接#

上一篇文章:W5500以太网控制器芯片(一):ioLibrary库实现TCP服务器
?

前面已经通过移植官方的ioLibrary库实现了TCP回环测试(W5500做tcp服务器),下面我们来实现W5500做TCP客户端,连接远程的TCP服务器。

准备工具:

a、电脑上装一个网络调试工具,做TCP服务器用

b、一个路由器,后面电脑和W5500都要接到路由器上

c、W5500+支持SPI接口的MCU或者SOC

d、官方的ioLibrary库文件(上一篇文章中说明了下载方式)


1、移植驱动

基本TCP客户端测试依旧不需要引入其他驱动,只要W5500的基本驱动即可,即前一篇文章的W5500、socket、wizchip_config的c和h文件引入工程中即可,与TCP服务器的引入方式一致

2、SPI接口初始化

与TCP服务器的也完全一致,直接参照前一篇文章即可,分别实现以下3类接口:
(1)SPI读写
(2)进入、退出临界区
(3)片选信号输出

3、实现TCP客户端

(1)网络初始化:参照上一篇文章,包括network_init,以及上面几个SPI接口函数的注册
?

    delay_init();	    	 	//延时函数初始化
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2

	uart_init(115200);	 	//串口初始化
		
	LED_Init();
 
	SPI2_Init();            //初始化SPI

	// First of all, Should register SPI callback functions implemented by user for accessing WIZCHIP 
	/* Critical section callback */
	//reg_wizchip_cris_cbfunc(SPI_CrisEnter, SPI_CrisExit);	//注册临界区函数
	reg_wizchip_cris_cbfunc(NULL, NULL); // 注册临界区函数
		
	reg_wizchip_cs_cbfunc(SPI_CS_Select, SPI_CS_Deselect);// 注册片选函数

	/* SPI Read & Write callback function */
	reg_wizchip_spi_cbfunc(SPI_ReadByte, SPI_WriteByte);	//注册读写函数
 
	/* WIZCHIP SOCKET Buffer initialize */
	if(ctlwizchip(CW_INIT_WIZCHIP,(void*)memsize) == -1){
		 printf("WIZCHIP Initialized fail.\r\n");
		 while(1);
	}

	/* PHY link status check */
	do{
		 if(ctlwizchip(CW_GET_PHYLINK, (void*)&tmp) == -1){
				printf("Unknown PHY Link stauts.\r\n");
		 }
	}while(tmp == PHY_LINK_OFF);
	
	/* Network initialization */
	network_init();

(2)定义一下要连接的服务器的IP和端口

uint8_t dest_ip[4] = {10, 1, 1, 144};
uint16_t dest_port = 	5000;

(3)TCP客户端事件处理函数实现

/**
  * @brief  TCP客户端事件处理函数
  */
int32_t loopback_tcpc(uint8_t sn, uint8_t* buf, uint8_t* destip, uint16_t destport)
{
   int32_t ret; // return value for SOCK_ERRORs
   uint16_t size = 0, sentsize=0;

   // Port number for TCP client (will be increased)
   uint16_t any_port = 	5000;

   // Socket Status Transitions
   // Check the W5500 Socket n status register (Sn_SR, The 'Sn_SR' controlled by Sn_CR command or Packet send/recv status)
   switch(getSn_SR(sn))
   {
      case SOCK_ESTABLISHED :
         if(getSn_IR(sn) & Sn_IR_CON)	// Socket n interrupt register mask; TCP CON interrupt = connection with peer is successful
         {
#ifdef _LOOPBACK_DEBUG_
			printf("%d:Connected to - %d.%d.%d.%d : %d\r\n",sn, destip[0], destip[1], destip[2], destip[3], destport);
#endif
			setSn_IR(sn, Sn_IR_CON);  // this interrupt should be write the bit cleared to '1'
         }

         //
         // Data Transaction Parts; Handle the [data receive and send] process
         //
		 if((size = getSn_RX_RSR(sn)) > 0) // Sn_RX_RSR: Socket n Received Size Register, Receiving data length
         {
			if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE; // DATA_BUF_SIZE means user defined buffer size (array)
			ret = recv(sn, buf, size); // Data Receive process (H/W Rx socket buffer -> User's buffer)

			if(ret <= 0) return ret; // If the received data length <= 0, receive failed and process end
			size = (uint16_t) ret;
			sentsize = 0;

			// Data sentsize control
			while(size != sentsize)
			{
				ret = send(sn, buf+sentsize, size-sentsize); // Data send process (User's buffer -> Destination through H/W Tx socket buffer)
				
				printf("%s\r\n",buf);
				
				if(ret < 0) // Send Error occurred (sent data length < 0)
				{
					close(sn); // socket close
					return ret;
				}
				sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
			}
         }
		 //
         break;

      case SOCK_CLOSE_WAIT :
#ifdef _LOOPBACK_DEBUG_
         //printf("%d:CloseWait\r\n",sn);
#endif
         if((ret=disconnect(sn)) != SOCK_OK) return ret;
#ifdef _LOOPBACK_DEBUG_
         printf("%d:Socket Closed\r\n", sn);
#endif
         break;

      case SOCK_INIT :
#ifdef _LOOPBACK_DEBUG_
    	 printf("%d:Try to connect to the %d.%d.%d.%d : %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport);
#endif
    	 if( (ret = connect(sn, destip, destport)) != SOCK_OK) return ret;	//	Try to TCP connect to the TCP server (destination)
         break;

      case SOCK_CLOSED:
    	  close(sn);
    	  if((ret=socket(sn, Sn_MR_TCP, any_port++, SF_TCP_NODELAY)) != sn) return ret; // TCP socket open with 'any_port' port number
#ifdef _LOOPBACK_DEBUG_
    	 printf("%d:TCP client loopback start\r\n",sn);
         //printf("%d:Socket opened\r\n",sn);
#endif
         break;
      default:
			{
         break;
			}
   }
   return 1;
}

上面将W5500客户端从电脑服务器上收到的TCP数据通过串口打印出来,同时回复给电脑

(4)在主进程中加入TCP客户端事件处理

	/*******************************/
	/* WIZnet W5500 Code Examples  */
	/*******************************/
  /* Main loop */
	while(1)
	{
		//TCP客户端回环测试
		loopback_tcpc(SOCK_TCPS, gDATABUF, dest_ip, dest_port);

		delay_ms(20);
		LED1 = 0;
		delay_ms(20);
		LED1 = 1;

	} // end of Main loop

在循环中定时处理TCP客户端事件,同时闪一下灯(循环间隔不重要,别太长就行)

4、验证客户端

?(1)首先,我们要将电脑和设备全部接到路由器上(电脑不必用以太网,wifi连上去也一样)

(2)检查路由器的网关地址和路由器给电脑分配的IP地址



当然,路由器找不到该功能的,CMD命令行ipconfig一下查电脑的IP和网关即可


此时,读到的网关为10.1.1.1,所以我们要把W5500的默认IP地址改到该网段下(前三个网段一致),比如10.1.1.200,参照前一篇文章。


wiz_NetInfo gWIZNETINFO = { .mac = {0x00, 0x08, 0xdc,0x00, 0xab, 0xcd},
                            .ip = {10, 1, 1, 200},
                            .sn = {255,255,255,0},
                            .gw = {10, 1, 1, 1},
                            .dns = {8,8,8,8},
                            .dhcp = NETINFO_STATIC};

(4)在电脑上使用网络调试工具,开启一个TCP服务器(注意端口号服务器要和客户端程序里设置的一致,比如此处设置的都是5000)

?(5)设备写入程序,上电开始测试


从串口数据上可以看到,设备开始连接,并连接电脑成功





电脑发送的数据,W5500原样返回,同时串口返回的数据也符合我们的预期。

这样,TCP客户端模式收发数据就实现了。注意:

(1)、W5500设置的IP的不应该与路由器内其他设备冲突
(2)、连接的服务器不只可以是本地的电脑,如果路由器是联网的,那么连接任意公网内的TCP服务器都是可以的,比如如果你有个云服务器,在上面开一个TCP服务器,也是可以连上的
?
当然,我们实际使用,肯定不可能将W5500连上网口后,还要检查路由器的IP,然后重新改一下程序,把W5500的IP地址改掉,这也不现实。所以,还要在W5500上引入DHCP服务,这个东西下一篇文章再说。


?

?

?

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-07-14 23:16:55  更:2021-07-14 23:18:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/29 9:37:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码