STM32F107——W5500網(wǎng)絡(luò)通信
掃描二維碼
隨時(shí)隨地手機(jī)看文章
#ifndef?_W5500_QUEUE_H_ #define?_W5500_QUEUE_H_ #include?"type.h" #define?W5500_FRAME_SIZE??????????2048 #define?W5500_RECV_QUEUE_SIZE?????20 typedef?enum { ??W5500_FAILURE?=?0, ??W5500_OK?=?1, }?w5500_queue_status_t; typedef?__packed?struct { ??uint8_t?data[W5500_FRAME_SIZE]; ??uint16_t?length; }?w5500_frame_t; typedef?struct { ??uint16_t?in; ??uint16_t?out; ??uint16_t?count; ??uint16_t?item_size[W5500_RECV_QUEUE_SIZE]; ??uint8_t?data[W5500_RECV_QUEUE_SIZE][W5500_FRAME_SIZE]; }?w5500_queue_t; extern?w5500_queue_t?w5500_queue_recv; void?W5500QueueInit(w5500_queue_t?*q); uint8_t?W5500QueueWrite(w5500_queue_t?*q,?w5500_frame_t?*data); uint8_t?W5500QueueRead(w5500_queue_t?*q,?w5500_frame_t?*data); #endif?/*?_W5500_QUEUE_H_?*/
#include?"w5500_queue.h" #include#include#include?"debug.h" w5500_queue_t?w5500_queue_recv; void?W5500QueueInit(w5500_queue_t?*q) { ??int?i; ??for(i?=?0;?i?<?W5500_RECV_QUEUE_SIZE;?++i) ??{ ????memset(q->data[i],?0,?W5500_FRAME_SIZE); ??} ??memset(q->item_size,?0,?sizeof(q->item_size)); ??q->in???=?0; ??q->out??=?0; ??q->count?=?0; } uint8_t?W5500QueueWrite(w5500_queue_t?*q,?w5500_frame_t?*frame) { ??if((q->out?%?W5500_RECV_QUEUE_SIZE?==?q->in)?&&?(q->count?==?W5500_RECV_QUEUE_SIZE)) ??{ ????return?W5500_FAILURE; ??} ??q->item_size[q->in]?=?frame->length; ??memcpy(q->data[q->in],?frame->data,?frame->length); ??q->in?=?(q->in?+?1)?%?W5500_RECV_QUEUE_SIZE; ??q->count++; ??return?W5500_OK; } uint8_t?W5500QueueRead(w5500_queue_t?*q,?w5500_frame_t?*frame) { ??if((q->in?==?q->out)?&&?(q->count?==?0)) ??{ ????return?W5500_FAILURE; ??} ??frame->length?=?q->item_size[q->out]; ??memcpy(frame->data,?q->data[q->out],?q->item_size[q->out]); ??q->out?=?(q->out?+?1)?%?W5500_RECV_QUEUE_SIZE; ??q->count--; ??return?W5500_OK; }
#ifndef?_W5500_H_ #define?_W5500_H_ #include?"type.h" #include?"debug.h" /*****************?Common?Register?*****************/ #define?MR????0x0000 #define?RST???0x80 #define?WOL???0x20 #define?PB????0x10 #define?PPP???0x08 #define?FARP??0x02 #define?GAR???0x0001 #define?SUBR??0x0005 #define?SHAR??0x0009 #define?SIPR??0x000f #define?INTLEVEL??0x0013 #define?IR????????0x0015 #define?CONFLICT??0x80 #define?UNREACH???0x40 #define?PPPOE?????0x20 #define?MP????????0x10 #define?IMR???????0x0016 #define?IM_IR7????0x80 #define?IM_IR6????0x40 #define?IM_IR5????0x20 #define?IM_IR4????0x10 #define?SIR???????0x0017 #define?S7_INT????0x80 #define?S6_INT????0x40 #define?S5_INT????0x20 #define?S4_INT????0x10 #define?S3_INT????0x08 #define?S2_INT????0x04 #define?S1_INT????0x02 #define?S0_INT????0x01 #define?SIMR??????0x0018 #define?S7_IMR????0x80 #define?S6_IMR????0x40 #define?S5_IMR????0x20 #define?S4_IMR????0x10 #define?S3_IMR????0x08 #define?S2_IMR????0x04 #define?S1_IMR????0x02 #define?S0_IMR????0x01 #define?RTR_w5500?0x0019 #define?RCR_w5500?0x001b #define?PTIMER??0x001c #define?PMAGIC??0x001d #define?PHA?????0x001e #define?PSID????0x0024 #define?PMRU????0x0026 #define?UIPR????0x0028 #define?UPORT???0x002c #define?PHYCFGR?0x002e #define?RST_PHY?0x80 #define?OPMODE??0x40 #define?DPX?????0x04 #define?SPD?????0x02 #define?LINK????0x01 #define?VERR????0x0039 /*********************?Socket?Register?*******************/ #define?Sn_MR?????????0x0000 #define?MULTI_MFEN????0x80 #define?BCASTB????????0x40 #define?ND_MC_MMB?????0x20 #define?UCASTB_MIP6B??0x10 #define?MR_CLOSE??????0x00 #define?MR_TCP????????0x01 #define?MR_UDP????????0x02 #define?MR_MACRAW?????0x04 #define?Sn_CR?????????0x0001 #define?OPEN??????????0x01 #define?LISTEN????????0x02 #define?CONNECT???????0x04 #define?DISCON????????0x08 #define?CLOSE?????????0x10 #define?SEND??????????0x20 #define?SEND_MAC??????0x21 #define?SEND_KEEP?????0x22 #define?RECV??????????0x40 #define?Sn_IR?????????0x0002 #define?IR_SEND_OK????0x10 #define?IR_TIMEOUT????0x08 #define?IR_RECV???????0x04 #define?IR_DISCON?????0x02 #define?IR_CON????????0x01 #define?Sn_SR?????????0x0003 #define?SOCK_CLOSED???0x00 #define?SOCK_INIT?????0x13 #define?SOCK_LISTEN???0x14 #define?SOCK_ESTABLISHED??0x17 #define?SOCK_CLOSE_WAIT???0x1c #define?SOCK_UDP??????0x22 #define?SOCK_MACRAW???0x02 #define?SOCK_SYNSEND??0x15 #define?SOCK_SYNRECV??0x16 #define?SOCK_FIN_WAI??0x18 #define?SOCK_CLOSING??0x1a #define?SOCK_TIME_WAIT??0x1b #define?SOCK_LAST_ACK?0x1d #define?Sn_PORT???0x0004 #define?Sn_DHAR???0x0006 #define?Sn_DIPR???0x000c #define?Sn_DPORTR?0x0010 #define?Sn_MSSR???0x0012 #define?Sn_TOS????0x0015 #define?Sn_TTL????0x0016 #define?Sn_RXBUF_SIZE?0x001e #define?Sn_TXBUF_SIZE?0x001f #define?Sn_TX_FSR?0x0020 #define?Sn_TX_RD??0x0022 #define?Sn_TX_WR??0x0024 #define?Sn_RX_RSR?0x0026 #define?Sn_RX_RD??0x0028 #define?Sn_RX_WR??0x002a #define?Sn_IMR??????0x002c #define?IMR_SENDOK??0x10 #define?IMR_TIMEOUT?0x08 #define?IMR_RECV????0x04 #define?IMR_DISCON??0x02 #define?IMR_CON?????0x01 #define?Sn_FRAG?????0x002d #define?Sn_KPALVTR??0x002f /*******************************************************************/ /************************?SPI?Control?Byte?*************************/ /*******************************************************************/ /*?Operation?mode?bits?*/ #define?VDM???0x00 #define?FDM1??0x01 #define?FDM2??0x02 #define?FDM4??0x03 /*?Read_Write?control?bit?*/ #define?RWB_READ??0x00 #define?RWB_WRITE?0x04 /*?Block?select?bits?*/ #define?COMMON_R??0x00 /*?Socket?0?*/ #define?S0_REG????0x08 #define?S0_TX_BUF?0x10 #define?S0_RX_BUF?0x18 /*?Socket?1?*/ #define?S1_REG????0x28 #define?S1_TX_BUF?0x30 #define?S1_RX_BUF?0x38 /*?Socket?2?*/ #define?S2_REG????0x48 #define?S2_TX_BUF?0x50 #define?S2_RX_BUF?0x58 /*?Socket?3?*/ #define?S3_REG????0x68 #define?S3_TX_BUF?0x70 #define?S3_RX_BUF?0x78 /*?Socket?4?*/ #define?S4_REG????0x88 #define?S4_TX_BUF?0x90 #define?S4_RX_BUF?0x98 /*?Socket?5?*/ #define?S5_REG????0xa8 #define?S5_TX_BUF?0xb0 #define?S5_RX_BUF?0xb8 /*?Socket?6?*/ #define?S6_REG????0xc8 #define?S6_TX_BUF?0xd0 #define?S6_RX_BUF?0xd8 /*?Socket?7?*/ #define?S7_REG????0xe8 #define?S7_TX_BUF?0xf0 #define?S7_RX_BUF?0xf8 #define?SOCKET_OK??0xff #define?SOCKET_FAILURE?0x00 #define?S_RX_SIZE?2048??/*定義Socket接收緩沖區(qū)的大小,可以根據(jù)W5500_RMSR的設(shè)置修改?*/ #define?S_TX_SIZE?2048????/*定義Socket發(fā)送緩沖區(qū)的大小,可以根據(jù)W5500_TMSR的設(shè)置修改?*/ /***************-----?端口數(shù)據(jù)緩沖區(qū)?-----***************/ extern?uint8_t?socket_rx_buffer[2048];?//端口接收數(shù)據(jù)緩沖區(qū) extern?uint8_t?socket_tx_buffer[2048];?//端口發(fā)送數(shù)據(jù)緩沖區(qū) typedef?unsigned?char?SOCKET;?????//自定義端口號(hào)數(shù)據(jù)類型 void?W5500Init(void); void?W5500SocketScan(void); uint16_t?W5500SocketRecv(uint8_t?*buffer); void?W5500SocketSend(uint8_t?*buffer,?uint16_t?length); void?W5500Process(void); extern?void?w5500_test(void); #endif
#include#include?"stm32f10x.h" #include?"stm32f10x_spi.h" #include?"target.h" #include?"delay.h" #include?"w5500.h" #include?"w5500_queue.h" #include?"debug.h" static?uint8_t?gateway_addr[4]; static?uint8_t?sub_mask[4]; static?uint8_t?mac_addr[6]; static?uint8_t?ip_addr[4]; static?uint8_t?s0_port[2];???//端口0的端口號(hào)(5000) static?uint8_t?s0_dip[4];????//端口0目的IP地址 static?uint8_t?s0_dport[2];??//端口0目的端口號(hào)(6000) static?uint8_t?udp_daddr[4];?//UDP(廣播)模式,目的主機(jī)IP地址 static?uint8_t?udp_dport[2];?//UDP(廣播)模式,目的主機(jī)端口號(hào) /***************-----?端口的運(yùn)行模式?-----***************/ static?uint8_t?s0_mode?=?3;?//端口0的運(yùn)行模式,0:TCP服務(wù)器模式,1:TCP客戶端模式,2:UDP(廣播)模式 #define?TCP_SERVER??0x00??//TCP服務(wù)器模式 #define?TCP_CLIENT??0x01??//TCP客戶端模式? #define?UDP_MODE????0x02??//UDP(廣播)模式? /***************-----?端口的運(yùn)行狀態(tài)?-----***************/ static?uint8_t?s0_state?=?0;?//端口0狀態(tài)記錄,1:端口完成初始化,2端口完成連接(可以正常傳輸數(shù)據(jù)) #define?S_INIT????0x01??//端口完成初始化? #define?S_CONN????0x02??//端口完成連接,可以正常傳輸數(shù)據(jù)? /***************-----?端口收發(fā)數(shù)據(jù)的狀態(tài)?-----***************/ static?uint8_t?s0_data;????//端口0接收和發(fā)送數(shù)據(jù)的狀態(tài),1:端口接收到數(shù)據(jù),2:端口發(fā)送數(shù)據(jù)完成 #define?S_RECEIVE????0x01?//端口接收到一個(gè)數(shù)據(jù)包? #define?S_TRANSMITOK?0x02?//端口發(fā)送一個(gè)數(shù)據(jù)包完成? /***************-----?端口數(shù)據(jù)緩沖區(qū)?-----***************/ uint8_t?socket_rx_buffer[2048];??//端口接收數(shù)據(jù)緩沖區(qū) uint8_t?socket_tx_buffer[2048];??//端口發(fā)送數(shù)據(jù)緩沖區(qū) static?void?w5500_gpio_init(void) { ??RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,?ENABLE); ??W5500_RST_CONFIG(); ??W5500_RST_LOW(); ??W5500_INT_CONFIG(); ??W5500_CS_CONFIG(); ??W5500_SPI_CONFIG();?//?clk??miso??mosi } static?void?w5500_spi_init(void) { ??SPI_InitTypeDef?SPI_InitStructure; ??RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,?ENABLE); ??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_InitStructure.SPI_BaudRatePrescaler?=?SPI_BaudRatePrescaler_2; ??SPI_InitStructure.SPI_FirstBit?=?SPI_FirstBit_MSB; ??SPI_InitStructure.SPI_CRCPolynomial?=?7; ??SPI_Init(W5500_SPI,?&SPI_InitStructure); ??SPI_Cmd(W5500_SPI,?ENABLE); } static?void?w5500_send_byte(uint8_t?data) { ??SPI_I2S_SendData(W5500_SPI,?data);//寫(xiě)1個(gè)字節(jié)數(shù)據(jù) ??while(SPI_I2S_GetFlagStatus(W5500_SPI,?SPI_I2S_FLAG_TXE)?==?RESET);//等待數(shù)據(jù)寄存器空 } static?void?w5500_send_short(uint16_t?data) { ??w5500_send_byte(data?/?256); ??w5500_send_byte(data); } static?void?w5500_write_byte(uint16_t?reg,?uint8_t?data) { ??W5500_CS_LOW(); ??w5500_send_short(reg); ??w5500_send_byte(FDM1?|?RWB_WRITE?|?COMMON_R);?//?寫(xiě)控制字節(jié),1個(gè)字節(jié)數(shù)據(jù)長(zhǎng)度,寫(xiě)數(shù)據(jù),選擇通用寄存器 ??w5500_send_byte(data); ??W5500_CS_HIGH(); } static?void?w5500_write_short(uint16_t?reg,?uint16_t?data) { ??W5500_CS_LOW(); ??w5500_send_short(reg); ??w5500_send_byte(FDM2?|?RWB_WRITE?|?COMMON_R);?//?寫(xiě)控制字節(jié),2個(gè)字節(jié)數(shù)據(jù)長(zhǎng)度,寫(xiě)數(shù)據(jù),選擇通用寄存器 ??w5500_send_short(data); ??W5500_CS_HIGH(); } static?void?w5500_write(uint16_t?reg,?uint8_t?*buffer,?uint16_t?length) { ??uint16_t?i; ??W5500_CS_LOW(); ??w5500_send_short(reg); ??w5500_send_byte(VDM?|?RWB_WRITE?|?COMMON_R); ??for(i?=?0;?i?<?length;?++i) ??{ ????w5500_send_byte(*buffer++); ??} ??W5500_CS_HIGH(); } static?void?w5500_sock_write_byte(SOCKET?s,?uint16_t?reg,?uint8_t?data) { ??W5500_CS_LOW(); ??w5500_send_short(reg); ??w5500_send_byte(FDM1?|?RWB_WRITE?|?(s?*?0x20?+?0x08));?//?寫(xiě)控制字節(jié),1個(gè)字節(jié)數(shù)據(jù)長(zhǎng)度,寫(xiě)數(shù)據(jù),選擇端口s的寄存器 ??w5500_send_byte(data); ??W5500_CS_HIGH(); } static?void?w5500_sock_write_short(SOCKET?s,?uint16_t?reg,?uint16_t?data) { ??W5500_CS_LOW(); ??w5500_send_short(reg); ??w5500_send_byte(FDM2?|?RWB_WRITE?|?(s?*?0x20?+?0x08));?//?寫(xiě)控制字節(jié),2個(gè)字節(jié)數(shù)據(jù)長(zhǎng)度,寫(xiě)數(shù)據(jù),選擇端口s的寄存器 ??w5500_send_short(data); ??W5500_CS_HIGH(); } static?void?w5500_sock_write_4bytes(SOCKET?s,?uint16_t?reg,?uint8_t?*buffer) { ??W5500_CS_LOW(); ??w5500_send_short(reg); ??w5500_send_byte(FDM4?|?RWB_WRITE?|?(s?*?0x20?+?0x08));?//?寫(xiě)控制字節(jié),4個(gè)字節(jié)數(shù)據(jù)長(zhǎng)度,寫(xiě)數(shù)據(jù),選擇端口s的寄存器 ??w5500_send_byte(*buffer++); ??w5500_send_byte(*buffer++); ??w5500_send_byte(*buffer++); ??w5500_send_byte(*buffer++); ??W5500_CS_HIGH(); } static?uint8_t?w5500_read_byte(uint16_t?reg) { ??uint8_t?value; ??W5500_CS_LOW(); ??w5500_send_short(reg); ??w5500_send_byte(FDM1?|?RWB_READ?|?COMMON_R);?//?寫(xiě)控制字節(jié),1個(gè)字節(jié)數(shù)據(jù)長(zhǎng)度,讀數(shù)據(jù),選擇通用寄存器 ??value?=?SPI_I2S_ReceiveData(W5500_SPI); ??w5500_send_byte(0x00); ??value?=?SPI_I2S_ReceiveData(W5500_SPI); ??W5500_CS_HIGH(); ??return?value; } static?uint8_t?w5500_sock_read_byte(SOCKET?s,?uint16_t?reg) { ??uint8_t?value; ??W5500_CS_LOW(); ??w5500_send_short(reg); ??w5500_send_byte(FDM1?|?RWB_READ?|?(s?*?0x20?+?0x08));?//?寫(xiě)控制字節(jié),1個(gè)字節(jié)數(shù)據(jù)長(zhǎng)度,讀數(shù)據(jù),選擇端口s的寄存器 ??value?=?SPI_I2S_ReceiveData(W5500_SPI); ??w5500_send_byte(0x00); ??value?=?SPI_I2S_ReceiveData(W5500_SPI); ??W5500_CS_HIGH(); ??return?value; } static?uint16_t?w5500_sock_read_2bytes(SOCKET?s,?uint16_t?reg) { ??uint16_t?value; ??W5500_CS_LOW(); ??w5500_send_short(reg); ??w5500_send_byte(FDM2?|?RWB_READ?|?(s?*?0x20?+?0x08));?//?寫(xiě)控制字節(jié),2個(gè)字節(jié)數(shù)據(jù)長(zhǎng)度,讀數(shù)據(jù),選擇端口s的寄存器 ??value?=?SPI_I2S_ReceiveData(W5500_SPI); ??w5500_send_byte(0x00); ??value?=?SPI_I2S_ReceiveData(W5500_SPI); ??w5500_send_byte(0x00); ??value?*=?256; ??value?+=?SPI_I2S_ReceiveData(W5500_SPI); ??W5500_CS_HIGH(); ??return?value; } static?uint16_t?w5500_socket_read(SOCKET?s,?uint8_t?*buffer) { ??uint16_t?rx_size,?offset,?offset1,?i; ??uint8_t?j; ??rx_size?=?w5500_sock_read_2bytes(s,?Sn_RX_RSR); ??if(rx_size?==?0) ??{ ????return?0;??//沒(méi)接收到數(shù)據(jù)則返回 ??} ??if(rx_size?>?1460) ??{ ????rx_size?=?1460; ??} ??offset?=?w5500_sock_read_2bytes(s,?Sn_RX_RD); ??offset1?=?offset; ??offset?&=?(S_RX_SIZE?-?1);?//計(jì)算實(shí)際的物理地址 ??W5500_CS_LOW(); ??w5500_send_short(offset);//寫(xiě)16位地址 ??w5500_send_byte(VDM?|?RWB_READ?|?(s?*?0x20?+?0x18));?//寫(xiě)控制字節(jié),N個(gè)字節(jié)數(shù)據(jù)長(zhǎng)度,讀數(shù)據(jù),選擇端口s的寄存器 ??j?=?SPI_I2S_ReceiveData(SPI2); ??if((offset?+?rx_size)?<?S_RX_SIZE)?//如果最大地址未超過(guò)W5500接收緩沖區(qū)寄存器的最大地址 ??{ ????for(i?=?0;?i?<?rx_size;?i++)?//循環(huán)讀取rx_size個(gè)字節(jié)數(shù)據(jù) ????{ ??????w5500_send_byte(0x00);//發(fā)送一個(gè)啞數(shù)據(jù) ??????j?=?SPI_I2S_ReceiveData(SPI2);?//讀取1個(gè)字節(jié)數(shù)據(jù) ??????*buffer?=?j;?//將讀取到的數(shù)據(jù)保存到數(shù)據(jù)保存緩沖區(qū) ??????buffer++;//數(shù)據(jù)保存緩沖區(qū)指針地址自增1 ????} ??} ??else//如果最大地址超過(guò)W5500接收緩沖區(qū)寄存器的最大地址 ??{ ????offset?=?S_RX_SIZE?-?offset; ????for(i?=?0;?i?<?offset;?i++)?//循環(huán)讀取出前offset個(gè)字節(jié)數(shù)據(jù) ????{ ??????w5500_send_byte(0x00);//發(fā)送一個(gè)啞數(shù)據(jù) ??????j?=?SPI_I2S_ReceiveData(SPI2);?//讀取1個(gè)字節(jié)數(shù)據(jù) ??????*buffer?=?j;?//將讀取到的數(shù)據(jù)保存到數(shù)據(jù)保存緩沖區(qū) ??????buffer++;//數(shù)據(jù)保存緩沖區(qū)指針地址自增1 ????} ????W5500_CS_HIGH(); ????W5500_CS_LOW(); ????w5500_send_short(0x00);//寫(xiě)16位地址 ????w5500_send_byte(VDM?|?RWB_READ?|?(s?*?0x20?+?0x18));?//寫(xiě)控制字節(jié),N個(gè)字節(jié)數(shù)據(jù)長(zhǎng)度,讀數(shù)據(jù),選擇端口s的寄存器 ????j?=?SPI_I2S_ReceiveData(SPI2); ????for(;?i?<?rx_size;?i++)?//循環(huán)讀取后rx_size-offset個(gè)字節(jié)數(shù)據(jù) ????{ ??????w5500_send_byte(0x00);//發(fā)送一個(gè)啞數(shù)據(jù) ??????j?=?SPI_I2S_ReceiveData(SPI2);?//讀取1個(gè)字節(jié)數(shù)據(jù) ??????*buffer?=?j;?//將讀取到的數(shù)據(jù)保存到數(shù)據(jù)保存緩沖區(qū) ??????buffer++;//數(shù)據(jù)保存緩沖區(qū)指針地址自增1 ????} ??} ??W5500_CS_HIGH(); ??offset1?+=?rx_size;?//更新實(shí)際物理地址,即下次讀取接收到的數(shù)據(jù)的起始地址 ??w5500_sock_write_short(s,?Sn_RX_RD,?offset1); ??w5500_sock_write_byte(s,?Sn_CR,?RECV);//發(fā)送啟動(dòng)接收命令 ??return?rx_size;//返回接收到數(shù)據(jù)的長(zhǎng)度 } static?void?w5500_socket_write(SOCKET?s,?uint8_t?*buffer,?uint16_t?length) { ??uint16_t?offset,?offset1,?i; ??//如果是UDP模式,可以在此設(shè)置目的主機(jī)的IP和端口號(hào) ??if((w5500_sock_read_byte(s,?Sn_MR)?&?0x0f)?!=?SOCK_UDP)?//如果Socket打開(kāi)失敗 ??{ ????w5500_sock_write_4bytes(s,?Sn_DIPR,?udp_daddr);//設(shè)置目的主機(jī)IP ????w5500_sock_write_short(s,?Sn_DPORTR,?udp_dport[0]?*?256?+?udp_dport[1]);?//設(shè)置目的主機(jī)端口號(hào) ??} ??offset?=?w5500_sock_read_2bytes(s,?Sn_TX_WR); ??offset1?=?offset; ??offset?&=?(S_TX_SIZE?-?1);?//計(jì)算實(shí)際的物理地址 ??W5500_CS_LOW(); ??w5500_send_short(offset);//寫(xiě)16位地址 ??w5500_send_byte(VDM?|?RWB_WRITE?|?(s?*?0x20?+?0x10));?//寫(xiě)控制字節(jié),N個(gè)字節(jié)數(shù)據(jù)長(zhǎng)度,寫(xiě)數(shù)據(jù),選擇端口s的寄存器 ??if((offset?+?length)?<?S_TX_SIZE)?//如果最大地址未超過(guò)W5500發(fā)送緩沖區(qū)寄存器的最大地址 ??{ ????for(i?=?0;?i?<?length;?++i)?//循環(huán)寫(xiě)入size個(gè)字節(jié)數(shù)據(jù) ????{ ??????w5500_send_byte(*buffer++);//寫(xiě)入一個(gè)字節(jié)的數(shù)據(jù) ????} ??} ??else//如果最大地址超過(guò)W5500發(fā)送緩沖區(qū)寄存器的最大地址 ??{ ????offset?=?S_TX_SIZE?-?offset; ????for(i?=?0;?i?<?offset;?++i)?//循環(huán)寫(xiě)入前offset個(gè)字節(jié)數(shù)據(jù) ????{ ??????w5500_send_byte(*buffer++);//寫(xiě)入一個(gè)字節(jié)的數(shù)據(jù) ????} ????W5500_CS_HIGH(); ????W5500_CS_LOW(); ????w5500_send_short(0x00);//寫(xiě)16位地址 ????w5500_send_byte(VDM?|?RWB_WRITE?|?(s?*?0x20?+?0x10));?//寫(xiě)控制字節(jié),N個(gè)字節(jié)數(shù)據(jù)長(zhǎng)度,寫(xiě)數(shù)據(jù),選擇端口s的寄存器 ????for(;?i?<?length;?i++)?//循環(huán)寫(xiě)入size-offset個(gè)字節(jié)數(shù)據(jù) ????{ ??????w5500_send_byte(*buffer++);//寫(xiě)入一個(gè)字節(jié)的數(shù)據(jù) ????} ??} ??W5500_CS_HIGH(); ??offset1?+=?length;?//更新實(shí)際物理地址,即下次寫(xiě)待發(fā)送數(shù)據(jù)到發(fā)送數(shù)據(jù)緩沖區(qū)的起始地址 ??w5500_sock_write_short(s,?Sn_TX_WR,?offset1); ??w5500_sock_write_byte(s,?Sn_CR,?SEND);//發(fā)送啟動(dòng)發(fā)送命令 } static?void?w5500_hardware_reset(void) { ??W5500_RST_LOW(); ??delay_ms(5); ??W5500_RST_HIGH(); ??delay_ms(20); ??while((w5500_read_byte(PHYCFGR)?&?LINK)?==?0);//等待以太網(wǎng)連接完成 } static?void?w5500_reg_init(void) { ??uint8_t?i?=?0; ??w5500_write_byte(MR,?RST);//軟件復(fù)位W5500,置1有效,復(fù)位后自動(dòng)清0 ??delay_ms(10); ??//設(shè)置網(wǎng)關(guān)(Gateway)的IP地址,Gateway_IP為4字節(jié)unsigned?char數(shù)組,自己定義 ??//使用網(wǎng)關(guān)可以使通信突破子網(wǎng)的局限,通過(guò)網(wǎng)關(guān)可以訪問(wèn)到其它子網(wǎng)或進(jìn)入Internet ??w5500_write(GAR,?gateway_addr,?4); ??//設(shè)置子網(wǎng)掩碼(MASK)值,SUB_MASK為4字節(jié)unsigned?char數(shù)組,自己定義 ??//子網(wǎng)掩碼用于子網(wǎng)運(yùn)算 ??w5500_write(SUBR,?sub_mask,?4); ??//設(shè)置物理地址,PHY_ADDR為6字節(jié)unsigned?char數(shù)組,自己定義,用于唯一標(biāo)識(shí)網(wǎng)絡(luò)設(shè)備的物理地址值 ??//該地址值需要到IEEE申請(qǐng),按照OUI的規(guī)定,前3個(gè)字節(jié)為廠商代碼,后三個(gè)字節(jié)為產(chǎn)品序號(hào) ??//如果自己定義物理地址,注意第一個(gè)字節(jié)必須為偶數(shù) ??w5500_write(SHAR,?mac_addr,?6); ??//設(shè)置本機(jī)的IP地址,IP_ADDR為4字節(jié)unsigned?char數(shù)組,自己定義 ??//注意,網(wǎng)關(guān)IP必須與本機(jī)IP屬于同一個(gè)子網(wǎng),否則本機(jī)將無(wú)法找到網(wǎng)關(guān) ??w5500_write(SIPR,?ip_addr,?4); ??//設(shè)置發(fā)送緩沖區(qū)和接收緩沖區(qū)的大小,參考W5500數(shù)據(jù)手冊(cè) ??for(i?=?0;?i?<?8;?i++) ??{ ????w5500_sock_write_byte(i,?Sn_RXBUF_SIZE,?0x02);?//Socket?Rx?memory?size=2k ????w5500_sock_write_byte(i,?Sn_TXBUF_SIZE,?0x02);?//Socket?Tx?mempry?size=2k ??} ??//設(shè)置重試時(shí)間,默認(rèn)為2000(200ms) ??//每一單位數(shù)值為100微秒,初始化時(shí)值設(shè)為2000(0x07D0),等于200毫秒 ??w5500_write_short(RTR_w5500,?0x07d0); ??//設(shè)置重試次數(shù),默認(rèn)為8次 ??//如果重發(fā)的次數(shù)超過(guò)設(shè)定值,則產(chǎn)生超時(shí)中斷(相關(guān)的端口中斷寄存器中的Sn_IR?超時(shí)位(TIMEOUT)置“1”) ??w5500_write_byte(RCR_w5500,?8); ??//啟動(dòng)中斷,參考W5500數(shù)據(jù)手冊(cè)確定自己需要的中斷類型 ??//IMR_CONFLICT是IP地址沖突異常中斷,IMR_UNREACH是UDP通信時(shí),地址無(wú)法到達(dá)的異常中斷 ??//其它是Socket事件中斷,根據(jù)需要添加 ??w5500_write_byte(IMR,?IM_IR7?|?IM_IR6); ??w5500_write_byte(SIMR,?S0_IMR); ??w5500_sock_write_byte(0,?Sn_IMR,?IMR_SENDOK?|?IMR_TIMEOUT?|?IMR_RECV?|?IMR_DISCON?|?IMR_CON); } static?uint8_t?w5500_gateway_check(void) { ??uint8_t?ip_adde[4]; ??ip_adde[0]?=?ip_addr[0]?+?1; ??ip_adde[1]?=?ip_addr[1]?+?1; ??ip_adde[2]?=?ip_addr[2]?+?1; ??ip_adde[3]?=?ip_addr[3]?+?1; ??//檢查網(wǎng)關(guān)及獲取網(wǎng)關(guān)的物理地址 ??w5500_sock_write_4bytes(0,?Sn_DIPR,?ip_adde);?//向目的地址寄存器寫(xiě)入與本機(jī)IP不同的IP值 ??w5500_sock_write_byte(0,?Sn_MR,?MR_TCP);?//設(shè)置socket為T(mén)CP模式 ??w5500_sock_write_byte(0,?Sn_CR,?OPEN);?//打開(kāi)Socket ??delay_ms(5);//延時(shí)5ms ??if(w5500_sock_read_byte(0,?Sn_SR)?!=?SOCK_INIT)?//如果socket打開(kāi)失敗 ??{ ????w5500_sock_write_byte(0,?Sn_CR,?CLOSE);?//打開(kāi)不成功,關(guān)閉Socket ????return?SOCKET_FAILURE;//返回FALSE(0x00) ??} ??w5500_sock_write_byte(0,?Sn_CR,?CONNECT);?//設(shè)置Socket為Connect模式 ??do ??{ ????uint8_t?j?=?0; ????j?=?w5500_sock_read_byte(0,?Sn_IR);?//讀取Socket0中斷標(biāo)志寄存器 ????if(j?!=?0) ????{ ??????w5500_sock_write_byte(0,?Sn_IR,?j); ????} ????delay_ms(5);//延時(shí)5ms ????if((j?&?IR_TIMEOUT)?==?IR_TIMEOUT) ????{ ??????return?SOCKET_FAILURE; ????} ????else?if(w5500_sock_read_byte(0,?Sn_DHAR)?!=?0xff) ????{ ??????w5500_sock_write_byte(0,?Sn_CR,?CLOSE);?//關(guān)閉Socket ??????return?SOCKET_OK; ????} ??} ??while(1); } static?void?w5500_socket_init(SOCKET?s) { ??//設(shè)置分片長(zhǎng)度,參考W5500數(shù)據(jù)手冊(cè),該值可以不修改 ??w5500_sock_write_short(0,?Sn_MSSR,?1460);//最大分片字節(jié)數(shù)=1460(0x5b4) ??//設(shè)置指定端口 ??switch(s) ??{ ??case?0: ??{ ????if(UDP_MODE?==?s0_mode) ????{ ??????//設(shè)置端口0的端口號(hào) ??????w5500_sock_write_short(0,?Sn_PORT,?s0_port[0]?*?256?+?s0_port[1]); ????} ????else?if(TCP_CLIENT?==?s0_mode) ????{ ??????//設(shè)置端口0的端口號(hào) ??????w5500_sock_write_short(0,?Sn_PORT,?s0_port[0]?*?256?+?s0_port[1]); ??????//設(shè)置端口0目的(遠(yuǎn)程)端口號(hào) ??????w5500_sock_write_short(0,?Sn_DPORTR,?s0_dport[0]?*?256?+?s0_dport[1]); ??????//設(shè)置端口0目的(遠(yuǎn)程)IP地址 ??????w5500_sock_write_4bytes(0,?Sn_DIPR,?s0_dip); ????} ????else?if(TCP_SERVER?==?s0_mode) ????{ ??????//設(shè)置端口0的端口號(hào) ??????w5500_sock_write_short(0,?Sn_PORT,?s0_port[0]?*?256?+?s0_port[1]); ????} ??} ??break; ??case?1: ????break; ??case?2: ????break; ??case?3: ????break; ??case?4: ????break; ??case?5: ????break; ??case?6: ????break; ??case?7: ????break; ??default: ????break; ??} } static?uint8_t?w5500_socket_connect(SOCKET?s) { ??w5500_sock_write_byte(s,?Sn_MR,?MR_TCP);? ??w5500_sock_write_byte(s,?Sn_CR,?OPEN);? ??delay_ms(5); ??if(w5500_sock_read_byte(s,?Sn_SR)?!=?SOCK_INIT)? ??{ ????w5500_sock_write_byte(s,?Sn_CR,?CLOSE);? ????return?SOCKET_FAILURE; ??} ??w5500_sock_write_byte(s,?Sn_CR,?CONNECT);? ??return?SOCKET_OK; } static?uint8_t?w5500_socket_listen(SOCKET?s) { ??w5500_sock_write_byte(s,?Sn_MR,?MR_TCP);? ??w5500_sock_write_byte(s,?Sn_CR,?OPEN); ??delay_ms(5); ??if(w5500_sock_read_byte(s,?Sn_SR)?!=?SOCK_INIT)? ??{ ????w5500_sock_write_byte(s,?Sn_CR,?CLOSE);? ????return?SOCKET_FAILURE; ??} ??w5500_sock_write_byte(s,?Sn_CR,?LISTEN);? ??delay_ms(5); ??if(w5500_sock_read_byte(s,?Sn_SR)?!=?SOCK_LISTEN) ??{ ????w5500_sock_write_byte(s,?Sn_CR,?CLOSE); ????return?SOCKET_FAILURE; ??} ??return?SOCKET_OK; } static?uint8_t?w5500_socket_udp(SOCKET?s) { ??w5500_sock_write_byte(s,?Sn_MR,?MR_UDP); ??w5500_sock_write_byte(s,?Sn_CR,?OPEN); ??delay_ms(5); ??if(w5500_sock_read_byte(s,?Sn_SR)?!=?SOCK_UDP) ??{ ????w5500_sock_write_byte(s,?Sn_CR,?CLOSE); ????return?SOCKET_FAILURE; ??} ??else ??{ ????return?SOCKET_OK; ??} } static?void?w5500_load_para(void) { ??gateway_addr[0]?=?192; ??gateway_addr[1]?=?168; ??gateway_addr[2]?=?1; ??gateway_addr[3]?=?1; ??sub_mask[0]?=?255; ??sub_mask[1]?=?255; ??sub_mask[2]?=?255; ??sub_mask[3]?=?0; ??mac_addr[0]?=?0x0c; ??mac_addr[1]?=?0x29; ??mac_addr[2]?=?0xab; ??mac_addr[3]?=?0x7c; ??mac_addr[4]?=?0x00; ??mac_addr[5]?=?0x02; ??ip_addr[0]?=?192; ??ip_addr[1]?=?168; ??ip_addr[2]?=?1; ??ip_addr[3]?=?199; ??s0_port[0]?=?0x18; ??s0_port[1]?=?0x56; ??udp_daddr[0]?=?192; ??udp_daddr[1]?=?168; ??udp_daddr[2]?=?1; ??udp_daddr[3]?=?190; #if?0 ??s0_dip[0]?=?192; ??s0_dip[1]?=?168; ??s0_dip[2]?=?1; ??s0_dip[3]?=?99; ??s0_dport[0]?=?0x18;? ??s0_dport[1]?=?0x56;? #endif ??udp_dport[0]?=?0x17; ??udp_dport[1]?=?0x70; ??s0_mode?=?UDP_MODE; } void?W5500Init(void) { ??w5500_gpio_init(); ??w5500_spi_init(); ??w5500_load_para();?//?load?net?para?[ip,?port,?mask...] ??w5500_hardware_reset(); ??w5500_reg_init(); ??w5500_gateway_check(); ??w5500_socket_init(0); } void?W5500SocketScan(void) { ??if(s0_state?==?0) ??{ ????if(s0_mode?==?TCP_SERVER) ????{ ??????if(w5500_socket_listen(0)?==?SOCKET_OK) ??????{ ????????s0_state?=?S_INIT; ??????} ??????else ??????{ ????????s0_state?=?0; ??????} ????} ????else?if(s0_mode?==?TCP_CLIENT) ????{ ??????if(w5500_socket_connect(0)?==?SOCKET_OK) ??????{ ????????s0_state?=?S_INIT; ??????} ??????else ??????{ ????????s0_state?=?0; ??????} ????} ????else ????{ ??????if(w5500_socket_udp(0)?==?SOCKET_OK) ??????{ ????????debug("1234rn"); ????????s0_state?=?S_INIT?|?S_CONN; ??????} ??????else ??????{ ????????s0_state?=?0; ??????} ????} ??} } uint16_t?W5500SocketRecv(uint8_t?*buffer) { ??uint16_t?length; ??if((s0_data?&?S_RECEIVE)?==?S_RECEIVE) ??{ ????s0_data?&=?~S_RECEIVE; ????length?=?w5500_socket_read(0,?buffer); ??} ??return?length; } void?W5500SocketSend(uint8_t?*buffer,?uint16_t?length) { ??if(s0_state?==?(S_INIT?|?S_CONN)) ??{ ????s0_data?&=?~S_TRANSMITOK; ????w5500_socket_write(0,?buffer,?length); ??} } void?W5500InterruptProcess(void) { ??uint8_t?i,?j; IntDispose: ??i?=?w5500_read_byte(IR);//讀取中斷標(biāo)志寄存器 ??w5500_write_byte(IR,?(i?&?0xf0));//回寫(xiě)清除中斷標(biāo)志 ??if((i?&?CONFLICT)?==?CONFLICT)//IP地址沖突異常處理 ??{ ????//自己添加代碼 ??} ??if((i?&?UNREACH)?==?UNREACH)//UDP模式下地址無(wú)法到達(dá)異常處理 ??{ ????debug("-------n"); ????//自己添加代碼 ??} ??i?=?w5500_read_byte(SIR);?//讀取端口中斷標(biāo)志寄存器 ??if((i?&?S0_INT)?==?S0_INT)//Socket0事件處理 ??{ ????j?=?w5500_sock_read_byte(0,?Sn_IR);?//讀取Socket0中斷標(biāo)志寄存器 ????w5500_sock_write_byte(0,?Sn_IR,?j); ????if(j?&?IR_CON)?//在TCP模式下,Socket0成功連接 ????{ ??????s0_state?|=?S_CONN;?//網(wǎng)絡(luò)連接狀態(tài)0x02,端口完成連接,可以正常傳輸數(shù)據(jù) ????} ????if(j?&?IR_DISCON)?//在TCP模式下Socket斷開(kāi)連接處理 ????{ ??????w5500_sock_write_byte(0,?Sn_CR,?CLOSE);?//關(guān)閉端口,等待重新打開(kāi)連接 ??????w5500_socket_init(0);???//指定Socket(0~7)初始化,初始化端口0 ??????s0_state?=?0;?//網(wǎng)絡(luò)連接狀態(tài)0x00,端口連接失敗 ????} ????if(j?&?IR_SEND_OK)?//Socket0數(shù)據(jù)發(fā)送完成,可以再次啟動(dòng)S_tx_process()函數(shù)發(fā)送數(shù)據(jù) ????{ ??????s0_data?|=?S_TRANSMITOK;?//端口發(fā)送一個(gè)數(shù)據(jù)包完成 ????} ????if(j?&?IR_RECV)?//Socket接收到數(shù)據(jù),可以啟動(dòng)S_rx_process()函數(shù) ????{ ??????s0_data?|=?S_RECEIVE;?//端口接收到一個(gè)數(shù)據(jù)包 ????} ????if(j?&?IR_TIMEOUT)?//Socket連接或數(shù)據(jù)傳輸超時(shí)處理 ????{ ??????w5500_sock_write_byte(0,?Sn_CR,?CLOSE);?//?關(guān)閉端口,等待重新打開(kāi)連接 ??????s0_state?=?0;?//網(wǎng)絡(luò)連接狀態(tài)0x00,端口連接失敗 ????} ??} ??if(w5500_read_byte(SIR)?!=?0) ??{ ????goto?IntDispose; ??} } //?test?use static?void?socket_data_process(SOCKET?s) { ??w5500_frame_t?frame; ??frame.length?=?w5500_socket_read(s,?frame.data); //?debug("socket_data_process...rn"); ??W5500QueueWrite(&w5500_queue_recv,?&frame); ??if(UDP_MODE?==?s0_mode) ??{ ????udp_daddr[0]?=?frame.data[0]; ????udp_daddr[1]?=?frame.data[1]; ????udp_daddr[2]?=?frame.data[2]; ????udp_daddr[3]?=?frame.data[3]; ????udp_dport[0]?=?frame.data[4]; ????udp_dport[1]?=?frame.data[5]; ??} } void?W5500Process(void) { ??W5500SocketScan(); ??debug("22222rn"); ??W5500InterruptProcess(); ??debug("3333rn"); ??if((s0_data?&?S_RECEIVE)?==?S_RECEIVE)//如果Socket0接收到數(shù)據(jù) ??{ ????s0_data?&=?~S_RECEIVE; ????socket_data_process(0);//W5500接收并發(fā)送接收到的數(shù)據(jù) ??} ??debug("1111rn"); } void?w5500_test(void) { ??static?uint16_t?W5500_Send_Delay_Counter?=?0; ??W5500_Send_Delay_Counter++; ??W5500SocketScan(); ??W5500InterruptProcess(); ??if((s0_data?&?S_RECEIVE)?==?S_RECEIVE)//如果Socket0接收到數(shù)據(jù) ??{ ????s0_data?&=?~S_RECEIVE; ????socket_data_process(0);//W5500接收并發(fā)送接收到的數(shù)據(jù) ??} ??else?if(W5500_Send_Delay_Counter?>=?500)//定時(shí)發(fā)送字符串 ??{ ????if(s0_state?==?(S_INIT?|?S_CONN)) ????{ ??????s0_data?&=?~S_TRANSMITOK; ??????memcpy(socket_tx_buffer,?"rn123456rn",?10); ??????w5500_socket_write(0,?socket_tx_buffer,?10);//指定Socket(0~7)發(fā)送數(shù)據(jù)處理,端口0發(fā)送23字節(jié)數(shù)據(jù) ??????W5500_Send_Delay_Counter?=?0; ????} ??} }