说明

需要调整的内容为W5500.h中关于IP地址、端口号、子网掩码、网关等参数

W5500

#ifndef_W5500_H_

#define_W5500_H_

/****************** Parameter **********************/

//网关地址

#define GATEWAY_IP_0 125

#define GATEWAY_IP_1 217

#define GATEWAY_IP_2 54

#define GATEWAY_IP_3 254

#define SUB_MASK_0 255

#define SUB_MASK_1 255

#define SUB_MASK_2 255

#define SUB_MASK_3 0

#define PHY_ADDR_0 0x80

#define PHY_ADDR_1 0x9E

#define PHY_ADDR_2 0x01

#define PHY_ADDR_3 0x56

#define PHY_ADDR_4 0x37

#define PHY_ADDR_5 0xC6

//本机IP地址

#define IP_ADDR_0 125

#define IP_ADDR_1 217

#define IP_ADDR_2 54

#define IP_ADDR_3 55

//本机端口号

#define S0_PORT_0 0x13

#define S0_PORT_1 0x88

//UDP(广播)模式,目的主机IP地址

#define UDP_DIR_0 125

#define UDP_DIR_1 217

#define UDP_DIR_2 54

#define UDP_DIR_3 242

//UDP(广播)模式,目的主机端口号

#define UDP_DPORT_0 0x17

#define UDP_DPORT_1 0x75

//模式配置

#define S0_MODE UDP_MODE

/***************** Common Register *****************/

#define MR0x0000

#define RST0x80

#define WOL0x20

#define PB0x10

#define PPP0x08

#define FARP0x02

#define GAR0x0001

#define SUBR0x0005

#define SHAR0x0009

#define SIPR0x000f

#define INTLEVEL0x0013

#define IR0x0015

#define CONFLICT0x80

#define UNREACH0x40

#define PPPOE0x20

#define MP0x10

#define IMR0x0016

#define IM_IR70x80

#define IM_IR60x40

#define IM_IR50x20

#define IM_IR40x10

#define SIR0x0017

#define S7_INT0x80

#define S6_INT0x40

#define S5_INT0x20

#define S4_INT0x10

#define S3_INT0x08

#define S2_INT0x04

#define S1_INT0x02

#define S0_INT0x01

#define SIMR0x0018

#define S7_IMR0x80

#define S6_IMR0x40

#define S5_IMR0x20

#define S4_IMR0x10

#define S3_IMR0x08

#define S2_IMR0x04

#define S1_IMR0x02

#define S0_IMR0x01

#define RTR0x0019

#define RCR0x001b

#define PTIMER0x001c

#define PMAGIC0x001d

#define PHA0x001e

#define PSID0x0024

#define PMRU0x0026

#define UIPR0x0028

#define UPORT0x002c

#define PHYCFGR0x002e

#define RST_PHY0x80

#define OPMODE0x40

#define DPX0x04

#define SPD0x02

#define LINK0x01

#define VERR0x0039

/********************* Socket Register *******************/

#define Sn_MR0x0000

#define MULTI_MFEN0x80

#define BCASTB0x40

#defineND_MC_MMB0x20

#define UCASTB_MIP6B0x10

#define MR_CLOSE0x00

#define MR_TCP0x01

#define MR_UDP0x02

#define MR_MACRAW0x04

#define Sn_CR0x0001

#define OPEN0x01

#define LISTEN0x02

#define CONNECT0x04

#define DISCON0x08

#define CLOSE0x10

#define SEND0x20

#define SEND_MAC0x21

#define SEND_KEEP0x22

#define RECV0x40

#define Sn_IR0x0002

#define IR_SEND_OK0x10

#define IR_TIMEOUT0x08

#define IR_RECV0x04

#define IR_DISCON0x02

#define IR_CON0x01

#define Sn_SR0x0003

#define SOCK_CLOSED0x00

#define SOCK_INIT0x13

#define SOCK_LISTEN0x14

#define SOCK_ESTABLISHED0x17

#define SOCK_CLOSE_WAIT0x1c

#define SOCK_UDP0x22

#define SOCK_MACRAW0x02

#define SOCK_SYNSEND0x15

#define SOCK_SYNRECV0x16

#define SOCK_FIN_WAI0x18

#define SOCK_CLOSING0x1a

#define SOCK_TIME_WAIT0x1b

#define SOCK_LAST_ACK0x1d

#define Sn_PORT0x0004

