測試W5500的第3步_使用ioLibrary庫創建TCPServer

W5500是一款具有8個Socket的網絡芯片,支持TCP Server模式,最多可同時連接8個客戶端。本文介紹了基于STM32F10x和W5500的TCP Server實現,包括SPI初始化、W5500復位、網絡參數配置、Socket狀態管理等功能,適用于需要多客戶端連接的嵌入式網絡應用場景。

w5500具有8個Socket,TCPserver模式下最多支持8個客戶端同時訪問。

文件下載地址:https://gitee.com/wiznet-hk/STM32F10x_W5500_Examples
源文件下載地址:https://gitee.com/wiznet-hk

1、wiz_platform.c有改動

#include "wiz_platform.h"
#include <stdio.h>
#include <stdint.h>
#include "wizchip_conf.h"
#include "wiz_interface.h"
#include "stm32f10x.h"
#include "delay.h"//函數功能:SPI1初始化
void wiz_spi_init(void)
{GPIO_InitTypeDef 	GPIO_InitStructure;SPI_InitTypeDef   SPI_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA的外設時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);  //使能SPI1的外設時鐘GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;         //選擇PIN5,是SPI1的SCLGPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	  //選擇引腳為復用推挽輸出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //設置引腳的最高工作速率為50MHzGPIO_Init(GPIOA, &GPIO_InitStructure);  //根據GPIO_InitStructure結構指針所指向的參數配置PA5引腳	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;         //選擇PIN6,是SPI1的MISOGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;	  //選擇引腳為輸入懸浮GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //設置引腳的最高工作速率為50MHzGPIO_Init(GPIOA, &GPIO_InitStructure);  //根據GPIO_InitStructure結構指針所指向的參數配置PA6引腳GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;         //選擇PIN7,是SPI1的MOSIGPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	  //選擇引腳為復用推挽輸出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //設置引腳的最高工作速率為50MHzGPIO_Init(GPIOA, &GPIO_InitStructure);  //根據GPIO_InitStructure結構指針所指向的參數配置PA7引腳GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;         //選擇PIN3,是W5500的片選腳CSGPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //選擇引腳為推挽輸出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //設置引腳的最高工作速率為50MHzGPIO_Init(GPIOA, &GPIO_InitStructure);  //根據GPIO_InitStructure結構指針所指向的參數配置PA3引腳//設置SPI1的工作模式SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI設置為雙線雙向全雙工SPI_InitStructure.SPI_Mode = SPI_Mode_Master;     //設置為主SPISPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //設置SPI發送接收為8位幀結構SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;        //設置SCK空閑時鐘為低電平SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;      //數據捕獲于第1個時鐘沿//SCK空閑時鐘為低電平,數據捕獲于第1個時鐘沿,這樣就設置了SPI從機在下降沿采集數據了//SPI從機在下降沿采集數據,這要求CPU必須在SCK上升沿輸出位值,在SCK為高電平時達到穩定,為數據采集做好準備SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;  //設置NSS輸出由SSI位控制SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;//設置波特率預分頻值為2SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;  //設置數據傳輸先從MSB位開始SPI_InitStructure.SPI_CRCPolynomial = 7;            //使用CRC7校驗SPI_Init(SPI1, &SPI_InitStructure);SPI_Cmd(SPI1, ENABLE); //使能SPI外設
}//函數功能:初始化W5500的RST引腳和INT引腳
void wiz_rst_int_init(void)
{GPIO_InitTypeDef  GPIO_InitStructure;RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOC, ENABLE ); //使能GPIOC外設的高速時鐘/* W5500_RST引腳初始化配置(PC5) */GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_5;	//選擇PC5為W5500的RST引腳GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_ResetBits(GPIOC, GPIO_Pin_5);RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOC, ENABLE ); //使能GPIOC外設的高速時鐘/* W5500_INT引腳初始化配置(PC4) */	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;	//選擇PC4為W5500的INT引腳GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;GPIO_Init(GPIOC, &GPIO_InitStructure);
}//函數功能:使能SPI片選
void wizchip_select(void)
{GPIO_ResetBits(GPIOA,GPIO_Pin_4);//輸出低電平表示選擇W5500
}//函數功能:不使能SPI片選
void wizchip_deselect(void)
{GPIO_SetBits(GPIOA,GPIO_Pin_4);//輸出高電平表示不選擇W5500
}//函數功能:通過SPI,將dat的值發送給W5500
void wizchip_write_byte(uint8_t dat)
{while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){//檢查SPI1的發送完成標志是否建立}SPI_I2S_SendData(SPI1, dat);//通過SPI,將dat發送給W5500while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){//檢查SPI1的接收完成標志是否建立}SPI_I2S_ReceiveData(SPI1);//讀SPI接收數據寄存器
}//函數功能:通過SPI讀取1個字節,并返回
uint8_t wizchip_read_byte(void)
{while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){//檢查SPI1的發送完成標志是否建立}SPI_I2S_SendData(SPI1,0xffff);//發送16個移位時鐘,為接收數據作準備while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){//檢查SPI1的接收完成標志是否建立}return SPI_I2S_ReceiveData(SPI1);//讀SPI接收數據寄存器
}//函數功能:通過SPI,將buf[]中的前len個字節發送給W5500
void wizchip_write_buff(uint8_t *buf, uint16_t len)
{uint16_t idx = 0;for (idx = 0; idx < len; idx++){wizchip_write_byte(buf[idx]);//通過SPI,將buf[idx]的值發送給W5500}
}//函數功能:通過SPI讀取len個字節,保存到buf[]中
void wizchip_read_buff(uint8_t *buf, uint16_t len)
{uint16_t idx = 0;for (idx = 0; idx < len; idx++){buf[idx] = wizchip_read_byte();//通過SPI讀取1個字節,保存到buf[idx]中}
}//函數功能:W5500使用RST引腳復位
void wizchip_reset(void)
{GPIO_SetBits(GPIOC, GPIO_Pin_5);//復位引腳拉高delay_ms(10);GPIO_ResetBits(GPIOC, GPIO_Pin_5);//復位引腳拉低delay_ms(10);GPIO_SetBits(GPIOC, GPIO_Pin_5);//復位引腳拉高delay_ms(10);
}//函數功能:注冊SPI片選函數,單字節讀寫函數和多字節讀寫函數
//1.注冊SPI片選信號函數
//2.注冊SPI讀寫單一字節函數
//3.注冊SPI讀寫多字節函數
void wizchip_spi_cb_reg(void)
{reg_wizchip_cs_cbfunc(wizchip_select, wizchip_deselect);//注冊SPI片選信號函數reg_wizchip_spi_cbfunc(wizchip_read_byte, wizchip_write_byte);//注冊SPI讀寫單一字節函數reg_wizchip_spiburst_cbfunc(wizchip_read_buff, wizchip_write_buff);//注冊SPI讀寫多字節函數
}//函數功能:配置TIM2每毫秒中斷一次
void wiz_timer_init(void)
{TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);TIM_TimeBaseStructure.TIM_Period = 1000 - 1;TIM_TimeBaseStructure.TIM_Prescaler = 72 - 1;TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);TIM_ClearFlag(TIM2, TIM_FLAG_Update);TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);TIM_Cmd(TIM2, ENABLE);
}//函數功能:使能TIM2中斷
void wiz_tim_irq_enable(void)
{TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
}//函數功能:不使能TIM2中斷
void wiz_tim_irq_disable(void)
{TIM_ITConfig(TIM2, TIM_IT_Update, DISABLE);
}//函數功能:TIM2每毫秒中斷一次
void TIM2_IRQHandler(void)
{static uint32_t wiz_timer_1ms_count = 0;if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET){wiz_timer_1ms_count++;if (wiz_timer_1ms_count >= 1000){wiz_timer_1ms_count = 0;}TIM_ClearITPendingBit(TIM2, TIM_IT_Update);}
}

