[经验] 分享W5500例程

123131wqe   2020-4-10 15:54 楼主

/**********************************************************************************
 * 文件名  :W5500.c
 * 描述    :W5500 驱动函数库         
 * 库版本  :ST_v3.5

 * 淘宝    :http://yixindianzikeji.taobao.com/
**********************************************************************************/

#include "stm32f10x.h"
#include "stm32f10x_spi.h"                
#include "W5500.h"    
#include "delay.h"
/***************----- 网络参数变量定义 -----***************/
unsigned char Gateway_IP[4];//网关IP地址
unsigned char Sub_Mask[4];    //子网掩码
unsigned char Phy_Addr[6];    //物理地址(MAC)
unsigned char IP_Addr[4];    //本机IP地址

unsigned char S0_Port[2];    //端口0的端口号(5000)
unsigned char S0_DIP[4];    //端口0目的IP地址
unsigned char S0_DPort[2];    //端口0目的端口号(6000)

unsigned char UDP_DIPR[4];    //UDP(广播)模式,目的主机IP地址
unsigned char UDP_DPORT[2];    //UDP(广播)模式,目的主机端口号

/***************----- 端口的运行模式 -----***************/
unsigned char S0_Mode =3;    //端口0的运行模式,0:TCP服务器模式,1:TCP客户端模式,2:UDP(广播)模式
#define TCP_SERVER    0x00    //TCP服务器模式
#define TCP_CLIENT    0x01    //TCP客户端模式
#define UDP_MODE    0x02    //UDP(广播)模式

/***************----- 端口的运行状态 -----***************/
unsigned char S0_State =0x00;    //端口0状态记录,1:端口完成初始化,2端口完成连接(可以正常传输数据)
#define S_INIT        0x01    //端口完成初始化
#define S_CONN        0x02    //端口完成连接,可以正常传输数据

/***************----- 端口收发数据的状态 -----***************/
unsigned char S0_Data=0x00;        //端口0接收和发送数据的状态,1:端口接收到数据,2:端口发送数据完成
#define S_RECEIVE     0x01    //端口接收到一个数据包
#define S_TRANSMITOK 0x02    //端口发送一个数据包完成

/***************----- 端口数据缓冲区 -----***************/
unsigned char Rx_Buffer[2048];    //端口接收数据缓冲区
unsigned char Tx_Buffer[2048];    //端口发送数据缓冲区

unsigned char W5500_Interrupt;    //W5500中断标志(0:无中断,1:有中断)

/*******************************************************************************
* 函数名  : W5500_GPIO_Configuration
* 描述    : W5500 GPIO初始化配置
* 输入    : 无
* 输出    : 无
* 返回值  : 无
* 说明    : 无
*******************************************************************************/
void W5500_GPIO_Configuration(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    EXTI_InitTypeDef  EXTI_InitStructure;    

    /* W5500_RST引脚初始化配置(PC5) */
    GPIO_InitStructure.GPIO_Pin  = W5500_RST;                   //pin 5
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;            //速率10MHZ
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        //推挽输出
    GPIO_Init(W5500_RST_PORT, &GPIO_InitStructure);            //PC
    GPIO_ResetBits(W5500_RST_PORT, W5500_RST);                   //默认PC5置低            
    
    /* W5500_INT引脚初始化配置(PC4) */    
    GPIO_InitStructure.GPIO_Pin = W5500_INT;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(W5500_INT_PORT, &GPIO_InitStructure);
        
    /* Connect EXTI Line4 to PC4 */
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource4);

    /* PC4 as W5500 interrupt input */
    EXTI_InitStructure.EXTI_Line = EXTI_Line4;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
}