#define Sn_DHAR 0x0006

#define Sn_DIPR0x000c

#define Sn_DPORTR0x0010

#define Sn_MSSR0x0012

#define Sn_TOS0x0015

#define Sn_TTL0x0016

#define Sn_RXBUF_SIZE0x001e

#define Sn_TXBUF_SIZE0x001f

#define Sn_TX_FSR0x0020

#define Sn_TX_RD0x0022

#define Sn_TX_WR0x0024

#define Sn_RX_RSR0x0026

#define Sn_RX_RD0x0028

#define Sn_RX_WR0x002a

#define Sn_IMR0x002c

#define IMR_SENDOK0x10

#define IMR_TIMEOUT0x08

#define IMR_RECV0x04

#define IMR_DISCON0x02

#define IMR_CON0x01

#define Sn_FRAG0x002d

#define Sn_KPALVTR0x002f

/*******************************************************************/

/************************ SPI Control Byte *************************/

/*******************************************************************/

/* Operation mode bits */

#define VDM0x00

#define FDM10x01

#defineFDM20x02

#define FDM40x03

/* Read_Write control bit */

#define RWB_READ0x00

#define RWB_WRITE0x04

/* Block select bits */

#define COMMON_R0x00

/* Socket 0 */

#define S0_REG0x08

#define S0_TX_BUF0x10

#define S0_RX_BUF0x18

/* Socket 1 */

#define S1_REG0x28

#define S1_TX_BUF0x30

#define S1_RX_BUF0x38

/* Socket 2 */

#define S2_REG0x48

#define S2_TX_BUF0x50

#define S2_RX_BUF0x58

/* Socket 3 */

#define S3_REG0x68

#define S3_TX_BUF0x70

#define S3_RX_BUF0x78

/* Socket 4 */

#define S4_REG0x88

#define S4_TX_BUF0x90

#define S4_RX_BUF0x98

/* Socket 5 */

#define S5_REG0xa8

#define S5_TX_BUF0xb0

#define S5_RX_BUF0xb8

/* Socket 6 */

#define S6_REG0xc8

#define S6_TX_BUF0xd0

#define S6_RX_BUF0xd8

/* Socket 7 */

#define S7_REG0xe8

#define S7_TX_BUF0xf0

#define S7_RX_BUF0xf8

#define TRUE0xff

#define FALSE0x00

#define S_RX_SIZE2048/*定义Socket接收缓冲区的大小,可以根据W5500_RMSR的设置修改 */

#define S_TX_SIZE2048 /*定义Socket发送缓冲区的大小,可以根据W5500_TMSR的设置修改 */

/***************----- W5500 GPIO定义 -----***************/

#define W5500_SCSGPIO_Pin_4//定义W5500的CS引脚

#define W5500_SCS_PORTGPIOA

#define W5500_RSTGPIO_Pin_0//定义W5500的RST引脚

#define W5500_RST_PORTGPIOB

#define W5500_INTGPIO_Pin_1//定义W5500的INT引脚

#define W5500_INT_PORTGPIOB

/***************----- 网络参数变量定义 -----***************/

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_SERVER0x00//TCP服务器模式

#define TCP_CLIENT0x01//TCP客户端模式

#define UDP_MODE0x02//UDP(广播)模式

/***************----- 端口的运行状态 -----***************/

extern unsigned char S0_State;//端口0状态记录,1:端口完成初始化,2端口完成连接(可以正常传输数据)

#define S_INIT0x01//端口完成初始化

#define S_CONN0x02//端口完成连接,可以正常传输数据

/***************----- 端口收发数据的状态 -----***************/

extern unsigned char S0_Data;//端口0接收和发送数据的状态,1:端口接收到数据,2:端口发送数据完成

#define S_RECEIVE0x01//端口接收到一个数据包

#define S_TRANSMITOK0x02//端口发送一个数据包完成

/***************----- 端口数据缓冲区 -----***************/

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中断处理程序框架

void NVIC_Configuration(void);

void RCC_Configuration(void);

void Timer2_Init_Config(void);

void SendData(unsigned char* data,int length);

void My_W5500_Init(void);

void W5500_Socket_Set(void);

void Process_Socket_Data(SOCKET s);

#endif

W5500.c

/**********************************************************************************

* 文件名 :W5500.c

* 描述 :W5500 驱动函数库

* 库版本 :ST_v3.5

**********************************************************************************/

#include "stm32f10x.h"