2、wiz_platform.h

#ifndef __WIZ_PLATFORM_H__
#define __WIZ_PLATFORM_H__#include <stdint.h>/*** @brief   wiz spi init* @param   none* @return  none*/
void wiz_spi_init(void);/*** @brief   wiz rst and int pin init* @param   none* @return  none*/
void wiz_rst_int_init(void);/*** @brief   hardware reset wizchip* @param   none* @return  none*/
void wizchip_reset(void);/*** @brief   Register the WIZCHIP SPI callback function* @param   none* @return  none*/
void wizchip_spi_cb_reg(void);/*** @brief   wiz timer init* @param   none* @return  none*/
void wiz_timer_init(void);/*** @brief   Turn on wiz timer interrupt* @param   none* @return  none*/
void wiz_tim_irq_enable(void);/*** @brief   Turn off wiz timer interrupt* @param   none* @return  none*/
void wiz_tim_irq_disable(void);
#endif

3、wiz_interface.c有改動

#include "wiz_interface.h"
#include "wiz_platform.h"
#include "wizchip_conf.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "delay.h"void wizchip_initialize(void);
void Server_network_init(uint8_t *ethernet_buff, wiz_NetInfo *conf_info);void wizchip_version_check(void);
void print_network_information(void);
void wiz_phy_link_check(void);
void wiz_print_phy_info(void);#define W5500_VERSION 0x04
//函數功能:讀取芯片版本號碼,并檢查是否正確
void wizchip_version_check(void)
{uint8_t error_count = 0;while (1){delay_ms(1000);if (getVERSIONR() != W5500_VERSION){//讀取芯片版本號碼error_count++;if (error_count > 5){printf("error, %s version is 0x%02x, but read %s version value = 0x%02x\r\n", _WIZCHIP_ID_, W5500_VERSION, _WIZCHIP_ID_, getVERSIONR());while (1);}}else{break;}}
}/*** @brief Print PHY information*/
//函數功能:
//1.讀PHY配置寄存器的bit1和bit2
//2.串口輸出當前網速為100M/10M
//3.串口輸出當前以太網采用全雙工通訊/半雙工通訊
void wiz_print_phy_info(void)
{uint8_t get_phy_conf;get_phy_conf = getPHYCFGR();//讀PHY配置寄存器printf("The current Mbtis speed : %dMbps\r\n", get_phy_conf & 0x02 ? 100 : 10);//PHY配置寄存器,bit1=1表示網速為100M,bit1=0表示網速為10Mprintf("The current Duplex Mode : %s\r\n", get_phy_conf & 0x04 ? "Full-Duplex" : "Half-Duplex");//PHY配置寄存器,bit2=1表示以太網采用全雙工通訊,bit2=0表示以太網采用半雙工通訊
}//函數功能:
//讀PHY配置寄存器的bit[2:0]
//bit0=1表示W5500連接到局域網
//bit1=1表示當前網速為100M,否則為10M
//bit2=1表示當前以太網采用全雙工通訊,否則為半雙工通訊
void wiz_phy_link_check(void)
{uint8_t phy_link_status;do{delay_ms(1000);ctlwizchip(CW_GET_PHYLINK, (void *)&phy_link_status);//讀PH配置寄存器的bit0,保存到phy_link_status中,為1表示連接到局域網if (phy_link_status == PHY_LINK_ON){//W5500連接到局域網printf("PHY link\r\n");wiz_print_phy_info();//1.讀PHY配置寄存器的bit1和bit2//2.串口輸出當前網速為100M/10M//3.串口輸出當前以太網采用全雙工通訊/半雙工通訊}else{printf("PHY no link\r\n");}} while (phy_link_status == PHY_LINK_OFF);
}//1.注冊SPI片選函數,單字節讀寫函數和多字節讀寫函數
//2.W5500使用RST引腳復位
//3.讀取芯片版本號碼,并檢查是否正確
//4.讀PHY配置寄存器的bit[2:0],bit0=1表示W5500連接到局域網
//bit1=1表示當前網速為100M,否則為10M
//bit2=1表示當前以太網采用全雙工通訊,否則為半雙工通訊
void wizchip_initialize(void)
{wizchip_spi_cb_reg();//注冊SPI片選函數,單字節讀寫函數和多字節讀寫函數wizchip_reset();//W5500使用RST引腳復位wizchip_version_check();//讀取芯片版本號碼,并檢查是否正確//Read version registerwiz_phy_link_check();//讀PHY配置寄存器的bit[2:0]//bit0=1表示W5500連接到局域網//bit1=1表示當前網速為100M,否則為10M//bit2=1表示當前以太網采用全雙工通訊,否則為半雙工通訊
}//函數功能:讀本地網絡參數:MAC地址,GW網關,SN子網掩碼,本地IP地址,DNS服務器IP地址,DHCP,然后從串口輸出
void print_network_information(void)
{wiz_NetInfo net_info;wizchip_getnetinfo(&net_info);// Get chip configuration information//讀本地網絡參數:MAC地址,GW網關,SN子網掩碼,本地IP地址,DNS服務器IP地址,DHCPif (net_info.dhcp == NETINFO_DHCP){printf("====================================================================================================\r\n");printf(" %s network configuration : DHCP\r\n\r\n", _WIZCHIP_ID_);}else{printf("====================================================================================================\r\n");printf(" %s network configuration : static\r\n\r\n", _WIZCHIP_ID_);}printf(" MAC         : %02X:%02X:%02X:%02X:%02X:%02X\r\n", net_info.mac[0], net_info.mac[1], net_info.mac[2], net_info.mac[3], net_info.mac[4], net_info.mac[5]);printf(" IP          : %d.%d.%d.%d\r\n", net_info.ip[0], net_info.ip[1], net_info.ip[2], net_info.ip[3]);printf(" Subnet Mask : %d.%d.%d.%d\r\n", net_info.sn[0], net_info.sn[1], net_info.sn[2], net_info.sn[3]);printf(" Gateway     : %d.%d.%d.%d\r\n", net_info.gw[0], net_info.gw[1], net_info.gw[2], net_info.gw[3]);printf(" DNS         : %d.%d.%d.%d\r\n", net_info.dns[0], net_info.dns[1], net_info.dns[2], net_info.dns[3]);printf("====================================================================================================\r\n\r\n");
}//函數功能:TCP Server設置本地網絡信息
//1.使用"默認網絡參數"設置本地網絡參數:MAC地址,GW網關,SN子網掩碼,本地IP地址,DNS服務器IP地址,DHCP
//2.讀本地網絡參數:MAC地址,GW網關,SN子網掩碼,本地IP地址,DNS服務器IP地址,DHCP,然后從串口輸出
void Server_network_init(uint8_t *ethernet_buff, wiz_NetInfo *conf_info)
{wizchip_setnetinfo(conf_info);//設置本地網絡參數:MAC地址,GW網關,SN子網掩碼,本地IP地址,DNS服務器IP地址,DHCP模式print_network_information();//讀本地網絡參數:MAC地址,GW網關,SN子網掩碼,本地IP地址,DNS服務器IP地址,DHCP模式,然后從串口輸出
}

4、wiz_interface.h

#ifndef __WIZ_INTERFACE_H__
#define __WIZ_INTERFACE_H__#include "wizchip_conf.h"extern void wizchip_initialize(void);
extern void Server_network_init(uint8_t *ethernet_buff, wiz_NetInfo *conf_info);
#endif

5、W5500_Variable.c有改動

#include "W5500_Variable.h"
#include "socket.h"	// Just include one header for WIZCHIP
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "string.h" //使能strcpy(),strlen(),memset()//W5500的網絡參數
//本地物理地址:00 08 DC 11 11 11
//本地IP地址:192.168.1.199
//本地子網掩碼:	255.255.255.0
//本地網關:192.168.1.1
//DNS服務器IP地址:8.8.8.8
//程序固化IP地址
/* network information */
wiz_NetInfo default_net_info = {{0x00, 0x08, 0xdc,0x11, 0x11, 0x11},{192, 168, 1, 199},{255,255,255,0},{192, 168, 1, 1},{8,8,8,8},NETINFO_STATIC}; //靜態IP,程序固化IP地址
wiz_NetInfo net_info;uint8_t ethernet_buf[ETHERNET_BUF_MAX_SIZE] = {0};uint8_t destip[8][4];//存放8個端口的遠程IP地址
uint16_t destport[8];//存放8個遠程端口值

6、W5500_Variable.h有改動

#ifndef _W5500_Variable_H
#define _W5500_Variable_H#include "stm32f10x.h"//使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t
#include "wizchip_conf.h"extern wiz_NetInfo default_net_info;
extern wiz_NetInfo net_info;#define ETHERNET_BUF_MAX_SIZE (1024 * 2)
extern uint8_t ethernet_buf[ETHERNET_BUF_MAX_SIZE];extern uint8_t destip[8][4];
extern uint16_t destport[8];
#endif

7、TestTcpServer.c

#include "TestTcpServer.h"
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "w5500.h"
#include "W5500_Variable.h"
#include "socket.h"//w5500具有8個Socket,TCPserver模式下最多支持8個客戶端同時訪問int32_t loop_TestTcpServer(uint8_t sn, uint8_t* buf, uint16_t port);/*** @brief   tcp server loopback test* @param   sn:    socket number* @param   buf:   Data sending and receiving cache* @param   port:  Listen port* @return  value for SOCK_ERRORs,return 1:no error 
*/
//sn為SOCKET端口
//buf為接收數據緩沖區
//port為本地端口
int32_t loop_TestTcpServer(uint8_t sn, uint8_t* buf, uint16_t port)
{int32_t ret;uint16_t size = 0, sentsize=0;switch(getSn_SR(sn))//獲取W5500端口sn的狀態寄存器{case SOCK_ESTABLISHED ://W5500端口sn已經連接成功if(getSn_IR(sn) & Sn_IR_CON){//讀端口sn的Sn_IR中斷標志寄存器的bit0
#ifdef _LOOP_TestTcpServer_DEBUG_getSn_DIPR(sn, destip[sn]);destport[sn] = getSn_DPORT(sn);printf("Socket%d:Connected - %d.%d.%d.%d : %d\r\n",sn, destip[sn][0], destip[sn][1], destip[sn][2], destip[sn][3], destport[sn]);
#endifsetSn_IR(sn,Sn_IR_CON);//回寫端口sn的Sn_IR中斷標志寄存器的bit0,清除中斷標志}if((size = getSn_RX_RSR(sn)) > 0)//讀端口sn的Sn_RX_RSR寄存器,獲取該端口的接收緩沖區的數據長度{if(size > ETHERNET_BUF_MAX_SIZE) size = ETHERNET_BUF_MAX_SIZE;ret = recv(sn, buf, size);//讀"W5500端口sn"的數據,長度為size個字節,保存到bufbuf[ret]='\0';//添加字符串結束符printf("Socket%d recv: %s\n",sn,buf); //print the receive data.if(ret <= 0) return ret;      // check SOCKERR_BUSY & SOCKERR_XXX. For showing the occurrence of SOCKERR_BUSY.size = (uint16_t) ret;sentsize = 0;while(size != sentsize){ret = send(sn, buf+sentsize, size-sentsize);//將(buf+sentsize)為首地址的存儲單元的前len個字節通過"W5500端口sn"發送出去if(ret < 0){close(sn);//關閉端口sn的連接, socket closereturn ret;}sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.}}break;case SOCK_CLOSE_WAIT ://W5500端口sn處于等待關閉狀態
#ifdef _LOOP_TestTcpServer_DEBUG_printf("Socket%d:CloseWait\r\n",sn);
#endifif((ret = disconnect(sn)) != SOCK_OK) return ret;
#ifdef _LOOP_TestTcpServer_DEBUG_printf("Socket%d:Socket Closed\r\n", sn);
#endifbreak;case SOCK_INIT ://W5500端口sn已經初始化
#ifdef _LOOP_TestTcpServer_DEBUG_printf("Socket%d:Listen port [%d]\r\n", sn, port);
#endifif( (ret = listen(sn)) != SOCK_OK)//監聽SOCKET端口snreturn ret;break;case SOCK_CLOSED://W5500端口sn處于關閉狀態
#ifdef _LOOP_TestTcpServer_DEBUG_printf("Socket%d:TCP server start\r\n",sn);
#endifif((ret = socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret;
#ifdef _LOOP_TestTcpServer_DEBUG_printf("Socket%d:Socket opened\r\n",sn);
#endifbreak;default:break;}return 1;
}

8、TestTcpServer.h

#ifndef _TestTcpServer_H
#define _TestTcpServer_H#include "stm32f10x.h"//使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t#define TCPServerSOCEKET0        0     //W5500使用端口0作為TCP Server
#define TCPServerSOCEKET1        1     //W5500使用端口1作為TCP Server
#define TCPServerSOCEKET2        2     //W5500使用端口2作為TCP Server
#define TCPServerSOCEKET3        3     //W5500使用端口3作為TCP Server
#define TCPServerSOCEKET4        4     //W5500使用端口4作為TCP Server
#define TCPServerSOCEKET5        5     //W5500使用端口5作為TCP Server
#define TCPServerSOCEKET6        6     //W5500使用端口6作為TCP Server
#define TCPServerSOCEKET7        7     //W5500使用端口7作為TCP Server#define	_LOOP_TestTcpServer_DEBUG_  //允許串口跟蹤extern int32_t loop_TestTcpServer(uint8_t sn, uint8_t* buf, uint16_t port);#endif

?9、main.c

#include "stm32f10x.h"//使能uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t
#include "stdio.h"  //getchar(),putchar(),scanf(),printf(),puts(),gets(),sprintf()
#include "string.h" //使能strcpy(),strlen(),memset()
#include "delay.h"
#include "USART4.h"
#include "LED.h"//文件下載地址:https://gitee.com/wiznet-hk/STM32F10x_W5500_Examples
//源文件下載地址:https://gitee.com/wiznet-hk
#include "wiz_platform.h"
#include "wizchip_conf.h"
#include "wiz_interface.h"
#include "W5500_Variable.h"
#include "TestTcpServer.h"const char CPU_Reset_REG[]="\r\nCPU reset!\r\n";
int main(void)
{//	SCB->VTOR = 0x8000000;//中斷向量表重定義//	SystemInit();delay_init();//延時函數初始化NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//設置系統中斷優先級分組4USART4_Serial_Interface_Enable(115200);printf("%s",CPU_Reset_REG);//調試串口輸出"\r\nCPU reset!\r\n"LED_Init();LED0_ON();wiz_timer_init();  //配置TIM2每毫秒中斷一次wiz_spi_init();    //SPI1初始化wiz_rst_int_init();//初始化W5500的RST引腳和INT引腳printf("%s network install example\r\n",_WIZCHIP_ID_);wizchip_initialize();//1.注冊SPI片選函數,單字節讀寫函數和多字節讀寫函數//2.W5500使用RST引腳復位//3.讀取芯片版本號碼,并檢查是否正確//4.讀PHY配置寄存器的bit[2:0],bit0=1表示W5500連接到局域網//bit1=1表示當前網速為100M,否則為10M//bit2=1表示當前以太網采用全雙工通訊,否則為半雙工通訊Server_network_init(ethernet_buf, &default_net_info);
//TCP Server設置本地網絡信息
//1.使用"默認網絡參數"設置本地網絡參數:MAC地址,GW網關,SN子網掩碼,本地IP地址,DNS服務器IP地址,DHCP模式
//2.讀本地網絡參數:MAC地址,GW網關,SN子網掩碼,本地IP地址,DNS服務器IP地址,DHCP模式,然后從串口輸出setSn_KPALVTR(TCPServerSOCEKET0, 6); // 30s keepalive//Socket在線時間寄存器,在線驗證心跳包傳輸時間,他只在TCP模式下生效,在其他模式下將會被忽略,單位時間為5秒。//因此心跳包傳輸時間為6*5=30秒setSn_KPALVTR(TCPServerSOCEKET1, 6); // 30s keepalivesetSn_KPALVTR(TCPServerSOCEKET2, 6); // 30s keepalivesetSn_KPALVTR(TCPServerSOCEKET3, 6); // 30s keepalivesetSn_KPALVTR(TCPServerSOCEKET4, 6); // 30s keepalivesetSn_KPALVTR(TCPServerSOCEKET5, 6); // 30s keepalivesetSn_KPALVTR(TCPServerSOCEKET6, 6); // 30s keepalivesetSn_KPALVTR(TCPServerSOCEKET7, 6); // 30s keepalivewhile(1){loop_TestTcpServer(TCPServerSOCEKET0,ethernet_buf,5000);loop_TestTcpServer(TCPServerSOCEKET1,ethernet_buf,5000);loop_TestTcpServer(TCPServerSOCEKET2,ethernet_buf,5000);loop_TestTcpServer(TCPServerSOCEKET3,ethernet_buf,5000);loop_TestTcpServer(TCPServerSOCEKET4,ethernet_buf,5000);loop_TestTcpServer(TCPServerSOCEKET5,ethernet_buf,5000);loop_TestTcpServer(TCPServerSOCEKET6,ethernet_buf,5000);loop_TestTcpServer(TCPServerSOCEKET7,ethernet_buf,5000);LED0=!LED0;delay_ms(1000);}
}

10、工程樣板

11、串口仿真結果

12、TCP Client客戶機

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/906649.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/906649.shtml
英文地址,請注明出處:http://en.pswp.cn/news/906649.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Web攻防-SQL注入數據庫類型用戶權限架構分層符號干擾利用過程發現思路

知識點&#xff1a; 1、Web攻防-SQL注入-產生原理&應用因素 2、Web攻防-SQL注入-各類數據庫類型利用 演示案例-WEB攻防-SQL注入-數據庫類型&架構分層&符號干擾 一、數據庫知識 1、數據庫名&#xff0c;表名&#xff0c;列名&#xff0c;數據 2、自帶數據庫&…

手機合集(不定期更新)

一、華為手機&#xff1a; 1.華為手機自助維修的方法&#xff1a; https://blog.csdn.net/humors221/article/details/145946128 2.華為手機實用功能介紹&#xff1a; https://blog.csdn.net/humors221/article/details/132514011 3.華為手機清理大數據的方法&#xff1a;…

移動安全Android——ROOT檢測繞過

工具準備 Magisk GitHub - topjohnwu/Magisk: The Magic Mask for Android ZygisckNext GitHub - Dr-TSNG/ZygiskNext at v1.2.8 Shamiko Releases LSPosed/LSPosed.github.io 安卓ROOT教程 Magisk 安裝教程 - Magisk 中文網 問題 大多數手機在ROOT狀態下會出現APP閃…

Python高效網絡爬蟲開發指南

Python 網絡爬蟲入門與實戰 一、引言 隨著互聯網數據的爆炸性增長&#xff0c;獲取和分析這些數據變得越來越重要。網絡爬蟲作為數據采集的重要工具&#xff0c;在這其中扮演了不可或缺的角色。 二、環境搭建 首先我們需要安裝Python環境以及一些必要的庫&#xff1a; req…

wireshark: Display Filter Reference

https://www.wireshark.org/docs/dfref/// 這個里面的擴展功能還是很強大&#xff0c;可以幫著問題分析。支持大量的自定義化的字段讀取功能&#xff0c;支持很多的協議。 https://www.wireshark.org/docs/dfref///f/frame.html frame.time_delta Time delta from previous ca…

dify創建銀行客服系統例子

傳統的銀行客服系統&#xff0c;通常以會話管理的方式實現&#xff0c;配置繁瑣復雜&#xff0c;固定且不靈活。如&#xff1a; 智能體的出現&#xff0c;為實現銀行客服系統提供了想象空間&#xff0c;可以集知識庫和業務流程為一體實現靈活可控的智能客服系統&#xff0c;即能…

前端函數防抖(Debounce)完整講解 - 從原理、應用到完整實現

&#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有堅忍不拔之志 &#x1f390; 個人CSND主頁——Micro麥可樂的博客 &#x1f425;《Docker實操教程》專欄以最新的Centos版本為基礎進行Docker實操教程&#xff0c;入門到實戰 &#x1f33a;《RabbitMQ》…

服務接口鑒權與內部認證:自定義注解與AOP實現的企業級實踐

本文深入解析企業級系統中接口安全管控的核心需求&#xff0c;提出基于Spring AOP與自定義注解的輕量級鑒權方案。通過解構注解元數據定義、切面攔截邏輯、上下文傳遞機制等關鍵技術環節&#xff0c;系統闡述零侵入式鑒權體系的構建路徑。結合金融支付網關、多租戶SaaS平臺、物…

26考研|高等代數:線性變換

前言 線性變換這一章節是考頻較高的一部分&#xff0c;此部分涉及考點較多&#xff0c;涉及的考題也較多&#xff0c;學習線性變換時&#xff0c;應該注意搭建線性變換與矩陣之間的聯系&#xff0c;掌握如何利用矩陣表示一個線性變換結構&#xff0c;同時介紹了最簡單的線性變…

電磁兼容(EMC)仿真(精編版)

寫在前面 本系列文章主要講解電磁兼容(EMC)仿真的相關知識,希望能幫助更多的同學認識和了解電磁兼容(EMC)仿真。 若有相關問題,歡迎評論溝通,共同進步。(*^▽^*) 隨著產品復雜性和密集度的提高以及設計周期的不斷縮短,在設計周期的后期解決電磁兼容性(EMC)問題變得…

解決:dpkg: error: dpkg frontend lock is locked by another process

1、等待其他進程完成 如果后臺有其他包管理操作&#xff08;如自動更新、軟件安裝等&#xff09;&#xff0c;等待幾分鐘再重試。 可以通過以下命令查看是否有相關進程&#xff1a; ps aux | grep -E apt|apt-get|dpkg 2、強制終止占用鎖的進程 如果確認沒有其他包管理操作&…

LVGL(lv_textarea文本框控件)

文章目錄 一、lv_textarea 是什么&#xff1f;二、基本用法1. 創建 lv_textarea 對象2. 設置提示文字&#xff08;占位符&#xff09;3. 設置最大長度4. 設置密碼模式&#xff08;顯示為\*號&#xff09;5. 獲取和設置內容6. 配合虛擬鍵盤使用&#xff08;常用于觸摸屏&#xf…

【Java高階面經:數據庫篇】18、分布式事務:如何在分庫分表中實現高性能與一致性?

一、分布式事務核心挑戰:分庫分表下的一致性困境 在分布式系統架構中,分庫分表通過將數據分散存儲提升了擴展性和性能,但卻打破了傳統單庫事務的邊界,使得分布式事務成為保障數據一致性的核心難題。其挑戰主要體現在以下三方面: 1.1 ACID特性的分布式撕裂 原子性(Atomi…

【云吶】房地產企業固定資產如何管理

房產類固定資產如辦公樓、門面房、宿舍樓、庫房等&#xff0c;價值高、使用年限長、權屬復雜、變更流程多&#xff0c;是企業最為關鍵的資產類型之一。管理房產類資產不僅要“看得到”&#xff0c;更要“管得住”。 房產資產管理應從權屬明確開始。固定資產管理系統支持房產資產…

oracle數據庫生成awr報告,排查數據庫服務器CPU100%,系統卡頓,慢sql,根據sqlid查詢關鍵信息,如會話SID,客戶端機器名

AWR報告簡介 AWR是Oracle 10g版本推出的特性,全稱叫做 Automatic Workload Repository 全自動負載信息庫 。Oracle啟動后,會有后臺進程定時采集并保存系統快照信息,也可以手工創建快照。AWR通過對比兩個時間點的快照信息,生成該時間段的AWR報告,幫助DBA或開發人員了解 Ora…

kafka吞吐量提升總結

前言 原本自以為閱讀了很久kafka的源碼&#xff0c;對于kafka的了解已經深入到一定程度了&#xff0c;后面在某大廠的面試中&#xff0c;面試官詢問我&#xff0c;如果需要提升kafka的性能&#xff0c;應該怎么做&#xff0c;我發現我能答上來的點非常的少&#xff0c;也暴露了…

鴻蒙 HarmonyOS NEXT 系統 Preference 首選項使用全解析

鴻蒙HarmonyOS系統Preference首選項使用全解析 大家好&#xff0c;我是威哥。在鴻蒙應用開發里&#xff0c;用戶偏好設置的管理是極為重要的一環。HarmonyOS為我們提供了Preference組件&#xff0c;它能讓我們輕松實現應用設置界面&#xff0c;對用戶首選項進行高效管理。接下…

xdc約束學習

對clk的約束 //約束clk為 125M Hz create_clock -period 8.000 -name gt_refclk1_p -waveform {0.000 4.000} [get_ports gt_refclk1_p] 偽時鐘路徑&#xff0c;用于兩個時鐘域之間數據的交互 單邊性&#xff08;unateness&#xff09;對于時序很重要&#xff0c;因為它指定的…

在 Ubuntu 虛擬機中實現 HTML 表單與 C 語言 HTTP 服務器交互

一、環境說明 系統&#xff1a;Ubuntu 虛擬機&#xff08;已安裝基本開發工具&#xff0c;如 GCC&#xff09;目標&#xff1a;通過 C 語言服務器托管 HTML 表單頁面&#xff0c;并實現數據提交交互 二、核心文件準備 1. 創建 HTML 表單頁面&#xff08;xunfei.html&#xf…

LVS 負載均衡集群應用實戰

前提:三臺虛擬機,有nginx,要做負載 1. LVS-server 安裝lvs管理軟件 [root@lvs-server ~]# yum -y install ipvsadm 程序包:ipvsadm(LVS管理工具) 主程序:/usr/sbin/ipvsadm 規則保存工具:/usr/sbin/ipvsadm-save > /path/to/file 配置文件:/etc/sysconfig/ipvsad…