STM32驱动W5100实现udp通信

本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.

环境:

主机:WIN7

开发环境:MDK4.72

MCU:STM32F103ZE

源代码:

驱动层代码:

drv_w5100.h

/*********************************************************************
*                               w5100驱动层头文件
*                             (c)copyright 2013,jdh
*                               All Right Reserved
*文件名:drv_w5100.h
*程序员:jdh
*修改日期:2013/10/22
*         2013/10/23
*         2013/10/24
**********************************************************************/
/*********************************************************************
硬件连接说明
电路标号            单片机引脚       特殊功能
W5100_MISO          PB4             SPI3_MISO
W5100_MOSI          PB5             SPI3_MOSI
W5100_CS            PA15            SPI3_NSS
W5100_SCLK          PB3             SPI3_SCK
/RESET              PD3
/INT                PD6
**********************************************************************/#ifndef _DRV_W5100_H_
#define _DRV_W5100_H_/*********************************************************************
*                           头文件
**********************************************************************/#include "stm32f10x.h"
#include "stm32f10x_spi.h"/*********************************************************************
*                           宏定义
**********************************************************************//*********************************************************************
*                           读写操作
**********************************************************************///写操作
#define WRITE_COMMAND           0xf0
//读操作
#define READ_COMMAND            0x0f    /*********************************************************************
*                           基地址
**********************************************************************/#define  COMMON_BASE 0x0000          /*********************************************************************
*                           寄存器
**********************************************************************///-----------------------------------------------------------------------------
//                               Common register
//-----------------------------------------------------------------------------
//Mode register, R/W, Default=0x00
#define SOCKET0       0
#define SOCKET1       1
#define SOCKET2       2
#define SOCKET3       3#define TCP_SERVER    0
#define TCP_CLIENT    1
#define UDP           2#define W5100_MODE   COMMON_BASE#define MODE_RST 0x80        //Software reset#define MODE_PB     0x10        //Ping block mode#define MODE_PPPOE 0x08        //PPOE mode#define MODE_AI      0x02        //Address auto increment in indirect bus I/F#define MODE_IND    0x01        //Indirect bus I/F mode//Gateway address register, R/W, default=0x00
#define W5100_GAR   COMMON_BASE+0x01//Subnet mask address, R/W, default=0x00
#define W5100_SUBR  COMMON_BASE+0x05//Source hardware address, R/W, default=0x00
#define W5100_SHAR  COMMON_BASE+0x09//Source IP address, R/W, default=0x00
#define W5100_SIPR  COMMON_BASE+0x0f//Interrupt and interrupt mask register
#define W5100_IR    COMMON_BASE+0x15   //RO, Default=0x00#define IR_CONFLICT  0x80        //IP conflict#define IR_UNREACH 0x40        //Destination unreachable#define IR_PPPOE   0x20        //PPOE close#define IR_S3_INT   0x08        //Occurrence of socket 3 socket interrupt#define IR_S2_INT  0x04        //Occurrence of socket 2 socket interrupt#define IR_S1_INT  0x02        //Occurrence of socket 1 socket interrupt#define IR_S0_INT  0x01        //Occurrence of socket 0 socket interrupt#define    W5100_IMR   COMMON_BASE+0x16   //R/W, Default=0x00#define IMR_CONFLICT    0x80        //IP conflict#define IMR_UNREACH    0x40        //Destination unreachable#define IMR_PPPOE  0x20        //PPOE close#define IMR_S3_INT  0x08        //Occurrence of socket 3 socket interrupt#define IMR_S2_INT 0x04        //Occurrence of socket 2 socket interrupt#define IMR_S1_INT 0x02        //Occurrence of socket 1 socket interrupt#define IMR_S0_INT 0x01        //Occurrence of socket 0 socket interrupt//Retry time value. Value 1 means 100us, R/W, default=0x07D0
#define W5100_RTR   COMMON_BASE+0x17//Retry count, R/W, Default=0x08
#define W5100_RCR   COMMON_BASE+0X19//RX memory size register, R/W, default=0x55
//--------------------------------------------------------    S1      S0      Memory size
//  Socket3    |  Socket2    |  Socket1    |  Socket0    |    0       0           1KB
//-------------|-------------|-------------|-------------|    0       1           2KB
//S1       S0  |S1       S0  |S1       S0  |S1       S0  |    1       0           4KB
//--------------------------------------------------------    1       1           8KB
#define W5100_RMSR  COMMON_BASE+0x1a//TX memory size register, R/W, default=0x55
#define W5100_TMSR  COMMON_BASE+0x1b//Authentication type in PPPOE mode, R, default=0x0000
#define W5100_PATR  COMMON_BASE+0x1c//PPP LCP request timer register, R/W, default=0x28
//Value 1 is about 25ms
#define W5100_PTIMER    COMMON_BASE+0x28//PPP LCP magic number register, R/W, default=0x00
#define W5100_PMAGIC    COMMON_BASE+0x29//Unreachable IP address, RO, default=0x00
#define W5100_UIPR  COMMON_BASE+0x2a//Unreachable port register, RO, default=0x0000
#define W5100_UPORT COMMON_BASE+0x2e//-----------------------------------------------------------------------------
//                                  Socket register
//-----------------------------------------------------------------------------
//Socket mode register, R/W, default=0x00
#define W5100_S0_MR COMMON_BASE+0x0400     //Socket 0
#define W5100_S1_MR COMMON_BASE+0x0500     //Socket 1
#define W5100_S2_MR COMMON_BASE+0x0600     //Socket 2
#define W5100_S3_MR COMMON_BASE+0x0700     //Socket 3#define S_MR_MULTI    0x80            //Multcasting#define S_MR_MC        0x20            //Multcast//  P3   P2   P1   P0     Meaning#define S_MR_CLOSED      0x00        //  0    0    0    0      Closed#define S_MR_TCP        0x01        //  0    0    0    1      TCP#define S_MR_UDP       0x02        //  0    0    1    0      UDP#define S_MR_IPRAW     0x03        //  0    0    1    1      IPRAW#define S_MR_MACRAW      0x04        //  0    1    0    0      MACRAW#define S_MR_PPPOE      0x05        //  0    1    0    1      PPPOE//Socket command register, R/W, default=0x00
#define W5100_S0_CR COMMON_BASE+0x0401     //Socket 0
#define W5100_S1_CR COMMON_BASE+0x0501     //Socket 1
#define W5100_S2_CR COMMON_BASE+0x0601     //Socket 2
#define W5100_S3_CR COMMON_BASE+0x0701     //Socket 3#define S_CR_OPEN     0x01        //It is used to initialize the socket#define S_CR_LISTEN        0x02        //In TCP mode, it waits for a connection request from any remote peer(Client)#define S_CR_CONNECT   0x04        //In TCP mode, it sends a connection request to remote peer(SERVER)#define S_CR_DISCON      0x08        //In TCP mode, it sends a connection termination request#define S_CR_CLOSE      0x10        //Used to close the socket#define S_CR_SEND     0x20        //It transmit the data as much as the increase size of write pointer#define S_CR_SEND_MAC   0x21        //In UDP mode, same as SEND#define S_CR_SEND_KEEP   0x22        //In TCP mode#define S_CR_RECV      0x40        //Receiving is processed including the value of socket RX read//pointer register/* Definition for PPPOE */#define S_CR_PCON 0x23        //Start of ADSL connection#define S_CR_PDISCON  0x24        //End of ADSL connection#define S_CR_PCR    0x25        //Send REQ message ineach phase#define S_CR_PCN 0x26        //Send NAK message in each phase#define S_CR_PCJ    0x27        //Senf REJECT message in each phase//Socket interrup register, RO, default=0x00
#define W5100_S0_IR COMMON_BASE+0x0402     //Socket 0
#define W5100_S1_IR COMMON_BASE+0x0502     //Socket 1
#define W5100_S2_IR COMMON_BASE+0x0602     //Socket 2
#define W5100_S3_IR COMMON_BASE+0x0702     //Socket 3#define S_IR_SENDOK       0x10        //Send data complete#define S_IR_TIMEOUT    0x08        //Set if timeout occurs during connection or termination//or data transmission#define S_IR_RECV     0x04        //Set if data is received#define S_IR_DISCON        0x02        //Set if receiv connection termination request#define S_IR_CON      0x01        //Set if connetion is established/* Definition for PPPOE */#define S_IR_PRECV   0x80        //Indicate receiving no support option data#define S_IR_PFAIL   0x40        //Indicate PAP Authentication fail#define S_IR_PNEXT    0x20        //Go next phase//Socket status register, RO, default=0x00
#define W5100_S0_SSR    COMMON_BASE+0x0403     //Socket 0
#define W5100_S1_SSR    COMMON_BASE+0x0503     //Socket 1
#define W5100_S2_SSR    COMMON_BASE+0x0603     //Socket 2
#define W5100_S3_SSR    COMMON_BASE+0x0703     //Socket 3#define S_SSR_CLOSED  0x00        //In case that OPEN command are given to Sn_CR, Timeout interrupt//is asserted or connection is terminated#define S_SSR_INIT    0x13        //In case that Sn_MR is set as TCP and OPEN commands are given to Sn_CR#define S_SSR_LISTEN 0x14        //In case that under the SOCK_INIT status, LISTEN commands//are given to Sn_CR#define S_SSR_ESTABLISHED 0x17    //In case that connection is established#define S_SSR_CLOSE_WAIT    0x1c    //In case that connection temination request is received#define S_SSR_UDP   0x22        //In case that OPEN command is given to Sn_CR when Sn_MR is set as UDP#define S_SSR_IPRAW   0x32        //In case that OPEN command is given to Sn_CR when Sn_MR is set as IPRAW#define S_SSR_MACRAW    0x42        //In case that OPEN command is given to S0_CR when S0_MR is set as MACRAW#define S_SSR_PPPOE    0x5f        //In case that OPEN command is given to S0_CR when S0_MR is set as PPPOE//Below is shown in the status change, and does not need much attention#define S_SSR_SYNSEND    0x15#define S_SSR_SYNRECV   0x16#define S_SSR_FIN_WAIT  0x18#define S_SSR_CLOSING   0x1a#define S_SSR_TIME_WAIT 0x1b#define S_SSR_LAST_ACK  0x1d#define S_SSR_ARP0  0x11#define S_SSR_ARP1  0x21#define S_SSR_ARP2  0x31//Socket Source port register, R/W, default=0x00
#define W5100_S0_PORT   COMMON_BASE+0x0404     //Socket 0
#define W5100_S1_PORT   COMMON_BASE+0x0504     //Socket 1
#define W5100_S2_PORT   COMMON_BASE+0x0604     //Socket 2
#define W5100_S3_PORT   COMMON_BASE+0x0704     //Socket 3//Socket destination hardware address register, R/W, default=0x00
#define W5100_S0_DHAR   COMMON_BASE+0x0406     //Socket 0
#define W5100_S1_DHAR   COMMON_BASE+0x0506     //Socket 1
#define W5100_S2_DHAR   COMMON_BASE+0x0606     //Socket 2
#define W5100_S3_DHAR   COMMON_BASE+0x0706     //Socket 3//Socket destination IP address register, R/W, default=0x00
#define W5100_S0_DIPR   COMMON_BASE+0x040c     //Socket 0
#define W5100_S1_DIPR   COMMON_BASE+0x050c     //Socket 1
#define W5100_S2_DIPR   COMMON_BASE+0x060c     //Socket 2
#define W5100_S3_DIPR   COMMON_BASE+0x070c     //Socket 3//Socket destionation port register, R/W, default=0x00
#define W5100_S0_DPORT  COMMON_BASE+0x0410     //Socket 0
#define W5100_S1_DPORT  COMMON_BASE+0x0510     //Socket 1
#define W5100_S2_DPORT  COMMON_BASE+0x0610     //Socket 2
#define W5100_S3_DPORT  COMMON_BASE+0x0710     //Socket 3//Socket maximum segment size register, R/W, default=0x00
#define W5100_S0_MSS    COMMON_BASE+0x0412     //Socket 0
#define W5100_S1_MSS    COMMON_BASE+0x0512     //Socket 1
#define W5100_S2_MSS    COMMON_BASE+0x0612     //Socket 2
#define W5100_S3_MSS    COMMON_BASE+0x0712     //Socket 3//Socket IP protocol register, R/W, default=0x00
//See http://www.iana.org/assignments/protocol-number
#define W5100_S0_PROTO  COMMON_BASE+0x0414     //Socket 0
#define W5100_S1_PROTO  COMMON_BASE+0x0514     //Socket 1
#define W5100_S2_PROTO  COMMON_BASE+0x0614     //Socket 2
#define W5100_S3_PROTO  COMMON_BASE+0x0714     //Socket 3//Socket IP type of servce register, R/W, default=0x00
#define W5100_S0_TOS    COMMON_BASE+0x0415     //Socket 0
#define W5100_S1_TOS    COMMON_BASE+0x0515     //Socket 1
#define W5100_S2_TOS    COMMON_BASE+0x0615     //Socket 2
#define W5100_S3_TOS    COMMON_BASE+0x0715     //Socket 3//Socket IP time to live register, R/W, default=0x80
#define W5100_S0_TTL    COMMON_BASE+0x0416     //Socket 0
#define W5100_S1_TTL    COMMON_BASE+0x0516     //Socket 1
#define W5100_S2_TTL    COMMON_BASE+0x0616     //Socket 2
#define W5100_S3_TTL    COMMON_BASE+0x0716     //Socket 3//Socket TX free size register, RO, default=0x0800
//should read upper byte first and lower byte later
#define W5100_S0_TX_FSR     COMMON_BASE+0x0420     //Socket 0
#define W5100_S1_TX_FSR     COMMON_BASE+0x0520     //Socket 1
#define W5100_S2_TX_FSR     COMMON_BASE+0x0620     //Socket 2
#define W5100_S3_TX_FSR     COMMON_BASE+0x0720     //Socket 3//Socket TX read pointer register, RO, default=0x0000
//should read upper byte first and lower byte later
#define W5100_S0_TX_RR      COMMON_BASE+0x0422     //Socket 0
#define W5100_S1_TX_RR      COMMON_BASE+0x0522     //Socket 1
#define W5100_S2_TX_RR      COMMON_BASE+0x0622     //Socket 2
#define W5100_S3_TX_RR      COMMON_BASE+0x0722     //Socket 3//Socket TX write pointer register, R/W, default=0x0000
//should read upper byte first and lower byte later
#define W5100_S0_TX_WR      COMMON_BASE+0x0424     //Socket 0
#define W5100_S1_TX_WR      COMMON_BASE+0x0524     //Socket 1
#define W5100_S2_TX_WR      COMMON_BASE+0x0624     //Socket 2
#define W5100_S3_TX_WR      COMMON_BASE+0x0724     //Socket 3//Socket RX size register, RO, default=0x0000
//should read upper byte first and lower byte later
#define W5100_S0_RX_RSR     COMMON_BASE+0x0426     //Socket 0
#define W5100_S1_RX_RSR     COMMON_BASE+0x0526     //Socket 1
#define W5100_S2_RX_RSR     COMMON_BASE+0x0626     //Socket 2
#define W5100_S3_RX_RSR     COMMON_BASE+0x0726     //Socket 3//Socket RX read pointer register, R/W, default=0x0000
//should read upper byte first and lower byte later
#define W5100_S0_RX_RR      COMMON_BASE+0x0428     //Socket 0
#define W5100_S1_RX_RR      COMMON_BASE+0x0528     //Socket 1
#define W5100_S2_RX_RR      COMMON_BASE+0x0628     //Socket 2
#define W5100_S3_RX_RR      COMMON_BASE+0x0728     //Socket 3//Socket RX read pointer register, R/W, default=0x0000
//should read upper byte first and lower byte later
#define W5100_S0_RX_WR      COMMON_BASE+0x042A     //Socket 0
#define W5100_S1_RX_WR      COMMON_BASE+0x052A     //Socket 1
#define W5100_S2_RX_WR      COMMON_BASE+0x062A     //Socket 2
#define W5100_S3_RX_WR      COMMON_BASE+0x072A     //Socket 3//TX memory
#define W5100_TX    COMMON_BASE+0x4000//RX memory
#define W5100_RX    COMMON_BASE+0x6000/*********************************************************************
*                           数据结构
**********************************************************************//*********************************************************************
*                           缓冲区结构
**********************************************************************/struct _W5100_Buf
{//缓冲区大小,单位字节uint16_t size;//基地址uint16_t base_addr;//屏蔽地址uint16_t mask_addr;
};/*********************************************************************
*                           全局变量声明
**********************************************************************//*********************************************************************
*                           发送缓存区参数
**********************************************************************/extern struct _W5100_Buf W5100_Tx_Buf[4];/*********************************************************************
*                           接收缓存区参数
**********************************************************************/extern struct _W5100_Buf W5100_Rx_Buf[4];/*********************************************************************
*                           函数
**********************************************************************//*********************************************************************
*                           初始化w5100
*参数:ip:本机ip,4字节
*     mac:本机mac,6字节
*     submask:掩码:4字节
*     gateway:网关,4字节
*     socket_tx_size:socket发送缓存大小,4字节
*     socket_rx_size:socket接收缓存大小,4字节
**********************************************************************/void drv_w5100_init(uint8_t *ip,uint8_t *mac,uint8_t *submask,uint8_t *gateway,\uint8_t *socket_tx_size,uint8_t *socket_rx_size);/*********************************************************************
*                           初始化io
*说明:初始化/INT和/RESET引脚
**********************************************************************/void drv_w5100_init_io(void);/*********************************************************************
*                           初始化spi
**********************************************************************/void drv_w5100_init_spi(void);/*********************************************************************
*                           初始化中断
**********************************************************************/void drv_w5100_init_irq(void);/*********************************************************************
*                           复位w5100
**********************************************************************/void drv_w5100_reset(void);/*********************************************************************
*                           使能芯片
*参数:enable:1使能,0关闭
**********************************************************************/void drv_w5100_enable(uint8_t enable);/*********************************************************************
*                           spi口发送一个字节
*参数:byte:发送的字节
*返回:收到的字节
**********************************************************************/uint8_t drv_w5100_spi_tx_byte(uint8_t byte);/*********************************************************************
*                           w5100写入一个字节
*参数:addr:地址
*     byte:字节
**********************************************************************/void drv_w5100_tx_byte(uint16_t addr,uint8_t byte);/*********************************************************************
*                           w5100写缓存
*参数:addr:w5100缓存开始地址
*     buf:缓存区地址
*     len:缓存长度
**********************************************************************/void drv_w5100_tx_buf(uint16_t addr,uint8_t *buf,uint16_t len);/*********************************************************************
*                           w5100读取一个字节
*参数:addr:地址
*返回:读取的字节
**********************************************************************/uint8_t drv_w5100_rx_byte(uint16_t addr);/*********************************************************************
*                           w5100读取缓存
*参数:addr:w5100缓存开始地址
*     buf:读取存放的缓存区地址
*     len:读取长度
**********************************************************************/void drv_w5100_rx_buf(uint16_t addr,uint8_t *buf,uint16_t len);/*********************************************************************
*                           w5100设置网关
*参数:addr:需要设置的网关,4字节
**********************************************************************/void drv_w5100_set_gateway(uint8_t *addr);/*********************************************************************
*                           读取w5100网关
*参数:addr:读取的网关存放地址,4字节长度
**********************************************************************/void drv_w5100_get_gateway(uint8_t *addr);/*********************************************************************
*                           w5100设置子网掩码
*参数:addr:需要设置的子网掩码,4字节
**********************************************************************/void drv_w5100_set_submask(uint8_t *addr);/*********************************************************************
*                           读取w5100子网掩码
*参数:addr:读取的子网掩码,4字节
**********************************************************************/void drv_w5100_get_submask(uint8_t *addr);/*********************************************************************
*                           w5100设置mac地址
*参数:mac:需要设置的mac,6字节
**********************************************************************/void drv_w5100_set_mac(uint8_t *mac);/*********************************************************************
*                           读取w5100的mac地址
*参数:addr:读取mac地址,6字节
**********************************************************************/void drv_w5100_get_mac(uint8_t *mac);/*********************************************************************
*                           w5100设置本机ip
*参数:ip:需要设置的ip,4字节
**********************************************************************/void drv_w5100_set_ip(uint8_t *ip);/*********************************************************************
*                           读取w5100的ip地址
*参数:addr:读取ip地址,4字节
**********************************************************************/void drv_w5100_get_ip(uint8_t *ip);/*********************************************************************
*                           w5100设置端口的端口号
*参数:socket:端口:0-3
*     port:端口号
**********************************************************************/void drv_w5100_set_socket_port(uint8_t socket,uint16_t port);/*********************************************************************
*                           读取w5100端口的端口号
*参数:socket:端口:0-3
*返回:端口号
**********************************************************************/uint16_t drv_w5100_get_socket_port(uint8_t socket);/*********************************************************************
*                           w5100设置端口的目的mac地址
*参数:socket:端口:0-3
*     mac:需要设置的mac,6字节
**********************************************************************/void drv_w5100_set_socket_mac(uint8_t socket,uint8_t *mac);/*********************************************************************
*                           读取w5100端口的目的mac地址
*参数:socket:端口:0-3
*     mac:读取的目的mac,6字节
**********************************************************************/void drv_w5100_get_socket_mac(uint8_t socket,uint8_t *mac);/*********************************************************************
*                           w5100设置端口的目的ip地址
*参数:socket:端口:0-3
*     ip:需要设置的ip,4字节
**********************************************************************/void drv_w5100_set_socket_dst_ip(uint8_t socket,uint8_t *ip);/*********************************************************************
*                           读取w5100端口的目的ip地址
*参数:socket:端口:0-3
*     ip:读取的目的ip,4字节
**********************************************************************/void drv_w5100_get_socket_dst_ip(uint8_t socket,uint8_t *ip);/*********************************************************************
*                           w5100设置端口的目的端口号
*参数:socket:端口:0-3
*     port:目的端口号
**********************************************************************/void drv_w5100_set_socket_dst_port(uint8_t socket,uint16_t port);/*********************************************************************
*                           读取w5100端口的目的端口号
*参数:socket:端口:0-3
*返回:端口号
**********************************************************************/uint16_t drv_w5100_get_socket_dst_port(uint8_t socket);/*********************************************************************
*                           设置w5100端口缓存大小
*说明:4个端口发送总缓存为8KB,接收总缓存为8KB
*参数:tx_size:发送缓存大小数组,4字节长度,值只能取1,2,4,8这4个.单位为KB
*     rx_size:发送缓存大小数组,4字节长度,值只能取1,2,4,8这4个.单位为KB
**********************************************************************/void drv_w5100_set_socket_buf_size(uint8_t *tx_size,uint8_t *rx_size);/*********************************************************************
*                           读取w5100端口的发送存储器剩余空间寄存器
*参数:socket:端口:0-3
*返回:发送存储器剩余空间
**********************************************************************/uint16_t drv_w5100_get_socket_tx_fsr(uint8_t socket);/*********************************************************************
*                           读取w5100端口的接收数据字节数寄存器
*参数:socket:端口:0-3
*返回:接收数据字节数
**********************************************************************/uint16_t drv_w5100_get_socket_rx_rsr(uint8_t socket);/*********************************************************************
*                           读取w5100端口接收的数据
*参数:socket:端口:0-3
*     buf:接收的数据存放的缓存
*     len:读取接收数据长度
**********************************************************************///void drv_w5100_socket_rx(uint8_t socket,uint8_t *buf,uint16_t len);/*********************************************************************
*                           读取w5100端口接收的数据
*参数:socket:端口:0-3
*     buf:接收的数据存放的缓存
*     len:读取接收数据长度
*     ip:接收数据的ip
*     port:接收数据的端口
**********************************************************************/void drv_w5100_socket_rx(uint8_t socket,uint8_t *buf,uint16_t len,uint8_t *ip,uint16_t *port);/*********************************************************************
*                           w5100端口发送数据
*参数:socket:端口:0-3
*     buf:发送的数据存放的缓存
*     len:发送数据长度
**********************************************************************/void drv_w5100_socket_tx(uint8_t socket,uint8_t *buf,uint16_t len);#endif