#include "stm32f10x_spi.h"

#include "W5500.h"

#include

/***************----- 网络参数变量定义 -----***************/

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_SERVER0x00//TCP服务器模式

#define TCP_CLIENT0x01//TCP客户端模式

#define UDP_MODE0x02//UDP(广播)模式

/***************----- 端口的运行状态 -----***************/

unsigned char S0_State =0;//端口0状态记录,1:端口完成初始化,2端口完成连接(可以正常传输数据)

#define S_INIT0x01//端口完成初始化

#define S_CONN0x02//端口完成连接,可以正常传输数据

/***************----- 端口收发数据的状态 -----***************/

unsigned char S0_Data;//端口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:有中断)

unsigned int Timer2_Counter=0; //Timer2定时器计数变量(ms)

unsigned int W5500_Send_Delay_Counter=0; //W5500发送延时计数变量(ms)

/*******************************************************************************

* 函数名 : W5500_GPIO_Configuration

* 描述 : W5500 GPIO初始化配置

* 输入 : 无

* 输出 : 无

* 返回值 : 无

* 说明 : 无

*******************************************************************************/

void W5500_GPIO_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/* W5500_RST引脚初始化配置(PC5) */

GPIO_InitStructure.GPIO_Pin = W5500_RST;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(W5500_RST_PORT, &GPIO_InitStructure);

GPIO_ResetBits(W5500_RST_PORT, W5500_RST);

}

/*******************************************************************************

* 函数名 : 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;

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为低电平

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

{

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)

{

for(i=0;i

{

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

{

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

{

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)

{

for(i=0;i

{

SPI1_Send_Byte(*dat_ptr++);//写入一个字节的数据

}

}

else//如果最大地址超过W5500发送缓冲区寄存器的最大地址

{

offset=S_TX_SIZE-offset;

for(i=0;i

{

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

{

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(50);

GPIO_SetBits(W5500_RST_PORT, W5500_RST);//复位引脚拉高

Delay(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(10);//延时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);

}

/*******************************************************************************

* 函数名 : 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(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(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]);

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(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(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(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(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:

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;

}

/*******************************************************************************

* 函数名 : NVIC_Configuration

* 描述 : STM32中断向量表配配置

* 输入 : 无

* 输出 : 无

* 返回值 : 无

* 说明 : 设置KEY1(PC11)的中断优先组

*******************************************************************************/

void NVIC_Configuration(void)

{

NVIC_InitTypeDef NVIC_InitStructure;//定义NVIC初始化结构体

/* Set the Vector Table base location at 0x08000000 */

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//设置中断优先级组为1,优先组(可设0~4位)

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//设置中断向量号

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//设置抢先优先级

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//设置响应优先级

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能NVIC

NVIC_Init(&NVIC_InitStructure);

}

/*******************************************************************************

* 函数名 : RCC_Configuration

* 描述 : 设置系统时钟为72MHZ(这个可以根据需要改)

* 输入 : 无

* 输出 : 无

* 返回值 : 无

* 说明 : STM32F107x和STM32F105x系列MCU与STM32F103x系列MCU时钟配置有所不同

*******************************************************************************/

void RCC_Configuration(void)

{

ErrorStatus HSEStartUpStatus; //外部高速时钟(HSE)的工作状态变量

RCC_DeInit(); //将所有与时钟相关的寄存器设置为默认值

RCC_HSEConfig(RCC_HSE_ON); //启动外部高速时钟HSE

HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待外部高速时钟(HSE)稳定

if(SUCCESS == HSEStartUpStatus) //如果外部高速时钟已经稳定

{

/* Enable Prefetch Buffer */

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Flash设置

/* Flash 2 wait state */

FLASH_SetLatency(FLASH_Latency_2);

RCC_HCLKConfig(RCC_SYSCLK_Div1); //设置AHB时钟等于系统时钟(1分频)/72MHZ

RCC_PCLK2Config(RCC_HCLK_Div1); //设置APB2时钟和HCLK时钟相等/72MHz(最大为72MHz)

RCC_PCLK1Config(RCC_HCLK_Div2); //设置APB1时钟是HCLK时钟的2分频/36MHz(最大为36MHz)

#ifndef STM32F10X_CL //如果使用的不是STM32F107x或STM32F105x系列MCU,PLL以下配置

RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //PLLCLK = 8MHz * 9 = 72 MHz

#else //如果使用的是STM32F107x或STM32F105x系列MCU,PLL以下配置

/***** 配置PLLx *****/

/* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */

RCC_PREDIV2Config(RCC_PREDIV2_Div5);

RCC_PLL2Config(RCC_PLL2Mul_8);

RCC_PLL2Cmd(ENABLE); //使能PLL2

while (RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET);//等待PLL2稳定

/* PLL configuration: PLLCLK = (PLL2 / 5) * 9 = 72 MHz */

RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);

RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);