/*******************************************************************************
* 函数名  : W5500_NVIC_Configuration
* 描述    : W5500 接收引脚中断优先级设置
* 输入    : 无
* 输出    : 无
* 返回值  : 无
* 说明    : 无
*******************************************************************************/
void W5500_NVIC_Configuration(void)
{
      NVIC_InitTypeDef NVIC_InitStructure;

    /* Enable the EXTI4 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

/*******************************************************************************
* 函数名  : EXTI4_IRQHandler
* 描述    : 中断线4中断服务函数(W5500 INT引脚中断服务函数)
* 输入    : 无
* 输出    : 无
* 返回值  : 无
* 说明    : 无
*******************************************************************************/
void EXTI4_IRQHandler(void)
{
    if(EXTI_GetITStatus(EXTI_Line4) != RESET)
    {
        EXTI_ClearITPendingBit(EXTI_Line4);
        W5500_Interrupt=1;
    }
}

/*******************************************************************************
* 函数名  : SPI_Configuration
* 描述    : W5500 SPI初始化配置(STM32 SPI1)
* 输入    : 无
* 输出    : 无
* 返回值  : 无
* 说明    : 无
*******************************************************************************/
void SPI_Configuration(void)
{
    GPIO_InitTypeDef     GPIO_InitStructure;
    SPI_InitTypeDef       SPI_InitStructure;       

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1 | RCC_APB2Periph_AFIO, ENABLE);    

    /* 初始化SCK、MISO、MOSI引脚 */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽   PA5,6,7
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);

    /* 初始化CS引脚 */
    GPIO_InitStructure.GPIO_Pin = W5500_SCS;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_Init(W5500_SCS_PORT, &GPIO_InitStructure);
    GPIO_SetBits(W5500_SCS_PORT, W5500_SCS);

    /* 初始化配置STM32 SPI1 */
    SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;    //SPI设置为双线双向全双工
    SPI_InitStructure.SPI_Mode=SPI_Mode_Master;                            //设置为主SPI
    SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;                        //SPI发送接收8位帧结构
    SPI_InitStructure.SPI_CPOL=SPI_CPOL_Low;                            //时钟悬空低
    SPI_InitStructure.SPI_CPHA=SPI_CPHA_1Edge;                            //数据捕获于第1个时钟沿
    SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;                                //NSS由外部管脚管理
    SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_2;    //波特率预分频值为2
    SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;                    //数据传输从MSB位开始
    SPI_InitStructure.SPI_CRCPolynomial=7;                                //CRC多项式为7
    SPI_Init(SPI1,&SPI_InitStructure);                                    //根据SPI_InitStruct中指定的参数初始化外设SPI1寄存器

    SPI_Cmd(SPI1,ENABLE);    //STM32使能SPI1
}

/*******************************************************************************
* 函数名  : SPI1_Send_Byte
* 描述    : SPI1发送1个字节数据
* 输入    : dat:待发送的数据
* 输出    : 无
* 返回值  : 无
* 说明    : 无
*******************************************************************************/
void SPI1_Send_Byte(unsigned char dat)
{
    SPI_I2S_SendData(SPI1,dat);//写1个字节数据
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);//等待数据寄存器空
}

/*******************************************************************************
* 函数名  : SPI1_Send_Short
* 描述    : SPI1发送2个字节数据(16位)
* 输入    : dat:待发送的16位数据
* 输出    : 无
* 返回值  : 无
* 说明    : 无
*******************************************************************************/
void SPI1_Send_Short(unsigned short dat)
{
    SPI1_Send_Byte(dat/256);//写数据高位
    SPI1_Send_Byte(dat);    //写数据低位
}

/*******************************************************************************
* 函数名  : Write_W5500_1Byte
* 描述    : 通过SPI1向指定地址寄存器写1个字节数据
* 输入    : reg:16位寄存器地址,dat:待写入的数据
* 输出    : 无
* 返回值  : 无
* 说明    : 无
*******************************************************************************/
void Write_W5500_1Byte(unsigned short reg, unsigned char dat)
{
    GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为低电平 PA4

    SPI1_Send_Short(reg);//通过SPI1写16位寄存器地址
    SPI1_Send_Byte(FDM1|RWB_WRITE|COMMON_R);//通过SPI1写控制字节,1个字节数据长度,写数据,选择通用寄存器
    SPI1_Send_Byte(dat);//写1个字节数据

    GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS为高电平
}

/*******************************************************************************
* 函数名  : Write_W5500_2Byte
* 描述    : 通过SPI1向指定地址寄存器写2个字节数据
* 输入    : reg:16位寄存器地址,dat:16位待写入的数据(2个字节)
* 输出    : 无
* 返回值  : 无
* 说明    : 无
*******************************************************************************/
void Write_W5500_2Byte(unsigned short reg, unsigned short dat)
{
    GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为低电平
        
    SPI1_Send_Short(reg);//通过SPI1写16位寄存器地址
    SPI1_Send_Byte(FDM2|RWB_WRITE|COMMON_R);//通过SPI1写控制字节,2个字节数据长度,写数据,选择通用寄存器
    SPI1_Send_Short(dat);//写16位数据

    GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS为高电平
}

/*******************************************************************************
* 函数名  : Write_W5500_nByte
* 描述    : 通过SPI1向指定地址寄存器写n个字节数据
* 输入    : reg:16位寄存器地址,*dat_ptr:待写入数据缓冲区指针,size:待写入的数据长度
* 输出    : 无
* 返回值  : 无
* 说明    : 无
*******************************************************************************/
void Write_W5500_nByte(unsigned short reg, unsigned char *dat_ptr, unsigned short size)
{
    unsigned short i;

    GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为低电平    
        
    SPI1_Send_Short(reg);//通过SPI1写16位寄存器地址
    SPI1_Send_Byte(VDM|RWB_WRITE|COMMON_R);//通过SPI1写控制字节,N个字节数据长度,写数据,选择通用寄存器

    for(i=0;i<size;i++)//循环将缓冲区的size个字节数据写入W5500
    {
        SPI1_Send_Byte(*dat_ptr++);//写一个字节数据
    }

    GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS为高电平
}

