STM32驱动W5100实现udp通信
STM32驱动W5100实现udp通信
本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.
/*********************************************************************
* 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
/*********************************************************************
* 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通信相关推荐
- 【W5500】STM32 H743驱动W5500进行UDP收发
前景提要 STM32 H743确实是个好芯片,但是这个MAC只有一个真是让我觉得不太够,想整双MAC的A核芯片玩玩,奈何实在也是没得精力弄Linux,虽然imx6ull也是一个好芯片.... 外挂MA ...
- STM32驱动W5100S网口模块实现UDP通讯
本文博客链接:https://blog.csdn.net/zsj2016o/article/details/88883863 作者:zsj ,转载请注明. STM32驱动W5100S网口模块实现UDP ...
- 通过LWIP 的RAW API 进行与服务器的UDP通信(stm32 f103 -- enc28j60)
LWIP的RAW API UDP通信详解(stm32f103-enc28j60) 项目整体托管到github上 实现任务 通过接收到上位机端发送来的数据来实现控制开发板做相应的操作. 代码实现 首先看 ...
- CH9121串口转以太网模块STM32驱动
CH9121串口转以太网模块STM32驱动 文章目录 CH9121串口转以太网模块STM32驱动 0. 简介 1. 特性: 2. 应用场合 3. 示例平台 4. 代码 0. 简介 CH9121 集成T ...
- 关于STM32驱动DS1302实时时钟的一点思考
关于STM32驱动DS1302实时时钟的一点思考 之前用51驱动过DS1302,没用多久就输出了正确的时间.当时以为这块芯片其实没啥,很简单.但是现在用STM32做项目,用到同样的芯片,以为这有何难, ...
- stm32读取目标芯片_使用stm32驱动RC522读IC卡(代码留言邮箱)
RC522与PN532简介 关于STM32驱动方式 接线说明 程序烧录 查看卡号 总结 RC522与PN532简介 在写这篇文章之前有写过一篇有关于PN532的文章,RC522与PN532在使用上都可 ...
- STM32驱动串口屏,STM32F103C8T6串口发送指令控制HMI串口屏
STM32驱动串口屏,STM32F103C8T6串口发送指令控制HMI串口屏 串口屏 基础指令集 硬件和接线 接线 实验前准备 STM32程序 串口程序 主函数 实验现象 总结 串口屏 串口屏是一个集 ...
- stm32驱动sd卡(1)
Stm32驱动sd卡知识总结(1) 1.Stm32支持SDIO接口,可以用来接入一张不超过32G的SD卡 2.CID寄存器长度为128bit,用来标记SD卡的全球唯一身份识别号 3.支持单线和四线传输 ...
- STM32驱动W5500连接腾讯云
STM32驱动W5500连接腾讯云 1.W5500简介 W5500 是一款全硬件 TCP/IP 嵌入式以太网控制器,为嵌入式系统提供了更加简易的互联网连接方案. W5500 集成了 TCP/IP ...
最新文章
- 学好C++十大良好的习惯
- Ubuntu+mps-youtube for crawling video / audio
- GUI(一) 一些自已看的东西
- 【Android 应用开发】BluetoothAdapter解析
- winFrom简单引用Webservice
- python知识:函数abs、delattr、hash、memeryview、index
- api报错 javaee maven_maven test 换javaee6 无法加载spring的配置文件 ?报错-问答-阿里云开发者社区-阿里云...
- 维权靠微博?用户京东金融账户被盗刷15万 处理未果怒发微博曝光
- H.264/AVC原理介绍
- 使用vcpkg安装指定版本的开源软件
- 深度学习中的优化算法之Adadelta
- 文本内容相似度计算方法:simhash
- 神经系统的解剖学基础是,神经系统系统解剖学
- 【以太坊】雷电网络的101网络原理概述
- Java基础重温_06:Debug模式(打断点、下一步),基础练习案例(减肥计划if,switch版本、逢七跳过、不死神兔、百钱白鸡、数组元素(求和,索引位置,反转)、判断数组是否相同、评委打分)
- ssh passphrase 测试
- 用python程序画出一些简单的动漫人物
- 设置TinyMCE在线HTML编辑控件只读
- NVIDIA最新的Cumulus Linux4.4发布了
- Ratinisa's Lontrir
热门文章
- CANN训练营第三季_昇腾CANN算子精讲课_TBE算子Sinh开发笔记_算子开发(二)
- 【Linux】Linux学习(三)常用基本命令(一)
- EBS开发_创建AP付款
- attempt包测试3_Adverbs_2020-02-04
- 81章 老子1章到_老子1章2章80章81章
- 吼 困 鸭
- LaTeX中手动修改参考文献格式
- Hanzi Weiter的简单应用小案例,在HTML汉字的书写,演示汉字笔画顺序的 汉字笔画库 js vue案例实例
- FLASH内存优化13条
- reg51.h、intrins.h这源文件