#endif

RCC_PLLCmd(ENABLE); //使能PLL

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //等待PLL稳定

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //设置系统时钟的时钟源为PLL

while(RCC_GetSYSCLKSource() != 0x08); //检查系统的时钟源是否是PLL

RCC_ClockSecuritySystemCmd(ENABLE); //使能系统安全时钟

/* Enable peripheral clocks --------------------------------------------------*/

/* Enable I2C1 and I2C1 clock */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

/* Enable GPIOA GPIOB SPI1 and USART1 clocks */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB

| RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD

| RCC_APB2Periph_AFIO, ENABLE);

}

}

/*******************************************************************************

* 函数名 : Timer2_Init_Config

* 描述 : Timer2初始化配置

* 输入 : 无

* 输出 : 无

* 返回 : 无

* 说明 : 无

*******************************************************************************/

void Timer2_Init_Config(void)

{

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//使能Timer2时钟

TIM_TimeBaseStructure.TIM_Period = 9;//设置在下一个更新事件装入活动的自动重装载寄存器周期的值(计数到10为1ms)

TIM_TimeBaseStructure.TIM_Prescaler = 7199;//设置用来作为TIMx时钟频率除数的预分频值(10KHz的计数频率)

TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//设置时钟分割:TDTS = TIM_CKD_DIV1

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上计数模式

TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE ); //使能TIM2指定的中断

TIM_Cmd(TIM2, ENABLE); //使能TIMx外设

}

/*******************************************************************************

* 函数名 : TIM2_IRQHandler

* 描述 : 定时器2中断断服务函数

* 输入 : 无

* 输出 : 无

* 返回 : 无

* 说明 : 无

*******************************************************************************/

void TIM2_IRQHandler(void)

{

if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)

{

TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

Timer2_Counter++;

W5500_Send_Delay_Counter++;

}

}

/*******************************************************************************

* 函数名 : Delay

* 描述 : 延时函数(ms)

* 输入 : d:延时系数,单位为毫秒

* 输出 : 无

* 返回 : 无

* 说明 : 延时是利用Timer2定时器产生的1毫秒的计数来实现的

*******************************************************************************/

void Delay(unsigned int d)

{

Timer2_Counter=0;

while(Timer2_Counter < d);

}

/*******************************************************************************

* 函数名 : Delay

* 描述 : 延时函数(ms)

* 输入 : *data 数据指针

* length 字节数

* 输出 : 无

* 返回 : 无

*******************************************************************************/

void SendData(unsigned char *data,int length)

{

if(S0_State == (S_INIT|S_CONN))

{

S0_Data&=~S_TRANSMITOK;

memcpy(Tx_Buffer, data, length);

Write_SOCK_Data_Buffer(0, Tx_Buffer, length);

}

}

/*******************************************************************************

* 函数名 : MyW5500_Init

* 描述 : 集成化W5500初始函数

* 输出 : 无

* 返回 : 无

*******************************************************************************/

void My_W5500_Init(void)