/*******************************************************************************
* 函数名  : Write_W5500_SOCK_1Byte
* 描述    : 通过SPI1向指定端口寄存器写1个字节数据
* 输入    : s:端口号,reg:16位寄存器地址,dat:待写入的数据
* 输出    : 无
* 返回值  : 无
* 说明    : 无
*******************************************************************************/
void Write_W5500_SOCK_1Byte(SOCKET s, unsigned short reg, unsigned char dat)
{
    GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为低电平    
        
    SPI1_Send_Short(reg);//通过SPI1写16位寄存器地址
    SPI1_Send_Byte(FDM1|RWB_WRITE|(s*0x20+0x08));//通过SPI1写控制字节,1个字节数据长度,写数据,选择端口s的寄存器
    SPI1_Send_Byte(dat);//写1个字节数据

    GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS为高电平
}

/*******************************************************************************
* 函数名  : Write_W5500_SOCK_2Byte
* 描述    : 通过SPI1向指定端口寄存器写2个字节数据
* 输入    : s:端口号,reg:16位寄存器地址,dat:16位待写入的数据(2个字节)
* 输出    : 无
* 返回值  : 无
* 说明    : 无
*******************************************************************************/
void Write_W5500_SOCK_2Byte(SOCKET s, unsigned short reg, unsigned short dat)
{
    GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为低电平
            
    SPI1_Send_Short(reg);//通过SPI1写16位寄存器地址
    SPI1_Send_Byte(FDM2|RWB_WRITE|(s*0x20+0x08));//通过SPI1写控制字节,2个字节数据长度,写数据,选择端口s的寄存器
    SPI1_Send_Short(dat);//写16位数据

    GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS为高电平
}

/*******************************************************************************
* 函数名  : Write_W5500_SOCK_4Byte
* 描述    : 通过SPI1向指定端口寄存器写4个字节数据
* 输入    : s:端口号,reg:16位寄存器地址,*dat_ptr:待写入的4个字节缓冲区指针
* 输出    : 无
* 返回值  : 无
* 说明    : 无
*******************************************************************************/
void Write_W5500_SOCK_4Byte(SOCKET s, unsigned short reg, unsigned char *dat_ptr)
{
    GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为低电平
            
    SPI1_Send_Short(reg);//通过SPI1写16位寄存器地址
    SPI1_Send_Byte(FDM4|RWB_WRITE|(s*0x20+0x08));//通过SPI1写控制字节,4个字节数据长度,写数据,选择端口s的寄存器

    SPI1_Send_Byte(*dat_ptr++);//写第1个字节数据
    SPI1_Send_Byte(*dat_ptr++);//写第2个字节数据
    SPI1_Send_Byte(*dat_ptr++);//写第3个字节数据
    SPI1_Send_Byte(*dat_ptr++);//写第4个字节数据

    GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS为高电平
}

/*******************************************************************************
* 函数名  : Read_W5500_1Byte
* 描述    : 读W5500指定地址寄存器的1个字节数据
* 输入    : reg:16位寄存器地址
* 输出    : 无
* 返回值  : 读取到寄存器的1个字节数据
* 说明    : 无
*******************************************************************************/
unsigned char Read_W5500_1Byte(unsigned short reg)
{
    unsigned char i;

    GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为低电平
            
    SPI1_Send_Short(reg);//通过SPI1写16位寄存器地址
    SPI1_Send_Byte(FDM1|RWB_READ|COMMON_R);//通过SPI1写控制字节,1个字节数据长度,读数据,选择通用寄存器

    i=SPI_I2S_ReceiveData(SPI1);
    SPI1_Send_Byte(0x00);//发送一个哑数据
    i=SPI_I2S_ReceiveData(SPI1);//读取1个字节数据

    GPIO_SetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为高电平
    return i;//返回读取到的寄存器数据
}

/*******************************************************************************
* 函数名  : Read_W5500_SOCK_1Byte
* 描述    : 读W5500指定端口寄存器的1个字节数据
* 输入    : s:端口号,reg:16位寄存器地址
* 输出    : 无
* 返回值  : 读取到寄存器的1个字节数据
* 说明    : 无
*******************************************************************************/
unsigned char Read_W5500_SOCK_1Byte(SOCKET s, unsigned short reg)
{
    unsigned char i;

    GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为低电平
            
    SPI1_Send_Short(reg);//通过SPI1写16位寄存器地址
    SPI1_Send_Byte(FDM1|RWB_READ|(s*0x20+0x08));//通过SPI1写控制字节,1个字节数据长度,读数据,选择端口s的寄存器

    i=SPI_I2S_ReceiveData(SPI1);
    SPI1_Send_Byte(0x00);//发送一个哑数据
    i=SPI_I2S_ReceiveData(SPI1);//读取1个字节数据

    GPIO_SetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为高电平
    return i;//返回读取到的寄存器数据
}