drv_w5100.c

/*********************************************************************
*                               w5100驱动层文件
*                             (c)copyright 2013,jdh
*                               All Right Reserved
*文件名:drv_w5100.c
*程序员:jdh
*修改日期:2013/10/22
*         2013/10/23
*         2013/10/24
**********************************************************************//*********************************************************************
*                           头文件
**********************************************************************/#include "drv_w5100.h"
#include "drv_delay.h"/*********************************************************************
*                           全局变量定义
**********************************************************************//*********************************************************************
*                           发送缓存区参数
**********************************************************************/struct _W5100_Buf W5100_Tx_Buf[4];/*********************************************************************
*                           接收缓存区参数
**********************************************************************/struct _W5100_Buf W5100_Rx_Buf[4];/*********************************************************************
*                           函数
**********************************************************************//*********************************************************************
*                           初始化w5100
*参数:ip:本机ip,4字节
*     mac:本机mac,6字节
*     submask:掩码:4字节
*     gateway:网关,4字节
*     socket_tx_size:socket发送缓存大小,4字节
*     socket_rx_size:socket接收缓存大小,4字节
**********************************************************************/void drv_w5100_init(uint8_t *ip,uint8_t *mac,uint8_t *submask,uint8_t *gateway,\uint8_t *socket_tx_size,uint8_t *socket_rx_size)
{uint8_t value = 0;//初始化IOdrv_w5100_init_io();//SPI初始化drv_w5100_init_spi();//中断初始化drv_w5100_init_irq();//复位w5100drv_w5100_reset();//软复位drv_w5100_tx_byte(W5100_MODE,MODE_RST);drv_delay_ms(300);//设置ipdrv_w5100_set_ip(ip);//设置macdrv_w5100_set_mac(mac);//设置掩码drv_w5100_set_submask(submask);//设置网关drv_w5100_set_gateway(gateway);//端口缓存设置drv_w5100_set_socket_buf_size(socket_tx_size,socket_rx_size);//设置中断value = drv_w5100_rx_byte(W5100_IMR);value |= IMR_CONFLICT | IMR_UNREACH | \IMR_S0_INT | IMR_S1_INT | IMR_S2_INT | IMR_S3_INT;drv_w5100_tx_byte(W5100_IMR,value);
}/*********************************************************************
*                           初始化io
*说明:初始化/INT和/RESET引脚
**********************************************************************/void drv_w5100_init_io(void)
{//定义IO初始化结构体GPIO_InitTypeDef GPIO_InitStructure;//初始化时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);//管脚初始化  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//选择GPIO响应速度GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    //设置为输出           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //初始化              GPIO_Init(GPIOD, &GPIO_InitStructure);  //初始化时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);//管脚初始化  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;//选择GPIO响应速度GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    //设置为输入         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //初始化                GPIO_Init(GPIOD, &GPIO_InitStructure);
}/*********************************************************************
*                           初始化spi
**********************************************************************/void drv_w5100_init_spi(void)
{//定义IO初始化结构体GPIO_InitTypeDef GPIO_InitStructure ;//定义SPI初始化结构体SPI_InitTypeDef  SPI_InitStructure ;//配置其他引脚//配置CS//开启时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE ) ;//配置SPI引脚CSNGPIO_InitStructure.GPIO_Pin = GPIO_Pin_15 | GPIO_Pin_12;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;GPIO_Init( GPIOA, &GPIO_InitStructure );//PA15默认是JTDI脚,重映射关闭JTDI功能GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//关闭w5100drv_w5100_enable(0);drv_w5100_enable(1);drv_w5100_enable(0);//初始化SPI//关闭SPISPI_Cmd(SPI3,DISABLE);//初始化SPI时钟    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3,ENABLE);//设置IO口时钟      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //配置SPI3引脚:SCK, MISO and MOSIGPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP ;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;GPIO_Init( GPIOB, &GPIO_InitStructure );// SPI配置SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex ;SPI_InitStructure.SPI_Mode = SPI_Mode_Master ;SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b ;SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low ;SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge ;SPI_InitStructure.SPI_NSS = SPI_NSS_Soft ;//SPI波特率分频设置:72M-18M,64M-16MSPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4 ;//SPI设置成LSB模式SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB ;SPI_InitStructure.SPI_CRCPolynomial = 7 ;SPI_Init( SPI3, &SPI_InitStructure ) ;//启动SPISPI_Cmd(SPI3,ENABLE);
}/*********************************************************************
*                           初始化中断
**********************************************************************/void drv_w5100_init_irq(void)
{//定义中断结构体NVIC_InitTypeDef NVIC_InitStructure ;//定义外部中断结构体EXTI_InitTypeDef EXTI_InitStructure;//初始化中断脚PD6时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//配置中断源为PD6GPIO_EXTILineConfig(GPIO_PortSourceGPIOD,GPIO_PinSource6);// 配置EXTI_Line6下降沿触发EXTI_ClearITPendingBit(EXTI_Line6);EXTI_InitStructure.EXTI_Line = EXTI_Line6;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);//打开NTRX中断NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;              //通道设置为外部中断线NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;      //中断抢占先等级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;            //中断响应优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                   //打开中断NVIC_Init(&NVIC_InitStructure);                                 //初始化//清中断//EXTI_ClearITPendingBit(EXTI9_5_IRQn);//EXTI_Line0中断允许//EXTI_GenerateSWInterrupt(EXTI_Line6);
}/*********************************************************************
*                           复位w5100
**********************************************************************/void drv_w5100_reset(void)
{GPIO_ResetBits(GPIOD,GPIO_Pin_3); drv_delay_ms(20);   GPIO_SetBits(GPIOD,GPIO_Pin_3);
}/*********************************************************************
*                           使能芯片
*参数:enable:1使能,0关闭
**********************************************************************/void drv_w5100_enable(uint8_t enable)
{if (enable){//使能GPIO_ResetBits(GPIOA,GPIO_Pin_15); }else{//关闭GPIO_SetBits(GPIOA,GPIO_Pin_15);}
}/*********************************************************************
*                           spi口发送一个字节
*参数:byte:发送的字节
*返回:收到的字节
**********************************************************************/uint8_t drv_w5100_spi_tx_byte(uint8_t byte)
{while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET);SPI_I2S_SendData(SPI3,byte);  while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET);return SPI_I2S_ReceiveData(SPI3);
}/*********************************************************************
*                           w5100写入一个字节
*参数:addr:地址
*     byte:字节
**********************************************************************/void drv_w5100_tx_byte(uint16_t addr,uint8_t byte)
{   //使能w5100drv_w5100_enable(1);drv_w5100_spi_tx_byte(WRITE_COMMAND);drv_w5100_spi_tx_byte(addr / 256);        drv_w5100_spi_tx_byte(addr % 256);      drv_w5100_spi_tx_byte(byte);            //关闭w5100drv_w5100_enable(0);
}/*********************************************************************
*                           w5100写缓存
*参数:addr:w5100缓存开始地址
*     buf:缓存区地址
*     len:缓存长度
**********************************************************************/void drv_w5100_tx_buf(uint16_t addr,uint8_t *buf,uint16_t len)
{uint16_t i;for (i = 0; i < len; i++){drv_w5100_tx_byte(addr + i,*buf++);}
}/*********************************************************************
*                           w5100读取一个字节
*参数:addr:地址
*返回:读取的字节
**********************************************************************/uint8_t drv_w5100_rx_byte(uint16_t addr)
{uint8_t byte = 0;//使能w5100drv_w5100_enable(1);drv_w5100_spi_tx_byte(READ_COMMAND);drv_w5100_spi_tx_byte(addr / 256);      drv_w5100_spi_tx_byte(addr % 256);      byte = drv_w5100_spi_tx_byte(0);           //关闭w5100drv_w5100_enable(0);return byte;
}/*********************************************************************
*                           w5100读取缓存
*参数:addr:w5100缓存开始地址
*     buf:读取存放的缓存区地址
*     len:读取长度
**********************************************************************/void drv_w5100_rx_buf(uint16_t addr,uint8_t *buf,uint16_t len)
{uint16_t i;for (i = 0; i < len; i++){*buf++ = drv_w5100_rx_byte(addr++);}
} /*********************************************************************
*                           w5100设置网关
*参数:addr:需要设置的网关,4字节
**********************************************************************/void drv_w5100_set_gateway(uint8_t *addr)
{   uint8_t i = 0;for (i = 0;i < 4;i++){drv_w5100_tx_byte(W5100_GAR + i,addr[i]);}
}/*********************************************************************
*                           读取w5100网关
*参数:addr:读取的网关存放地址,4字节长度
**********************************************************************/void drv_w5100_get_gateway(uint8_t *addr)
{uint8_t i = 0;for (i = 0;i < 4;i++){addr[i] = drv_w5100_rx_byte(W5100_GAR + i);}
}/*********************************************************************
*                           w5100设置子网掩码
*参数:addr:需要设置的子网掩码,4字节
**********************************************************************/void drv_w5100_set_submask(uint8_t *addr)
{uint8_t i = 0;for (i = 0;i < 4;i++){drv_w5100_tx_byte(W5100_SUBR + i,addr[i]);}
}/*********************************************************************
*                           读取w5100子网掩码
*参数:addr:读取的子网掩码,4字节
**********************************************************************/void drv_w5100_get_submask(uint8_t *addr)
{   uint8_t i = 0;for (i = 0;i < 4;i++){addr[i] = drv_w5100_rx_byte(W5100_SUBR + i);}
}/*********************************************************************
*                           w5100设置mac地址
*参数:mac:需要设置的mac,6字节
**********************************************************************/void drv_w5100_set_mac(uint8_t *mac)
{uint8_t i = 0;for (i = 0;i < 6;i++){drv_w5100_tx_byte(W5100_SHAR + i,mac[i]);}
}/*********************************************************************
*                           读取w5100的mac地址
*参数:addr:读取mac地址,6字节
**********************************************************************/void drv_w5100_get_mac(uint8_t *mac)
{   uint8_t i = 0;for (i = 0;i < 6;i++){mac[i] = drv_w5100_rx_byte(W5100_SHAR + i);}
}/*********************************************************************
*                           w5100设置本机ip
*参数:ip:需要设置的ip,4字节
**********************************************************************/void drv_w5100_set_ip(uint8_t *ip)
{uint8_t i = 0;for (i = 0;i < 4;i++){drv_w5100_tx_byte(W5100_SIPR + i,ip[i]);}
}/*********************************************************************
*                           读取w5100的ip地址
*参数:addr:读取ip地址,4字节
**********************************************************************/void drv_w5100_get_ip(uint8_t *ip)
{   uint8_t i = 0;for (i = 0;i < 4;i++){ip[i] = drv_w5100_rx_byte(W5100_SIPR + i);}
}/*********************************************************************
*                           w5100设置端口的端口号
*参数:socket:端口:0-3
*     port:端口号
**********************************************************************/void drv_w5100_set_socket_port(uint8_t socket,uint16_t port)
{uint16_t reg = 0;//根据端口号选择寄存器地址reg = W5100_S0_PORT + socket * 0x100;//设置端口号drv_w5100_tx_byte(reg,(port >> 8) & 0xff);drv_w5100_tx_byte(reg + 1,port & 0xff);
}/*********************************************************************
*                           读取w5100端口的端口号
*参数:socket:端口:0-3
*返回:端口号
**********************************************************************/uint16_t drv_w5100_get_socket_port(uint8_t socket)
{uint16_t reg = 0;uint16_t port = 0;//根据端口号选择寄存器地址reg = W5100_S0_PORT + socket * 0x100;//设置端口号port = drv_w5100_rx_byte(reg);port = (port << 8) + drv_w5100_rx_byte(reg + 1);return port;
}/*********************************************************************
*                           w5100设置端口的目的mac地址
*参数:socket:端口:0-3
*     mac:需要设置的mac,6字节
**********************************************************************/void drv_w5100_set_socket_mac(uint8_t socket,uint8_t *mac)
{uint8_t i = 0;uint16_t reg = 0;//根据端口号选择寄存器地址reg = W5100_S0_DHAR + socket * 0x100;//设置macfor (i = 0;i < 6;i++){drv_w5100_tx_byte(reg + i,mac[i]);}
}/*********************************************************************
*                           读取w5100端口的目的mac地址
*参数:socket:端口:0-3
*     mac:读取的目的mac,6字节
**********************************************************************/void drv_w5100_get_socket_mac(uint8_t socket,uint8_t *mac)
{uint8_t i = 0;uint16_t reg = 0;//根据端口号选择寄存器地址reg = W5100_S0_DHAR + socket * 0x100;//设置macfor (i = 0;i < 6;i++){mac[i] = drv_w5100_rx_byte(reg + i);}
}/*********************************************************************
*                           w5100设置端口的目的ip地址
*参数:socket:端口:0-3
*     ip:需要设置的ip,4字节
**********************************************************************/void drv_w5100_set_socket_dst_ip(uint8_t socket,uint8_t *ip)
{uint8_t i = 0;uint16_t reg = 0;//根据端口号选择寄存器地址reg = W5100_S0_DIPR + socket * 0x100;//设置ipfor (i = 0;i < 4;i++){drv_w5100_tx_byte(reg + i,ip[i]);}
}/*********************************************************************
*                           读取w5100端口的目的ip地址
*参数:socket:端口:0-3
*     ip:读取的目的ip,4字节
**********************************************************************/void drv_w5100_get_socket_dst_ip(uint8_t socket,uint8_t *ip)
{uint8_t i = 0;uint16_t reg = 0;//根据端口号选择寄存器地址reg = W5100_S0_DIPR + socket * 0x100;//读取ipfor (i = 0;i < 4;i++){ip[i] = drv_w5100_rx_byte(reg + i);}
}/*********************************************************************
*                           w5100设置端口的目的端口号
*参数:socket:端口:0-3
*     port:目的端口号
**********************************************************************/void drv_w5100_set_socket_dst_port(uint8_t socket,uint16_t port)
{uint16_t reg = 0;//根据端口号选择寄存器地址reg = W5100_S0_DPORT + socket * 0x100;//设置端口号drv_w5100_tx_byte(reg,(port >> 8) & 0xff);drv_w5100_tx_byte(reg + 1,port & 0xff);
}/*********************************************************************
*                           读取w5100端口的目的端口号
*参数:socket:端口:0-3
*返回:端口号
**********************************************************************/uint16_t drv_w5100_get_socket_dst_port(uint8_t socket)
{uint16_t reg = 0;uint16_t port = 0;//根据端口号选择寄存器地址reg = W5100_S0_DPORT + socket * 0x100;//设置端口号port = drv_w5100_rx_byte(reg);port = (port << 8) + drv_w5100_rx_byte(reg + 1);return port;
}/*********************************************************************
*                           设置w5100端口缓存大小
*说明:4个端口发送总缓存为8KB,接收总缓存为8KB
*参数:tx_size:发送缓存大小数组,4字节长度,值只能取1,2,4,8这4个.单位为KB
*     rx_size:发送缓存大小数组,4字节长度,值只能取1,2,4,8这4个.单位为KB
**********************************************************************/void drv_w5100_set_socket_buf_size(uint8_t *tx_size,uint8_t *rx_size)
{uint8_t value = 0;uint8_t i = 0;uint8_t tx_reg[4] = {0};uint8_t rx_reg[4] = {0};for (i = 0;i < 4;i++){switch (tx_size[i]){case 1:{tx_reg[i] = 0;break;}case 2:{tx_reg[i] = 1;break;}case 4:{tx_reg[i] = 2;break;}case 8:{tx_reg[i] = 3;break;}}switch (rx_size[i]){case 1:{rx_reg[i] = 0;break;}case 2:{rx_reg[i] = 1;break;}case 4:{rx_reg[i] = 2;break;}case 8:{rx_reg[i] = 3;break;}}}//设置写缓存大小value = (tx_reg[3] << 6) + (tx_reg[2] << 4) + \(tx_reg[1] << 2) + tx_reg[0];drv_w5100_tx_byte(W5100_TMSR, value);//设置读缓存大小value = (rx_reg[3] << 6) + (rx_reg[2] << 4) + \(rx_reg[1] << 2) + rx_reg[0];drv_w5100_tx_byte(W5100_RMSR, value);//设置缓冲区参数for (i = 0;i < 4;i++){//缓冲区大小W5100_Tx_Buf[i].size = tx_size[i] * 1024;W5100_Rx_Buf[i].size = rx_size[i] * 1024;//屏蔽地址W5100_Tx_Buf[i].mask_addr = W5100_Tx_Buf[i].size - 1;W5100_Rx_Buf[i].mask_addr = W5100_Rx_Buf[i].size - 1;//基地址if (i == 0){W5100_Tx_Buf[i].base_addr = W5100_TX;W5100_Rx_Buf[i].base_addr = W5100_RX;}else{W5100_Tx_Buf[i].base_addr = W5100_Tx_Buf[i - 1].base_addr + W5100_Tx_Buf[i - 1].size;W5100_Rx_Buf[i].base_addr = W5100_Rx_Buf[i - 1].base_addr + W5100_Tx_Buf[i - 1].size;}}
}/*********************************************************************
*                           读取w5100端口的发送存储器剩余空间寄存器
*参数:socket:端口:0-3
*返回:发送存储器剩余空间
**********************************************************************/uint16_t drv_w5100_get_socket_tx_fsr(uint8_t socket)
{uint16_t reg = 0;uint16_t size1 = 0;uint16_t size2 = 0;//根据端口号选择寄存器地址reg = W5100_S0_TX_FSR + socket * 0x100;while (1){//读取中断寄存器size1 = drv_w5100_rx_byte(reg);size1 = (size1 << 8) + drv_w5100_rx_byte(reg + 1);if (size1 != 0){size2 = drv_w5100_rx_byte(reg);size2 = (size2 << 8) + drv_w5100_rx_byte(reg + 1);if (size1 == size2){break;}}}return size1;
}/*********************************************************************
*                           读取w5100端口的接收数据字节数寄存器
*参数:socket:端口:0-3
*返回:接收数据字节数
**********************************************************************/uint16_t drv_w5100_get_socket_rx_rsr(uint8_t socket)
{uint16_t reg = 0;uint16_t size1 = 0;uint16_t size2 = 0;//根据端口号选择寄存器地址reg = W5100_S0_RX_RSR + socket * 0x100;while (1){//读取中断寄存器size1 = drv_w5100_rx_byte(reg);size1 = (size1 << 8) + drv_w5100_rx_byte(reg + 1);if (size1 != 0){size2 = drv_w5100_rx_byte(reg);size2 = (size2 << 8) + drv_w5100_rx_byte(reg + 1);if (size1 == size2){break;}}}return size1;
}/*********************************************************************
*                           读取w5100端口接收的数据
*参数:socket:端口:0-3
*     buf:接收的数据存放的缓存
*     len:读取接收数据长度
*     ip:接收数据的ip
*     port:接收数据的端口
**********************************************************************/void drv_w5100_socket_rx(uint8_t socket,uint8_t *buf,uint16_t len,uint8_t *ip,uint16_t *port)
{uint16_t shift = 0;uint16_t addr = 0;uint16_t reg = 0;uint16_t size = 0;uint16_t i = 0;uint8_t header[8] = {0};//读取接收缓冲区偏移量reg = W5100_S0_RX_RR + socket * 0x100;shift = drv_w5100_rx_byte(reg);shift = (shift << 8) + drv_w5100_rx_byte(reg + 1);//实际的偏移量shift &= W5100_Rx_Buf[socket].mask_addr;//物理地址addr = W5100_Rx_Buf[socket].base_addr + shift;/*for (i = 0;i < len;i++){if (shift >= W5100_Rx_Buf[socket].size){addr = W5100_Rx_Buf[socket].base_addr;shift = 0;}buf[i] = drv_w5100_rx_byte(addr++);shift++;}*//*//读取正文if (shift + len > W5100_Rx_Buf[socket].size){size = W5100_Rx_Buf[socket].size - shift;drv_w5100_rx_buf(addr, buf, size);drv_w5100_rx_buf(W5100_Rx_Buf[socket].base_addr, buf + size, len - size);}else{drv_w5100_rx_buf(addr, buf, len);}*///读取帧头if (shift + 8 > W5100_Rx_Buf[socket].size){size = W5100_Rx_Buf[socket].size - shift;drv_w5100_rx_buf(addr, header, size);drv_w5100_rx_buf(W5100_Rx_Buf[socket].base_addr, header + size, 8 - size);shift = 8 - size;}else{drv_w5100_rx_buf(addr, header, 8);shift += 8;}//保存帧头//读取ipip[0] = header[0];ip[1] = header[1];ip[2] = header[2];ip[3] = header[3];//端口*port = (header[4] << 8) + header[5];//实际地址更改addr = W5100_Rx_Buf[socket].base_addr + shift;//接收数据长度更改len -= 8;//读取正文if (shift + len > W5100_Rx_Buf[socket].size){size = W5100_Rx_Buf[socket].size - shift;drv_w5100_rx_buf(addr, buf, size);drv_w5100_rx_buf(W5100_Rx_Buf[socket].base_addr, buf + size, len - size);}else{drv_w5100_rx_buf(addr, buf, len);}//计算下一次偏移量shift = drv_w5100_rx_byte(reg);shift = (shift << 8) + drv_w5100_rx_byte(reg + 1);shift += len + 8;drv_w5100_tx_byte(reg,(shift >> 8) & 0xff);drv_w5100_tx_byte(reg + 1,shift & 0xff);//接收处理完成reg = W5100_S0_CR + socket * 0x100;drv_w5100_tx_byte(reg,S_CR_RECV);
}/*********************************************************************
*                           w5100端口发送数据
*参数:socket:端口:0-3
*     buf:发送的数据存放的缓存
*     len:发送数据长度
**********************************************************************/void drv_w5100_socket_tx(uint8_t socket,uint8_t *buf,uint16_t len)
{uint16_t shift = 0;uint16_t addr = 0;uint16_t reg = 0;uint16_t size = 0;//根据端口号选择寄存器地址reg = W5100_S0_TX_WR + socket * 0x100;//获得接收缓冲区读指针地址shift = drv_w5100_rx_byte(reg);shift = (shift << 8) + drv_w5100_rx_byte(reg + 1);//偏移地址shift &= W5100_Tx_Buf[socket].mask_addr;//实际地址addr = W5100_Tx_Buf[socket].base_addr + shift;//发送数据if (shift + len > W5100_Tx_Buf[socket].size){size = W5100_Tx_Buf[socket].size - shift;drv_w5100_tx_buf(addr, buf, size);drv_w5100_tx_buf(W5100_Tx_Buf[socket].base_addr, buf + size, len - size);}else{drv_w5100_tx_buf(addr, buf, len);}//发送指针偏移shift = drv_w5100_rx_byte(reg);shift = (shift << 8) + drv_w5100_rx_byte(reg + 1);shift += len;drv_w5100_tx_byte(reg, (shift >> 8) & 0xff);drv_w5100_tx_byte(reg + 1, shift & 0xff);//根据端口号选择寄存器地址reg = W5100_S0_CR + socket * 0x100;//发送drv_w5100_tx_byte(reg, S_CR_SEND);
}