{

RCC_Configuration();//设置系统时钟为72MHZ(这个可以根据需要改)

NVIC_Configuration();//STM32中断向量表配配置

SPI_Configuration();//W5500 SPI初始化配置(STM32 SPI1)

Timer2_Init_Config();//Timer2初始化配置

W5500_GPIO_Configuration();//W5500 GPIO初始化配置

/*Load_Net_Parameters*/

Gateway_IP[0] = GATEWAY_IP_0;//加载网关参数

Gateway_IP[1] = GATEWAY_IP_1;

Gateway_IP[2] = GATEWAY_IP_2;

Gateway_IP[3] = GATEWAY_IP_3;

Sub_Mask[0]=SUB_MASK_0;//加载子网掩码

Sub_Mask[1]=SUB_MASK_1;

Sub_Mask[2]=SUB_MASK_2;

Sub_Mask[3]=SUB_MASK_3;

Phy_Addr[0]=PHY_ADDR_0;//加载物理地址

Phy_Addr[1]=PHY_ADDR_1;

Phy_Addr[2]=PHY_ADDR_2;

Phy_Addr[3]=PHY_ADDR_3;

Phy_Addr[4]=PHY_ADDR_4;

Phy_Addr[5]=PHY_ADDR_5;

IP_Addr[0]=IP_ADDR_0;//加载本机IP地址

IP_Addr[1]=IP_ADDR_1;

IP_Addr[2]=IP_ADDR_2;

IP_Addr[3]=IP_ADDR_3;

S0_Port[0] = S0_PORT_0;//加载端口0的端口号5000

S0_Port[1] = S0_PORT_1;

UDP_DIPR[0] = UDP_DIR_0;//UDP(广播)模式,目的主机IP地址

UDP_DIPR[1] = UDP_DIR_1;

UDP_DIPR[2] = UDP_DIR_2;

UDP_DIPR[3] = UDP_DIR_3;

UDP_DPORT[0] = UDP_DPORT_0;//UDP(广播)模式,目的主机端口号

UDP_DPORT[1] = UDP_DPORT_1;

S0_Mode=UDP_MODE;//加载端口0的工作模式,UDP模式

W5500_Hardware_Reset();

W5500_Init();//初始化W5500寄存器函数

Detect_Gateway();//检查网关服务器

Socket_Init(0);//指定Socket(0~7)初始化,初始化端口0

}

/*******************************************************************************

* 函数名 : W5500_Socket_Set

* 描述 : W5500端口初始化配置

* 输入 : 无

* 输出 : 无

* 返回值 : 无

* 说明 : 分别设置4个端口,根据端口工作模式,将端口置于TCP服务器、TCP客户端或UDP模式.

*从端口状态字节Socket_State可以判断端口的工作情况

*******************************************************************************/

void W5500_Socket_Set(void)

{

if(S0_State==0)//端口0初始化配置

{

if(S0_Mode==TCP_SERVER)//TCP服务器模式

{

if(Socket_Listen(0)==TRUE)

S0_State=S_INIT;

else

S0_State=0;

}

else if(S0_Mode==TCP_CLIENT)//TCP客户端模式

{

if(Socket_Connect(0)==TRUE)

S0_State=S_INIT;

else

S0_State=0;

}

else//UDP模式

{

if(Socket_UDP(0)==TRUE)

S0_State=S_INIT|S_CONN;

else

S0_State=0;

}

}

}

/*******************************************************************************

* 函数名 : Process_Socket_Data

* 描述 : W5500接收并发送接收到的数据

* 输入 : s:端口号

* 输出 : 无

* 返回值 : 无

* 说明 : 本过程先调用S_rx_process()从W5500的端口接收数据缓冲区读取数据,

*然后将读取的数据从Rx_Buffer拷贝到Temp_Buffer缓冲区进行处理。

*处理完毕,将数据从Temp_Buffer拷贝到Tx_Buffer缓冲区。调用S_tx_process()

*发送数据。

*******************************************************************************/

void Process_Socket_Data(SOCKET s)

{

unsigned short size;

size=Read_SOCK_Data_Buffer(s, Rx_Buffer);

memcpy(Tx_Buffer, Rx_Buffer+8, size-8);

Write_SOCK_Data_Buffer(s, Tx_Buffer, size);

}

使用方法

W5500_Socket_Set(); //W5500端口初始化

W5500_Interrupt_Process(); //W5500中断处理程序框架

if((S0_Data & S_RECEIVE) == S_RECEIVE) //如果Socket0接收到数据

{

S0_Data&=~S_RECEIVE;

Read_SOCK_Data_Buffer(0, Rx_Buffer); //读取数据,返回值为数据长度

}

注意Rx_Buffer[0]~Rx_Buffer[7]为地址头(具体可参照UDP协议),真正的数据从Rx_Buffer[8]开始