/*******************************************************************************
* 函数名  : Read_W5500_SOCK_2Byte
* 描述    : 读W5500指定端口寄存器的2个字节数据
* 输入    : s:端口号,reg:16位寄存器地址
* 输出    : 无
* 返回值  : 读取到寄存器的2个字节数据(16位)
* 说明    : 无
*******************************************************************************/
unsigned short Read_W5500_SOCK_2Byte(SOCKET s, unsigned short reg)
{
    unsigned short i;

    GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为低电平
            
    SPI1_Send_Short(reg);//通过SPI1写16位寄存器地址
    SPI1_Send_Byte(FDM2|RWB_READ|(s*0x20+0x08));//通过SPI1写控制字节,2个字节数据长度,读数据,选择端口s的寄存器

    i=SPI_I2S_ReceiveData(SPI1);
    SPI1_Send_Byte(0x00);//发送一个哑数据
    i=SPI_I2S_ReceiveData(SPI1);//读取高位数据
    SPI1_Send_Byte(0x00);//发送一个哑数据
    i*=256;
    i+=SPI_I2S_ReceiveData(SPI1);//读取低位数据

    GPIO_SetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为高电平
    return i;//返回读取到的寄存器数据
}

/*******************************************************************************
* 函数名  : Read_SOCK_Data_Buffer
* 描述    : 从W5500接收数据缓冲区中读取数据
* 输入    : s:端口号,*dat_ptr:数据保存缓冲区指针
* 输出    : 无
* 返回值  : 读取到的数据长度,rx_size个字节
* 说明    : 无
*******************************************************************************/
unsigned short Read_SOCK_Data_Buffer(SOCKET s, unsigned char *dat_ptr)
{
    unsigned short rx_size;
    unsigned short offset, offset1;
    unsigned short i;
    unsigned char j;

    rx_size=Read_W5500_SOCK_2Byte(s,Sn_RX_RSR);
    if(rx_size==0) return 0;//没接收到数据则返回
    if(rx_size>1460) rx_size=1460;

    offset=Read_W5500_SOCK_2Byte(s,Sn_RX_RD);
    offset1=offset;
    offset&=(S_RX_SIZE-1);//计算实际的物理地址

    GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为低电平

    SPI1_Send_Short(offset);//写16位地址
    SPI1_Send_Byte(VDM|RWB_READ|(s*0x20+0x18));//写控制字节,N个字节数据长度,读数据,选择端口s的寄存器
    j=SPI_I2S_ReceiveData(SPI1);
    
    if((offset+rx_size)<S_RX_SIZE)//如果最大地址未超过W5500接收缓冲区寄存器的最大地址
    {
        for(i=0;i<rx_size;i++)//循环读取rx_size个字节数据
        {
            SPI1_Send_Byte(0x00);//发送一个哑数据
            j=SPI_I2S_ReceiveData(SPI1);//读取1个字节数据
            *dat_ptr=j;//将读取到的数据保存到数据保存缓冲区
            dat_ptr++;//数据保存缓冲区指针地址自增1
        }
    }
    else//如果最大地址超过W5500接收缓冲区寄存器的最大地址
    {
        offset=S_RX_SIZE-offset;
        for(i=0;i<offset;i++)//循环读取出前offset个字节数据
        {
            SPI1_Send_Byte(0x00);//发送一个哑数据
            j=SPI_I2S_ReceiveData(SPI1);//读取1个字节数据
            *dat_ptr=j;//将读取到的数据保存到数据保存缓冲区
            dat_ptr++;//数据保存缓冲区指针地址自增1
        }
        GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS为高电平

        GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为低电平

        SPI1_Send_Short(0x00);//写16位地址
        SPI1_Send_Byte(VDM|RWB_READ|(s*0x20+0x18));//写控制字节,N个字节数据长度,读数据,选择端口s的寄存器
        j=SPI_I2S_ReceiveData(SPI1);

        for(;i<rx_size;i++)//循环读取后rx_size-offset个字节数据
        {
            SPI1_Send_Byte(0x00);//发送一个哑数据
            j=SPI_I2S_ReceiveData(SPI1);//读取1个字节数据
            *dat_ptr=j;//将读取到的数据保存到数据保存缓冲区
            dat_ptr++;//数据保存缓冲区指针地址自增1
        }
    }
    GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS为高电平

    offset1+=rx_size;//更新实际物理地址,即下次读取接收到的数据的起始地址
    Write_W5500_SOCK_2Byte(s, Sn_RX_RD, offset1);
    Write_W5500_SOCK_1Byte(s, Sn_CR, RECV);//发送启动接收命令
    return rx_size;//返回接收到数据的长度
}