接口层文件:

inf_w5100.h

/*********************************************************************
*                         w5100接口层头文件
*                       (c)copyright 2013,jdh
*                         All Right Reserved
*文件名:inf_w5100.h
*程序员:jdh
*修改日期:2013/10/24
**********************************************************************/#ifndef _INF_W5100_H_
#define _INF_W5100_H_/*********************************************************************
*                           头文件
**********************************************************************///驱动层头文件
#include "drv_w5100.h"/*********************************************************************
*                           数据结构
**********************************************************************//*********************************************************************
*                           数据结构
**********************************************************************//*********************************************************************
*                           w5100端口中断信息
**********************************************************************/struct _W5100_Socket_Irq_Msg
{//端口中断uint8_t socket_int;//数据发送完成uint8_t send_ok;//在连接或终止,数据发送等过程超时uint8_t timeout;//当端口接收到数据时uint8_t recv;//当收到终止连接请求或终止连接过程已结束uint8_t discon;//当连接成功时uint8_t con;//接收ipuint8_t ip[4];//接收端口uint16_t port;//接收数据的字节数uint16_t size;
};/*********************************************************************
*                           w5100中断信息
**********************************************************************/struct _W5100_Irq_Msg
{//ip冲突uint8_t confict;//无法到达地址uint8_t unreach;//PPPoe连接关闭uint8_t pppoe;//端口中断信息struct _W5100_Socket_Irq_Msg socket_msg[4];
};/*********************************************************************
*                           函数
**********************************************************************//*********************************************************************
*                           初始化w5100
*参数:ip:本机ip,4字节
*     mac:本机mac,6字节
*     submask:掩码:4字节
*     gateway:网关,4字节
*     socket_tx_size:socket发送缓存大小,4字节
*     socket_rx_size:socket接收缓存大小,4字节
**********************************************************************/void inf_w5100_init(uint8_t *ip,uint8_t *mac,uint8_t *submask,uint8_t *gateway,\uint8_t *socket_tx_size,uint8_t *socket_rx_size);/*********************************************************************
*                           w5100设置本机ip
*参数:ip:需要设置的ip,4字节
**********************************************************************/void inf_w5100_set_ip(uint8_t *ip);/*********************************************************************
*                           读取w5100的ip地址
*参数:addr:读取ip地址,4字节
**********************************************************************/void inf_w5100_get_ip(uint8_t *ip);/*********************************************************************
*                           w5100设置mac地址
*参数:mac:需要设置的mac,6字节
**********************************************************************/void inf_w5100_set_mac(uint8_t *mac);/*********************************************************************
*                           读取w5100的mac地址
*参数:addr:读取mac地址,4字节
**********************************************************************/void inf_w5100_get_mac(uint8_t *mac);/*********************************************************************
*                           w5100设置网关
*参数:addr:需要设置的网关,4字节
**********************************************************************/void inf_w5100_set_gateway(uint8_t *addr);/*********************************************************************
*                           读取w5100网关
*参数:addr:读取的网关存放地址,4字节长度
**********************************************************************/void inf_w5100_get_gateway(uint8_t *addr);/*********************************************************************
*                           w5100设置子网掩码
*参数:addr:需要设置的子网掩码,4字节
**********************************************************************/void inf_w5100_set_submask(uint8_t *addr);/*********************************************************************
*                           读取w5100子网掩码
*参数:addr:读取的子网掩码,4字节
**********************************************************************/void inf_w5100_get_submask(uint8_t *addr);/*********************************************************************
*                           读取w5100端口的目的ip地址
*参数:socket:端口:0-3
*     ip:读取的目的ip,4字节
**********************************************************************/void inf_w5100_get_socket_dst_ip(uint8_t socket,uint8_t *ip);/*********************************************************************
*                           读取w5100端口的目的端口号
*参数:socket:端口:0-3
*返回:端口号
**********************************************************************/uint16_t inf_w5100_get_socket_dst_port(uint8_t socket);/*********************************************************************
*                           读取w5100端口的端口号
*参数:socket:端口:0-3
*返回:端口号
**********************************************************************/uint16_t inf_w5100_get_socket_port(uint8_t socket);/*********************************************************************
*                           w5100设置端口为udp模式
*参数:socket:端口:0-3
*     port:端口号
**********************************************************************/void inf_w5100_set_socket_udp_mode(uint8_t socket,uint16_t port);/*********************************************************************
*                           w5100发送数据
*参数:socket:端口
*     data:数据
*     size:大小,单位字节
*     ip:目标ip
*     port:目标端口号
**********************************************************************/void inf_w5100_write_data(uint16_t socket,uint8_t *data,uint16_t size,\uint8_t *ip,uint16_t port);/*********************************************************************
*                           清除中断信息结构体
*参数:msg:中断结构体地址
**********************************************************************/void inf_w5100_clear_w5100_irg_msg(struct _W5100_Irq_Msg *msg);/*********************************************************************
*                           w5100中断处理函数
*参数:msg:中断信息
*     buf0:接收socket0数据地址
*     buf1:接收socket1数据地址
*     buf2:接收socket2数据地址
*     buf3:接收socket3数据地址
**********************************************************************/void inf_w5100_irq_handler(struct _W5100_Irq_Msg *msg,uint8_t *buf0,uint8_t *buf1,uint8_t *buf2,uint8_t *buf3);#endif