w5500跨网段_基于STM32F1的局域网通信模块W5500驱动相关推荐

  1. w5500跨网段_串口转以太网模块—W5500S2E-S1如何与计算机建立局域网

    前面已经给大家介绍了关于W5500S2E-S1的相关功能和特性,想必大家对S2E模块都有了一个大概的了解,那么如何具体使用S2E模块呢? 因为S2E模块是一款联网模块,它的主要功能是实现串口和网口之间 ...

  2. php跨网段获取mac地址吗,局域网IP地址和MAC地址绑定,跨网段IP-MAC绑定。

    局域网的IP地址和MAC地址绑定,一般选择在交换机或者路由器上进行配置.交换机的IP-MAC地址绑定一般是基于端口的.主要用于绑定各个交换机端口的IP地址/MAC地址.支持该功能的交换机不多,配置和维 ...

  3. 基于tutk方案的p2p源码_基于JAVA的局域网文件共享平台P2P实训项目源码(毕业设计 课程设计)...

    [实例简介] 基于JAVA的局域网文件共享平台P2P实训项目源码(毕业设计 课程设计). 可直接运行.做毕业设计.课程设计或者想研究下技术的可以下载学习.需要更多资源的可以关注我. [实例截图] [核 ...

  4. 基于java的局域网教学管理系统_基于jsp的局域网教学系统B-JavaEE实现局域网教学系统B - java项目源码...

    基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的局域网教学系统B, 该项目可用各类java课程设计大作业中, 局域网教学系统B的系统架构分为前后台两部分, 最终实 ...

  5. 基于STM32F1的时钟芯片DS1302驱动

    目录 DS1302.h源代码 DS1302.c源代码 DS1302.h源代码 /************************************************************ ...

  6. qt中socket通信流程图_基于Qt的局域网通信设计说明书.doc

    文档控制记录 序号版本日期修改内容修改人审批人1V1.02017-04-24创建2 目录目录4 辅助功能设计14 1目的 本文主要介绍利用Qt实现局域网通信的主要实现流程和一些技术知识点的设计说明. ...

  7. python arp扫描_基于python的局域网arp扫描

    ARP协议 ARP 协议也叫做地址解析协议,就是IP地址转换成MAC地址的协议 原理:在局域网内广播,向所有的主机发送包含目标IP地址的请求报文,如果该IP地址的主机接到了报文,那么就会将自己的MAC ...

  8. java制作局域网聊天器_基于Java的局域网聊天工具

    一 需求分析 掌握Java语言的程序设计方法,理论结合实际操作巩固我们所学的现有知识,使用图形用户界面和socket通信实现一个聊天程序,充分利用线程知识,实现用一个局域网聊天室,同时学会处理各种异常 ...

  9. ARP 协议工作原理(同网段及跨网段)

    目录 一.ARP简介 二.ARP的工作原理 三.ARP协议在同网段工作原理 四.ARP协议在不同网段工作原理 一.ARP简介 ARP全称是"Address Resolution Protoc ...

最新文章

  1. LeetCode之Island Perimeter
  2. 进程线程协程-基本概念及特点
  3. mybatis查询返回null的原因_可怕!你没看错,这次确实是纯手工实现一个MyBatis框架...
  4. 事务的隔离级别 数据库
  5. [转]Kaldi语音识别
  6. shiro自定义logout filter
  7. Mac电脑很早以前就删除的信息,现在想要恢复该怎么做?
  8. cygwin下载可以用的服务器
  9. POJThe Doors AND NYIST 有趣的问题
  10. 嵌入式ARM(Allwinner H3)下使用rtl8188eus无线网卡
  11. android端的声音检测程序(检测声音分贝大小)
  12. Springboot链接SqlServer配置并通过JPA操作实战
  13. 如何批量导出QQ空间相册到电脑中
  14. c语言怎么做查询系统,c语言编辑查询系统,可实现增删改查
  15. roblox虚拟世界怎么做服务器,roblox虚拟世界
  16. c语言if语句后的一对圆括号,在C语言中,紧跟在关键字if后一对圆括号里的表达式()...
  17. 南京工业大学python课件_南京工业大学-NJUT.ppt
  18. 如何创建网站?网站制作基本流程详解
  19. 计算机局域网采用的数据传输系统,两台win7系统电脑怎么使用局域网传输文件...
  20. VSCode生产工具详细配置

热门文章

  1. 理解计算:从√2到AlphaGo ——第1季 从√2谈起
  2. mkv视频文件怎么转成mp4,这3个方法很好用
  3. 移动flexe小颗粒
  4. 【单片机项目】制作一辆基于STM32的智能小车——A4950电机驱动
  5. java并发编程实战wwj--------------------第二阶段------------Balking------------------29-30
  6. [rust学习笔记]数据类型
  7. 无胁科技-TVD每日漏洞情报-2022-10-24
  8. 20230516(2)
  9. Android正则校验16进制颜色码
  10. 数学建模层次分析法一致性检验建立