/*******************************************************************************
* 函数名  : Write_SOCK_Data_Buffer
* 描述    : 将数据写入W5500的数据发送缓冲区
* 输入    : s:端口号,*dat_ptr:数据保存缓冲区指针,size:待写入数据的长度
* 输出    : 无
* 返回值  : 无
* 说明    : 无
*******************************************************************************/
void Write_SOCK_Data_Buffer(SOCKET s, unsigned char *dat_ptr, unsigned short size)
{
    unsigned short offset,offset1;
    unsigned short i;

    //如果是UDP模式,可以在此设置目的主机的IP和端口号
    if((Read_W5500_SOCK_1Byte(s,Sn_MR)&0x0f) != SOCK_UDP)//如果Socket打开失败
    {        
        Write_W5500_SOCK_4Byte(s, Sn_DIPR, UDP_DIPR);//设置目的主机IP          
        Write_W5500_SOCK_2Byte(s, Sn_DPORTR, UDP_DPORT[0]*256+UDP_DPORT[1]);//设置目的主机端口号                
    }

    offset=Read_W5500_SOCK_2Byte(s,Sn_TX_WR);
    offset1=offset;
    offset&=(S_TX_SIZE-1);//计算实际的物理地址

    GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为低电平

    SPI1_Send_Short(offset);//写16位地址
    SPI1_Send_Byte(VDM|RWB_WRITE|(s*0x20+0x10));//写控制字节,N个字节数据长度,写数据,选择端口s的寄存器

    if((offset+size)<S_TX_SIZE)//如果最大地址未超过W5500发送缓冲区寄存器的最大地址
    {
        for(i=0;i<size;i++)//循环写入size个字节数据
        {
            SPI1_Send_Byte(*dat_ptr++);//写入一个字节的数据        
        }
    }
    else//如果最大地址超过W5500发送缓冲区寄存器的最大地址
    {
        offset=S_TX_SIZE-offset;
        for(i=0;i<offset;i++)//循环写入前offset个字节数据
        {
            SPI1_Send_Byte(*dat_ptr++);//写入一个字节的数据
        }
        GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS为高电平

        GPIO_ResetBits(W5500_SCS_PORT, W5500_SCS);//置W5500的SCS为低电平

        SPI1_Send_Short(0x00);//写16位地址
        SPI1_Send_Byte(VDM|RWB_WRITE|(s*0x20+0x10));//写控制字节,N个字节数据长度,写数据,选择端口s的寄存器

        for(;i<size;i++)//循环写入size-offset个字节数据
        {
            SPI1_Send_Byte(*dat_ptr++);//写入一个字节的数据
        }
    }
    GPIO_SetBits(W5500_SCS_PORT, W5500_SCS); //置W5500的SCS为高电平

    offset1+=size;//更新实际物理地址,即下次写待发送数据到发送数据缓冲区的起始地址
    Write_W5500_SOCK_2Byte(s, Sn_TX_WR, offset1);
    Write_W5500_SOCK_1Byte(s, Sn_CR, SEND);//发送启动发送命令                
}

/*******************************************************************************
* 函数名  : W5500_Hardware_Reset
* 描述    : 硬件复位W5500
* 输入    : 无
* 输出    : 无
* 返回值  : 无
* 说明    : W5500的复位引脚保持低电平至少500us以上,才能重围W5500
*******************************************************************************/
void W5500_Hardware_Reset(void)
{
    GPIO_ResetBits(W5500_RST_PORT, W5500_RST);//复位引脚拉低
    delay_ms(100);
    GPIO_SetBits(W5500_RST_PORT, W5500_RST);//复位引脚拉高
    delay_ms(200);
    while((Read_W5500_1Byte(PHYCFGR)&LINK)==0);//等待以太网连接完成
}