inf_w5100.c

/*********************************************************************
*                         w5100接口层文件
*                       (c)copyright 2013,jdh
*                         All Right Reserved
*文件名:inf_w5100.c
*程序员:jdh
*修改日期:2013/10/24
**********************************************************************//*********************************************************************
*                           头文件
**********************************************************************/#include "inf_w5100.h"/*********************************************************************
*                           函数
**********************************************************************//*********************************************************************
*                           初始化w5100
*参数:ip:本机ip,4字节
*     mac:本机mac,6字节
*     submask:掩码:4字节
*     gateway:网关,4字节
*     socket_tx_size:socket发送缓存大小,4字节
*     socket_rx_size:socket接收缓存大小,4字节
**********************************************************************/void inf_w5100_init(uint8_t *ip,uint8_t *mac,uint8_t *submask,uint8_t *gateway,\uint8_t *socket_tx_size,uint8_t *socket_rx_size)
{drv_w5100_init(ip,mac,submask,gateway,socket_tx_size,socket_rx_size);
}/*********************************************************************
*                           w5100设置本机ip
*参数:ip:需要设置的ip,4字节
**********************************************************************/void inf_w5100_set_ip(uint8_t *ip)
{drv_w5100_set_ip(ip);
}/*********************************************************************
*                           读取w5100的ip地址
*参数:addr:读取ip地址,4字节
**********************************************************************/void inf_w5100_get_ip(uint8_t *ip)
{drv_w5100_get_ip(ip);
}/*********************************************************************
*                           w5100设置mac地址
*参数:mac:需要设置的mac,6字节
**********************************************************************/void inf_w5100_set_mac(uint8_t *mac)
{drv_w5100_set_mac(mac);
}/*********************************************************************
*                           读取w5100的mac地址
*参数:addr:读取mac地址,4字节
**********************************************************************/void inf_w5100_get_mac(uint8_t *mac)
{drv_w5100_get_mac(mac);
}/*********************************************************************
*                           w5100设置网关
*参数:addr:需要设置的网关,4字节
**********************************************************************/void inf_w5100_set_gateway(uint8_t *addr)
{drv_w5100_set_gateway(addr);
}/*********************************************************************
*                           读取w5100网关
*参数:addr:读取的网关存放地址,4字节长度
**********************************************************************/void inf_w5100_get_gateway(uint8_t *addr)
{drv_w5100_get_gateway(addr);
}/*********************************************************************
*                           w5100设置子网掩码
*参数:addr:需要设置的子网掩码,4字节
**********************************************************************/void inf_w5100_set_submask(uint8_t *addr)
{drv_w5100_set_submask(addr);
}/*********************************************************************
*                           读取w5100子网掩码
*参数:addr:读取的子网掩码,4字节
**********************************************************************/void inf_w5100_get_submask(uint8_t *addr)
{drv_w5100_get_submask(addr);
}/*********************************************************************
*                           读取w5100端口的目的ip地址
*参数:socket:端口:0-3
*     ip:读取的目的ip,4字节
**********************************************************************/void inf_w5100_get_socket_dst_ip(uint8_t socket,uint8_t *ip)
{drv_w5100_get_socket_dst_ip(socket,ip);
}/*********************************************************************
*                           读取w5100端口的目的端口号
*参数:socket:端口:0-3
*返回:端口号
**********************************************************************/uint16_t inf_w5100_get_socket_dst_port(uint8_t socket)
{return drv_w5100_get_socket_dst_port(socket);
}/*********************************************************************
*                           读取w5100端口的端口号
*参数:socket:端口:0-3
*返回:端口号
**********************************************************************/uint16_t inf_w5100_get_socket_port(uint8_t socket)
{return drv_w5100_get_socket_port(socket);
}/*********************************************************************
*                           w5100设置端口为udp模式
*参数:socket:端口:0-3
*     port:端口号
**********************************************************************/void inf_w5100_set_socket_udp_mode(uint8_t socket,uint16_t port)
{uint8_t state = 0;uint16_t reg = 0;while (1){//设置为udp模式//根据端口号选择寄存器地址reg = W5100_S0_MR + socket * 0x100;//设置端口模式drv_w5100_tx_byte(reg,S_MR_UDP);//设置端口号drv_w5100_set_socket_port(socket,port);//打开端口//根据端口号选择寄存器地址reg = W5100_S0_CR + socket * 0x100;//端口开关drv_w5100_tx_byte(reg,S_CR_OPEN);//读取端口状态reg = W5100_S0_SSR + socket * 0x100;state = drv_w5100_rx_byte(reg);if (state == S_SSR_UDP){break;}else{//关闭端口//根据端口号选择寄存器地址reg = W5100_S0_CR + socket * 0x100;//端口开关drv_w5100_tx_byte(reg,0x10);}}
}/*********************************************************************
*                           w5100发送数据
*参数:socket:端口
*     data:数据
*     size:大小,单位字节
*     ip:目标ip,4字节
*     port:目标端口号
**********************************************************************/void inf_w5100_write_data(uint16_t socket,uint8_t *data,uint16_t size,\uint8_t *ip,uint16_t port)
{uint16_t free_bytes = 0;uint8_t dst_ip[4] = {0};//等待端口有足够空间发送while (1){free_bytes = drv_w5100_get_socket_tx_fsr(socket);if (free_bytes >= size){break;}}//设置目标ipdrv_w5100_set_socket_dst_ip(socket,ip);//设置目标端口drv_w5100_set_socket_dst_port(socket,port);//发送数据drv_w5100_socket_tx(socket,data,size);
}/*********************************************************************
*                           清除中断信息结构体
*参数:msg:中断结构体地址
**********************************************************************/void inf_w5100_clear_w5100_irg_msg(struct _W5100_Irq_Msg *msg)
{uint8_t i = 0;//ip冲突msg->confict = 0;//无法到达地址msg->unreach = 0;//PPPoe连接关闭msg->pppoe = 0;for (i = 0;i < 4;i++){//端口中断msg->socket_msg[i].socket_int = 0;//端口中断信息//数据发送完成msg->socket_msg[i].send_ok = 0;//在连接或终止,数据发送等过程超时msg->socket_msg[i].timeout = 0;//当端口接收到数据时msg->socket_msg[i].recv = 0;//当收到终止连接请求或终止连接过程已结束msg->socket_msg[i].discon = 0;//当连接成功时msg->socket_msg[i].con = 0;//ipmsg->socket_msg[i].ip[0] = 0;msg->socket_msg[i].ip[1] = 0;msg->socket_msg[i].ip[2] = 0;msg->socket_msg[i].ip[3] = 0;//端口msg->socket_msg[i].port = 0;//接收的字节数msg->socket_msg[i].size = 0;}
}/*********************************************************************
*                           w5100中断处理函数
*参数:msg:中断信息
*     buf0:接收socket0数据地址
*     buf1:接收socket1数据地址
*     buf2:接收socket2数据地址
*     buf3:接收socket3数据地址
**********************************************************************/void inf_w5100_irq_handler(struct _W5100_Irq_Msg *msg,uint8_t *buf0,uint8_t *buf1,uint8_t *buf2,uint8_t *buf3)
{uint8_t reg_value = 0;uint8_t i = 0;uint8_t flag[4] = {0};uint16_t reg_addr = 0;uint16_t shift = 0;//清除中断信号inf_w5100_clear_w5100_irg_msg(msg);//读取中断寄存器,判断中断类型reg_value = drv_w5100_rx_byte(W5100_IR);//清中断标志drv_w5100_tx_byte(W5100_IR,reg_value & 0xf0);//判断中断类型//IP地址冲突if ((reg_value & IR_CONFLICT) == IR_CONFLICT){msg->confict = 1;}//无法抵达地址if ((reg_value & IR_UNREACH) == IR_UNREACH){msg->unreach = 1;}//端口0中断if ((reg_value & IR_S0_INT) == IR_S0_INT){flag[0] = 1;}//端口1中断if ((reg_value & IR_S1_INT) == IR_S1_INT){flag[1] = 1;}//端口2中断if ((reg_value & IR_S2_INT) == IR_S2_INT){flag[2] = 1;}//端口3中断if ((reg_value & IR_S3_INT) == IR_S3_INT){flag[3] = 1;}for (i = 0;i < 4;i++){if (flag[i]){msg->socket_msg[i].socket_int = 1;//读取端口中断寄存器reg_addr = W5100_S0_IR + i * 0x100;reg_value = drv_w5100_rx_byte(reg_addr);//清中断标志drv_w5100_tx_byte(reg_addr,reg_value);//判断中断类型//数据发送完成if ((reg_value & S_IR_SENDOK) == S_IR_SENDOK){msg->socket_msg[i].send_ok = 1;}//在连接或终止,数据发送等过程超时if ((reg_value & S_IR_TIMEOUT) == S_IR_TIMEOUT){msg->socket_msg[i].timeout = 1;}//当端口接收到数据时if ((reg_value & S_IR_RECV) == S_IR_RECV){msg->socket_msg[i].recv = 1;msg->socket_msg[i].size = drv_w5100_get_socket_rx_rsr(i);//读取接收字节数switch (i){case 0:{drv_w5100_socket_rx(i,buf0,msg->socket_msg[i].size,\msg->socket_msg[i].ip,&msg->socket_msg[i].port);break;}case 1:{drv_w5100_socket_rx(i,buf1,msg->socket_msg[i].size,\msg->socket_msg[i].ip,&msg->socket_msg[i].port);break;}case 2:{drv_w5100_socket_rx(i,buf2,msg->socket_msg[i].size,\msg->socket_msg[i].ip,&msg->socket_msg[i].port);break;}case 3:{drv_w5100_socket_rx(i,buf3,msg->socket_msg[i].size,\msg->socket_msg[i].ip,&msg->socket_msg[i].port);break;}}//接收正文字节数msg->socket_msg[i].size -= 8;}//当收到终止连接请求或终止连接过程已结束if ((reg_value & S_IR_DISCON) == S_IR_DISCON){msg->socket_msg[i].discon = 1;}//当连接成功时if ((reg_value & S_IR_CON) == S_IR_CON){msg->socket_msg[i].con = 1;}}}
}

测试代码:

main.c:初始化w5100

int main(void)
{uint8_t i = 0;uint16_t buf1[3] = {1,2,3};uint16_t buf2[10] = {0};uint8_t ip[4] = {10,58,1,5};uint8_t mac[6] = {0x00,0xe0,0x4c,0x36,0xc9,0xb0};uint8_t submask[4] = {255,255,255,0};uint8_t gateway[4] = {10,58,1,1};uint8_t socket_tx_size[4] = {2,2,2,2};uint8_t socket_rx_size[4] = {2,2,2,2};uint8_t dst_ip[4] = {10,58,1,3};uint8_t buf[3] = {'j','d','h'};uint8_t arr[10] = {0};//初始化设备init_device();#ifndef DEBUG  //打开内部看门狗inf_enable_iwdg();
#endif//sram测试代码//FSMC_SRAM_WriteHalfWord(0,1);//FSMC_SRAM_WriteHalfWord(2,2);//FSMC_SRAM_WriteHalfWord(4,3);//Test_Data = FSMC_SRAM_ReadHalfWord(2);//FSMC_SRAM_WriteBuffer(buf1,0,3);//FSMC_SRAM_ReadBuffer(buf2,0,3);test_sram[0] = 5;test_sram[1] = 2;test_sram[2] = 3;FSMC_SRAM_ReadBuffer(buf2,0,10);__nop();//初始化网络inf_w5100_init(ip,mac,submask,gateway,socket_tx_size,socket_rx_size);//打开端口inf_w5100_set_socket_udp_mode(SOCKET0,2000);//inf_delay_ms(5000);//发送数据//inf_w5100_write_data(SOCKET0,ip,4,dst_ip,2000);//状态机执行while (1){for (i = 0;i < 6;i++){inf_set_led(i + 1,LED_ON);inf_delay_ms(10);inf_set_led(i + 1,LED_OFF);inf_delay_ms(10);}}
}

中断函数:定时发送,接收处理

/*********************************************************************
*                           系统滴答中断函数
**********************************************************************/void SysTick_Handler(void)
{uint8_t ip[4] = {10,58,1,5};uint8_t dst_ip[4] = {10,58,1,3};char *str = "zhang ling";Tick++;//if (Tick > 50 && Tick % 20 == 0)if (Tick > 50){inf_w5100_write_data(SOCKET0,(uint8_t *)str,11,dst_ip,2000);}
}/*********************************************************************
*                           w5100中断处理
**********************************************************************/void EXTI9_5_IRQHandler(void)
{if(EXTI_GetITStatus(EXTI_Line6) != RESET){//清中断EXTI_ClearITPendingBit(EXTI_Line6);    //处理w5100中断inf_w5100_irq_handler(&Msg,Buf0,Buf1,Buf2,Buf3);}
}

STM32驱动W5100实现udp通信相关推荐

  1. 【W5500】STM32 H743驱动W5500进行UDP收发

    前景提要 STM32 H743确实是个好芯片,但是这个MAC只有一个真是让我觉得不太够,想整双MAC的A核芯片玩玩,奈何实在也是没得精力弄Linux,虽然imx6ull也是一个好芯片.... 外挂MA ...

  2. STM32驱动W5100S网口模块实现UDP通讯

    本文博客链接:https://blog.csdn.net/zsj2016o/article/details/88883863 作者:zsj ,转载请注明. STM32驱动W5100S网口模块实现UDP ...

  3. 通过LWIP 的RAW API 进行与服务器的UDP通信(stm32 f103 -- enc28j60)

    LWIP的RAW API UDP通信详解(stm32f103-enc28j60) 项目整体托管到github上 实现任务 通过接收到上位机端发送来的数据来实现控制开发板做相应的操作. 代码实现 首先看 ...

  4. CH9121串口转以太网模块STM32驱动

    CH9121串口转以太网模块STM32驱动 文章目录 CH9121串口转以太网模块STM32驱动 0. 简介 1. 特性: 2. 应用场合 3. 示例平台 4. 代码 0. 简介 CH9121 集成T ...

  5. 关于STM32驱动DS1302实时时钟的一点思考

    关于STM32驱动DS1302实时时钟的一点思考 之前用51驱动过DS1302,没用多久就输出了正确的时间.当时以为这块芯片其实没啥,很简单.但是现在用STM32做项目,用到同样的芯片,以为这有何难, ...

  6. stm32读取目标芯片_使用stm32驱动RC522读IC卡(代码留言邮箱)

    RC522与PN532简介 关于STM32驱动方式 接线说明 程序烧录 查看卡号 总结 RC522与PN532简介 在写这篇文章之前有写过一篇有关于PN532的文章,RC522与PN532在使用上都可 ...

  7. STM32驱动串口屏,STM32F103C8T6串口发送指令控制HMI串口屏

    STM32驱动串口屏,STM32F103C8T6串口发送指令控制HMI串口屏 串口屏 基础指令集 硬件和接线 接线 实验前准备 STM32程序 串口程序 主函数 实验现象 总结 串口屏 串口屏是一个集 ...

  8. stm32驱动sd卡(1)

    Stm32驱动sd卡知识总结(1) 1.Stm32支持SDIO接口,可以用来接入一张不超过32G的SD卡 2.CID寄存器长度为128bit,用来标记SD卡的全球唯一身份识别号 3.支持单线和四线传输 ...

  9. STM32驱动W5500连接腾讯云

    STM32驱动W5500连接腾讯云 1.W5500简介    W5500 是一款全硬件 TCP/IP 嵌入式以太网控制器,为嵌入式系统提供了更加简易的互联网连接方案. W5500 集成了 TCP/IP ...

最新文章

  1. 学好C++十大良好的习惯
  2. Ubuntu+mps-youtube for crawling video / audio
  3. GUI(一) 一些自已看的东西
  4. 【Android 应用开发】BluetoothAdapter解析
  5. winFrom简单引用Webservice
  6. python知识:函数abs、delattr、hash、memeryview、index
  7. api报错 javaee maven_maven test 换javaee6 无法加载spring的配置文件 ?报错-问答-阿里云开发者社区-阿里云...
  8. 维权靠微博?用户京东金融账户被盗刷15万 处理未果怒发微博曝光
  9. H.264/AVC原理介绍
  10. 使用vcpkg安装指定版本的开源软件
  11. 深度学习中的优化算法之Adadelta
  12. 文本内容相似度计算方法:simhash
  13. 神经系统的解剖学基础是,神经系统系统解剖学
  14. 【以太坊】雷电网络的101网络原理概述
  15. Java基础重温_06:Debug模式(打断点、下一步),基础练习案例(减肥计划if,switch版本、逢七跳过、不死神兔、百钱白鸡、数组元素(求和,索引位置,反转)、判断数组是否相同、评委打分)
  16. ssh passphrase 测试
  17. 用python程序画出一些简单的动漫人物
  18. 设置TinyMCE在线HTML编辑控件只读
  19. NVIDIA最新的Cumulus Linux4.4发布了
  20. Ratinisa's Lontrir

热门文章

  1. CANN训练营第三季_昇腾CANN算子精讲课_TBE算子Sinh开发笔记_算子开发(二)
  2. 【Linux】Linux学习(三)常用基本命令(一)
  3. EBS开发_创建AP付款
  4. attempt包测试3_Adverbs_2020-02-04
  5. 81章 老子1章到_老子1章2章80章81章
  6. 吼 困 鸭
  7. LaTeX中手动修改参考文献格式
  8. Hanzi Weiter的简单应用小案例,在HTML汉字的书写,演示汉字笔画顺序的 汉字笔画库 js vue案例实例
  9. FLASH内存优化13条
  10. reg51.h、intrins.h这源文件