/*******************************************************************************
* 函数名  : W5500_Init
* 描述    : 初始化W5500寄存器函数
* 输入    : 无
* 输出    : 无
* 返回值  : 无
* 说明    : 在使用W5500之前,先对W5500初始化
*******************************************************************************/
void W5500_Init(void)
{
    u8 i=0;

    Write_W5500_1Byte(MR, RST);//软件复位W5500,置1有效,复位后自动清0
    delay_ms(20);//延时10ms,自己定义该函数

    //设置网关(Gateway)的IP地址,Gateway_IP为4字节unsigned char数组,自己定义
    //使用网关可以使通信突破子网的局限,通过网关可以访问到其它子网或进入Internet
    Write_W5500_nByte(GAR, Gateway_IP, 4);
            
    //设置子网掩码(MASK)值,SUB_MASK为4字节unsigned char数组,自己定义
    //子网掩码用于子网运算
    Write_W5500_nByte(SUBR,Sub_Mask,4);        
    
    //设置物理地址,PHY_ADDR为6字节unsigned char数组,自己定义,用于唯一标识网络设备的物理地址值
    //该地址值需要到IEEE申请,按照OUI的规定,前3个字节为厂商代码,后三个字节为产品序号
    //如果自己定义物理地址,注意第一个字节必须为偶数
    Write_W5500_nByte(SHAR,Phy_Addr,6);        

    //设置本机的IP地址,IP_ADDR为4字节unsigned char数组,自己定义
    //注意,网关IP必须与本机IP属于同一个子网,否则本机将无法找到网关
    Write_W5500_nByte(SIPR,IP_Addr,4);        
    
    //设置发送缓冲区和接收缓冲区的大小,参考W5500数据手册
    for(i=0;i<8;i++)
    {
        Write_W5500_SOCK_1Byte(i,Sn_RXBUF_SIZE, 0x02);//Socket Rx memory size=2k
        Write_W5500_SOCK_1Byte(i,Sn_TXBUF_SIZE, 0x02);//Socket Tx mempry size=2k
    }

    //设置重试时间,默认为2000(200ms)
    //每一单位数值为100微秒,初始化时值设为2000(0x07D0),等于200毫秒
    Write_W5500_2Byte(RTR, 0x07d0);

    //设置重试次数,默认为8次
    //如果重发的次数超过设定值,则产生超时中断(相关的端口中断寄存器中的Sn_IR 超时位(TIMEOUT)置“1”)
    Write_W5500_1Byte(RCR,8);

    //启动中断,参考W5500数据手册确定自己需要的中断类型
    //IMR_CONFLICT是IP地址冲突异常中断,IMR_UNREACH是UDP通信时,地址无法到达的异常中断
    //其它是Socket事件中断,根据需要添加
    Write_W5500_1Byte(IMR,IM_IR7 | IM_IR6);
    Write_W5500_1Byte(SIMR,S0_IMR);
    Write_W5500_SOCK_1Byte(0, Sn_IMR, IMR_SENDOK | IMR_TIMEOUT | IMR_RECV | IMR_DISCON | IMR_CON);
}

/*******************************************************************************
* 函数名  : Detect_Gateway
* 描述    : 检查网关服务器
* 输入    : 无
* 输出    : 无
* 返回值  : 成功返回TRUE(0xFF),失败返回FALSE(0x00)
* 说明    : 无
*******************************************************************************/
unsigned char Detect_Gateway(void)
{
    unsigned char ip_adde[4];
    ip_adde[0]=IP_Addr[0]+1;
    ip_adde[1]=IP_Addr[1]+1;
    ip_adde[2]=IP_Addr[2]+1;
    ip_adde[3]=IP_Addr[3]+1;

    //检查网关及获取网关的物理地址
    Write_W5500_SOCK_4Byte(0,Sn_DIPR,ip_adde);//向目的地址寄存器写入与本机IP不同的IP值
    Write_W5500_SOCK_1Byte(0,Sn_MR,MR_TCP);//设置socket为TCP模式
    Write_W5500_SOCK_1Byte(0,Sn_CR,OPEN);//打开Socket    
    delay_ms(5);//延时5ms     
    
    if(Read_W5500_SOCK_1Byte(0,Sn_SR) != SOCK_INIT)//如果socket打开失败
    {
        Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);//打开不成功,关闭Socket
        return FALSE;//返回FALSE(0x00)
    }

    Write_W5500_SOCK_1Byte(0,Sn_CR,CONNECT);//设置Socket为Connect模式                        

    do
    {
        u8 j=0;
        j=Read_W5500_SOCK_1Byte(0,Sn_IR);//读取Socket0中断标志寄存器
        if(j!=0)
        Write_W5500_SOCK_1Byte(0,Sn_IR,j);
        delay_ms(5);//延时5ms
        if((j&IR_TIMEOUT) == IR_TIMEOUT)
        {
            return FALSE;    
        }
        else if(Read_W5500_SOCK_1Byte(0,Sn_DHAR) != 0xff)
        {
            Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);//关闭Socket
            return TRUE;                            
        }
    }while(1);
}

/*******************************************************************************
* 函数名  : Socket_Init
* 描述    : 指定Socket(0~7)初始化
* 输入    : s:待初始化的端口
* 输出    : 无
* 返回值  : 无
* 说明    : 无
*******************************************************************************/
void Socket_Init(SOCKET s)
{
    //设置分片长度,参考W5500数据手册,该值可以不修改    
    Write_W5500_SOCK_2Byte(0, Sn_MSSR, 1460);//最大分片字节数=1460(0x5b4)
    //设置指定端口
    switch(s)
    {
        case 0:
            //设置端口0的端口号
            Write_W5500_SOCK_2Byte(0, Sn_PORT, S0_Port[0]*256+S0_Port[1]);
            //设置端口0目的(远程)端口号
            Write_W5500_SOCK_2Byte(0, Sn_DPORTR, S0_DPort[0]*256+S0_DPort[1]);
            //设置端口0目的(远程)IP地址
            Write_W5500_SOCK_4Byte(0, Sn_DIPR, S0_DIP);            
            
            break;

        case 1:
            break;

        case 2:
            break;

        case 3:
            break;

        case 4:
            break;

        case 5:
            break;

        case 6:
            break;

        case 7:
            break;

        default:
            break;
    }
}

/*******************************************************************************
* 函数名  : Socket_Connect
* 描述    : 设置指定Socket(0~7)为客户端与远程服务器连接
* 输入    : s:待设定的端口
* 输出    : 无
* 返回值  : 成功返回TRUE(0xFF),失败返回FALSE(0x00)
* 说明    : 当本机Socket工作在客户端模式时,引用该程序,与远程服务器建立连接
*            如果启动连接后出现超时中断,则与服务器连接失败,需要重新调用该程序连接
*            该程序每调用一次,就与服务器产生一次连接
*******************************************************************************/
unsigned char Socket_Connect(SOCKET s)
{
    Write_W5500_SOCK_1Byte(s,Sn_MR,MR_TCP);//设置socket为TCP模式
    Write_W5500_SOCK_1Byte(s,Sn_CR,OPEN);//打开Socket
    delay_ms(5);//延时5ms
    if(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_INIT)//如果socket打开失败
    {
        Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);//打开不成功,关闭Socket
        return FALSE;//返回FALSE(0x00)
    }
    Write_W5500_SOCK_1Byte(s,Sn_CR,CONNECT);//设置Socket为Connect模式
    return TRUE;//返回TRUE,设置成功
}

/*******************************************************************************
* 函数名  : Socket_Listen
* 描述    : 设置指定Socket(0~7)作为服务器等待远程主机的连接
* 输入    : s:待设定的端口
* 输出    : 无
* 返回值  : 成功返回TRUE(0xFF),失败返回FALSE(0x00)
* 说明    : 当本机Socket工作在服务器模式时,引用该程序,等等远程主机的连接
*            该程序只调用一次,就使W5500设置为服务器模式
*******************************************************************************/
unsigned char Socket_Listen(SOCKET s)
{
    Write_W5500_SOCK_1Byte(s,Sn_MR,MR_TCP);//设置socket为TCP模式
    Write_W5500_SOCK_1Byte(s,Sn_CR,OPEN);//打开Socket    
    delay_ms(5);//延时5ms
    if(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_INIT)//如果socket打开失败
    {
        Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);//打开不成功,关闭Socket
        return FALSE;//返回FALSE(0x00)
    }    
    Write_W5500_SOCK_1Byte(s,Sn_CR,LISTEN);//设置Socket为侦听模式    
    delay_ms(5);//延时5ms
    if(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_LISTEN)//如果socket设置失败
    {
        Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);//设置不成功,关闭Socket
        return FALSE;//返回FALSE(0x00)
    }

    return TRUE;

    //至此完成了Socket的打开和设置侦听工作,至于远程客户端是否与它建立连接,则需要等待Socket中断,
    //以判断Socket的连接是否成功。参考W5500数据手册的Socket中断状态
    //在服务器侦听模式不需要设置目的IP和目的端口号
}

/*******************************************************************************
* 函数名  : Socket_UDP
* 描述    : 设置指定Socket(0~7)为UDP模式
* 输入    : s:待设定的端口
* 输出    : 无
* 返回值  : 成功返回TRUE(0xFF),失败返回FALSE(0x00)
* 说明    : 如果Socket工作在UDP模式,引用该程序,在UDP模式下,Socket通信不需要建立连接
*            该程序只调用一次,就使W5500设置为UDP模式
*******************************************************************************/
unsigned char Socket_UDP(SOCKET s)
{
    Write_W5500_SOCK_1Byte(s,Sn_MR,MR_UDP);//设置Socket为UDP模式*/
    Write_W5500_SOCK_1Byte(s,Sn_CR,OPEN);//打开Socket*/
    delay_ms(5);//延时5ms
    if(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_UDP)//如果Socket打开失败
    {
        Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);//打开不成功,关闭Socket
        return FALSE;//返回FALSE(0x00)
    }
    else
        return TRUE;

    //至此完成了Socket的打开和UDP模式设置,在这种模式下它不需要与远程主机建立连接
    //因为Socket不需要建立连接,所以在发送数据前都可以设置目的主机IP和目的Socket的端口号
    //如果目的主机IP和目的Socket的端口号是固定的,在运行过程中没有改变,那么也可以在这里设置
}

/*******************************************************************************
* 函数名  : W5500_Interrupt_Process
* 描述    : W5500中断处理程序框架
* 输入    : 无
* 输出    : 无
* 返回值  : 无
* 说明    : 无
*******************************************************************************/
void W5500_Interrupt_Process(void)
{
    unsigned char i,j;

IntDispose:
    W5500_Interrupt=0;//清零中断标志
    i = Read_W5500_1Byte(IR);//读取中断标志寄存器
    Write_W5500_1Byte(IR, (i&0xf0));//回写清除中断标志

    if((i & CONFLICT) == CONFLICT)//IP地址冲突异常处理
    {
         //自己添加代码
    }

    if((i & UNREACH) == UNREACH)//UDP模式下地址无法到达异常处理
    {
        //自己添加代码
    }

    i=Read_W5500_1Byte(SIR);//读取端口中断标志寄存器    
    if((i & S0_INT) == S0_INT)//Socket0事件处理
    {
        j=Read_W5500_SOCK_1Byte(0,Sn_IR);//读取Socket0中断标志寄存器
        Write_W5500_SOCK_1Byte(0,Sn_IR,j);
        if(j&IR_CON)//在TCP模式下,Socket0成功连接
        {
            S0_State|=S_CONN;//网络连接状态0x02,端口完成连接,可以正常传输数据
        }
        if(j&IR_DISCON)//在TCP模式下Socket断开连接处理
        {
            Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);//关闭端口,等待重新打开连接
            Socket_Init(0);        //指定Socket(0~7)初始化,初始化端口0
            S0_State=0;//网络连接状态0x00,端口连接失败
        }
        if(j&IR_SEND_OK)//Socket0数据发送完成,可以再次启动S_tx_process()函数发送数据
        {
            S0_Data|=S_TRANSMITOK;//端口发送一个数据包完成
        }
        if(j&IR_RECV)//Socket接收到数据,可以启动S_rx_process()函数
        {
            S0_Data|=S_RECEIVE;//端口接收到一个数据包
        }
        if(j&IR_TIMEOUT)//Socket连接或数据传输超时处理
        {
            Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);// 关闭端口,等待重新打开连接
            S0_State=0;//网络连接状态0x00,端口连接失败
        }
    }

    if(Read_W5500_1Byte(SIR) != 0)
        goto IntDispose;
}

#ifndef    _W5500_H_
#define    _W5500_H_

/***************** Common Register *****************/
#define MR        0x0000
    #define RST        0x80
    #define WOL        0x20
    #define PB        0x10
    #define PPP        0x08
    #define FARP    0x02

#define GAR        0x0001
#define SUBR    0x0005
#define SHAR    0x0009
#define SIPR    0x000f

#define INTLEVEL    0x0013
#define IR        0x0015
    #define CONFLICT    0x80
    #define UNREACH        0x40
    #define PPPOE        0x20
    #define MP            0x10

#define IMR        0x0016
    #define IM_IR7        0x80
    #define IM_IR6        0x40
    #define IM_IR5        0x20
    #define IM_IR4        0x10

#define SIR        0x0017
    #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
    #define S7_IMR        0x80
    #define S6_IMR        0x40
    #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
#define PMAGIC    0x001d
#define PHA        0x001e
#define PSID    0x0024
#define PMRU    0x0026

#define UIPR    0x0028
#define UPORT    0x002c

#define PHYCFGR    0x002e
    #define RST_PHY        0x80
    #define OPMODE        0x40
    #define DPX            0x04
    #define SPD            0x02
    #define LINK        0x01

#define VERR    0x0039

/********************* Socket Register *******************/
#define Sn_MR        0x0000
    #define MULTI_MFEN        0x80
    #define BCASTB            0x40
    #define    ND_MC_MMB        0x20
    #define UCASTB_MIP6B    0x10
    #define MR_CLOSE        0x00
    #define MR_TCP        0x01
    #define MR_UDP        0x02
    #define MR_MACRAW        0x04

#define Sn_CR        0x0001
    #define OPEN        0x01
    #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
    #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
    #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
#define Sn_DHAR           0x0006
#define Sn_DIPR        0x000c
#define Sn_DPORTR    0x0010

#define Sn_MSSR        0x0012
#define Sn_TOS        0x0015
#define Sn_TTL        0x0016

#define Sn_RXBUF_SIZE    0x001e
#define Sn_TXBUF_SIZE    0x001f
#define Sn_TX_FSR    0x0020
#define Sn_TX_RD    0x0022
#define Sn_TX_WR    0x0024
#define Sn_RX_RSR    0x0026
#define Sn_RX_RD    0x0028
#define Sn_RX_WR    0x002a

#define Sn_IMR        0x002c
    #define IMR_SENDOK    0x10
    #define IMR_TIMEOUT    0x08
    #define IMR_RECV    0x04
    #define IMR_DISCON    0x02
    #define IMR_CON        0x01

#define Sn_FRAG        0x002d
#define Sn_KPALVTR    0x002f

/*******************************************************************/
/************************ 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_0    //定义W5500的RST引脚
#define W5500_RST_PORT    GPIOC

#define W5500_INT        GPIO_Pin_1    //定义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

 

 

回复评论 (3)

有人用这玩意儿做过项目么?稳定性咋样

点赞  2020-4-10 16:28

除了代码,有详细的介绍么

点赞  2020-4-10 22:56

代码不打包,看着好难受

点赞  2020-4-11 21:06
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复