代码语言
.
CSharp
.
JS
Java
Asp.Net
C
MSSQL
PHP
Css
PLSQL
Python
Shell
EBS
ASP
Perl
ObjC
VB.Net
VBS
MYSQL
GO
Delphi
AS
DB2
Domino
Rails
ActionScript
Scala
代码分类
文件
系统
字符串
数据库
网络相关
图形/GUI
多媒体
算法
游戏
Jquery
Extjs
Android
HTML5
菜单
网页交互
WinForm
控件
企业应用
安全与加密
脚本/批处理
开放平台
其它
【
C
】
W5500网卡驱动
作者:
Alex
/ 发布于
2015/6/25
/
1302
C51程序,基于SPI操作W5500,若要移植到ARM,只需要把模拟SPI那块改下就可以了。
#include "webserver.h" #include "w5500.h" void main(void) { IT0 = 1; //负跳变中断触发 EX0 = 1; //打开外部中断 EA = 1; //打开终中断 w5500_hardware_reset(); //W5500硬复位,通过引脚RST电平触发 w5500_init(); //w5500初始化 socket_init(SOCKET0, 80); //初始化SOCKET socket_listen(SOCKET0); //监听 while(1) { if(W5500_IRQMARK_ISSET()) //检测中断标志 w5500_irq_process(); //IRQ处理过程 } } //中断处理,使用1寄存器组压栈 void INT0_irq(void) interrupt 0 using 1 { //通过设置一个变量来触发w5500_irq_process函数 //中断处理时间不能太长,不然很影响性能, //所以用标志变量触发Main函数的中断处理函数 //w5500.h EA = 0; W5500_SET_IRQMARK(); EA = 1; } #ifndef _W5500_H_ #define _W5500_H_ #include <reg52.h> /***************** Common Register *****************/ #define MR 0x0000 #define RST 0x80 #define WOL 0x20 #define PB 0x10 #define PPP 0x08 #define FARP 0x02 #define GAR 0x0001 #define SUBR 0x0005 #define SHAR 0x0009 #define SIPR 0x000f #define INTLEVEL 0x0013 #define IR 0x0015 #define CONFLICT 0x80 #define UNREACH 0x40 #define PPPOE 0x20 #define MP 0x10 #define IMR 0x0016 #define IM_IR7 0x80 #define IM_IR6 0x40 #define IM_IR5 0x20 #define IM_IR4 0x10 #define SIR 0x0017 #define S7_INT 0x80 #define S6_INT 0x40 #define S5_INT 0x20 #define S4_INT 0x10 #define S3_INT 0x08 #define S2_INT 0x04 #define S1_INT 0x02 #define S0_INT 0x01 #define SIMR 0x0018 #define S7_IMR 0x80 #define S6_IMR 0x40 #define S5_IMR 0x20 #define S4_IMR 0x10 #define S3_IMR 0x08 #define S2_IMR 0x04 #define S1_IMR 0x02 #define S0_IMR 0x01 #define RTR 0x0019 #define RCR 0x001b #define PTIMER 0x001c #define PMAGIC 0x001d #define PHA 0x001e #define PSID 0x0024 #define PMRU 0x0026 #define UIPR 0x0028 #define UPORT 0x002c #define PHYCFGR 0x002e #define RST_PHY 0x80 #define OPMODE 0x40 #define DPX 0x04 #define SPD 0x02 #define LINK 0x01 #define VERR 0x0039 /********************* Socket Register *******************/ #define Sn_MR 0x0000 #define MULTI_MFEN 0x80 #define BCASTB 0x40 #define ND_MC_MMB 0x20 #define UCASTB_MIP6B 0x10 #define MR_CLOSE 0x00 #define MR_TCP 0x01 #define MR_UDP 0x02 #define MR_MACRAW 0x04 #define Sn_CR 0x0001 #define OPEN 0x01 #define LISTEN 0x02 #define CONNECT 0x04 #define DISCON 0x08 #define CLOSE 0x10 #define SEND 0x20 #define SEND_MAC 0x21 #define SEND_KEEP 0x22 #define RECV 0x40 #define Sn_IR 0x0002 #define IR_SEND_OK 0x10 #define IR_TIMEOUT 0x08 #define IR_RECV 0x04 #define IR_DISCON 0x02 #define IR_CON 0x01 #define Sn_SR 0x0003 #define SOCK_CLOSED 0x00 #define SOCK_INIT 0x13 #define SOCK_LISTEN 0x14 #define SOCK_ESTABLISHED 0x17 #define SOCK_CLOSE_WAIT 0x1c #define SOCK_UDP 0x22 #define SOCK_MACRAW 0x02 #define SOCK_SYNSEND 0x15 #define SOCK_SYNRECV 0x16 #define SOCK_FIN_WAI 0x18 #define SOCK_CLOSING 0x1a #define SOCK_TIME_WAIT 0x1b #define SOCK_LAST_ACK 0x1d #define Sn_PORT 0x0004 #define Sn_DHAR 0x0006 #define Sn_DIPR 0x000c #define Sn_DPORTR 0x0010 #define Sn_MSSR 0x0012 #define Sn_TOS 0x0015 #define Sn_TTL 0x0016 #define Sn_RXBUF_SIZE 0x001e #define Sn_TXBUF_SIZE 0x001f #define Sn_TX_FSR 0x0020 #define Sn_TX_RD 0x0022 #define Sn_TX_WR 0x0024 #define Sn_RX_RSR 0x0026 #define Sn_RX_RD 0x0028 #define Sn_RX_WR 0x002a #define Sn_IMR 0x002c #define IMR_SENDOK 0x10 #define IMR_TIMEOUT 0x08 #define IMR_RECV 0x04 #define IMR_DISCON 0x02 #define IMR_CON 0x01 #define Sn_FRAG 0x002d #define Sn_KPALVTR 0x002f /*******************************************************************/ /************************ SPI Control Byte *************************/ /*******************************************************************/ /* Operation mode bits */ #define VDM 0x00 #define FDM1 0x01 #define FDM2 0x02 #define FDM4 0x03 /* Read_Write control bit */ #define RWB_READ 0x00 #define RWB_WRITE 0x04 /* Block select bits */ #define COMMON_R 0x00 /* Socket 0 */ #define S0_REG 0x08 #define S0_TX_BUF 0x10 #define S0_RX_BUF 0x18 /* Socket 1 */ #define S1_REG 0x28 #define S1_TX_BUF 0x30 #define S1_RX_BUF 0x38 /* Socket 2 */ #define S2_REG 0x48 #define S2_TX_BUF 0x50 #define S2_RX_BUF 0x58 /* Socket 3 */ #define S3_REG 0x68 #define S3_TX_BUF 0x70 #define S3_RX_BUF 0x78 /* Socket 4 */ #define S4_REG 0x88 #define S4_TX_BUF 0x90 #define S4_RX_BUF 0x98 /* Socket 5 */ #define S5_REG 0xa8 #define S5_TX_BUF 0xb0 #define S5_RX_BUF 0xb8 /* Socket 6 */ #define S6_REG 0xc8 #define S6_TX_BUF 0xd0 #define S6_RX_BUF 0xd8 /* Socket 7 */ #define S7_REG 0xe8 #define S7_TX_BUF 0xf0 #define S7_RX_BUF 0xf8 #define TRUE 0xff #define FALSE 0x00 #define S_RX_SIZE 2048 #define S_TX_SIZE 2048 sbit W5500_RST = P3^3; sbit W5500_INT = P3^2; sbit W5500_SCS = P3^6; sbit W5500_SCLK = P3^7; sbit W5500_MISO = P3^4; sbit W5500_MOSI = P3^5; #define PHYADDR0 0x02 #define PHYADDR1 0x00 #define PHYADDR2 0x01 #define PHYADDR3 0x05 #define PHYADDR4 0x06 #define PHYADDR5 0x0e #define IPADDR0 192 #define IPADDR1 168 #define IPADDR2 1 #define IPADDR3 40 #define NETMASK0 255 #define NETMASK1 255 #define NETMASK2 255 #define NETMASK3 0 #define DRIPADDR0 192 #define DRIPADDR1 168 #define DRIPADDR2 1 #define DRIPADDR3 1 #define SOCKET unsigned char #define SOCKET0 0 #define SOCKET1 1 #define SOCKET2 2 #define SOCKET3 3 #define SOCKET4 4 #define SOCKET5 5 #define SOCKET6 6 #define SOCKET7 7 #include "webserver.h" #define W5500_IRQ_CALLBACK web_appcall #define W5500_SOCKET_DISCONN 0x01 #define W5500_SOCKET_CONN 0x02 #define W5500_SOCKET_SNDOK 0x04 #define W5500_SOCKET_RECVOK 0x08 #define W5500_SOCKET_TIMEOUT 0x10 #define W5500_IRQ_MARK 0x80 #define w5500_connect() (w5500_flags & W5500_SOCKET_CONN) #define w5500_disconnect() (w5500_flags & W5500_SOCKET_DISCONN) #define w5500_sendok() (w5500_flags & W5500_SOCKET_SNDOK) #define w5500_recvok() (w5500_flags & W5500_SOCKET_RECVOK) #define w5500_timeout() (w5500_flags & W5500_SOCKET_TIMEOUT) #define W5500_IRQMARK_ISSET() (w5500_flags & W5500_IRQ_MARK) #define W5500_SET_IRQMARK() do { w5500_flags |= W5500_IRQ_MARK; } while(0) #define W5500_RESET_IRQMARK() do { w5500_flags &= ~W5500_IRQ_MARK; } while(0) extern unsigned char w5500_flags; extern void w5500_hardware_reset(void); extern void w5500_init(void); extern void socket_init(SOCKET s, unsigned int port); extern unsigned char socket_listen(SOCKET s); extern void socket_close(SOCKET s); extern unsigned int socket_recv(SOCKET s, unsigned char *pbuf, unsigned int mxsize); extern void socket_send(SOCKET s, unsigned char *pbuf, unsigned int buf_size); extern void w5500_irq_process(void); #endif /* w5500驱动模块 作者邮箱: huangchaomeng@qq.com 2015年6月1日 */ #include <intrins.h> #include "w5500.h" /* 空读一次SPI。SPI读写前初始化"脉冲",因为有时候相隔一段时间后 第一个读取或者写入的字节会失败,所以先读写0一次。 */ #define W5500_NOP() do { W5500_MISO = 0; \ W5500_MOSI = 0; \ w5500_read_byte(0x00); \ } while(0) //网卡物理地址 static unsigned char ethmac[6] = { PHYADDR0, PHYADDR1, PHYADDR2, PHYADDR3, PHYADDR4, PHYADDR5 }; //网卡IP地址 static unsigned char ipaddr[4] = { IPADDR0, IPADDR1, IPADDR2, IPADDR3 }; //网卡子网掩码 static unsigned char netmask[4] = { NETMASK0, NETMASK1, NETMASK2, NETMASK3 }; //网卡网关地址 static unsigned char dripaddr[4] = { DRIPADDR0, DRIPADDR1, DRIPADDR2, DRIPADDR3 }; unsigned char w5500_flags; //中断标志 //延迟 ms static void delay(unsigned int x) { unsigned int i,j; for(j=0;j<5;j++) for(i=0;i<x;i++); } //SPI读写时序,这里是模式0,具体可以参考SPI模式0时序图 static unsigned char spi_process(unsigned char dat) { unsigned char i, ret = 0; for(i = 0; i < 8; i++) { //判断最高位是否为0 if(dat & 0x80) W5500_MOSI = 1; //给高电平 else W5500_MOSI = 0; //给低电平 dat <<= 1; W5500_SCLK = 1; //SCK上升沿写入 ret <<= 1; ret |= W5500_MISO; //上升沿写入的同时读取 W5500_SCLK = 0; //恢复默认电平 } return ret; } //SPI写入一个字节 static void spi_write(unsigned char dat) { spi_process(dat); } //SPI读取一个字节 static unsigned char spi_read(void) { return spi_process(0x00); } //SPI写入2个字节 static void spi_write_short(unsigned int dat) { spi_write((unsigned char)(dat >> 8)); //先写入高8位字节 spi_write((unsigned char)(dat & 0x00ff)); } //向W5500通用寄存器写入1字节数据,参数1:寄存器地址,参数二:数据 static void w5500_write_byte(unsigned int reg, unsigned char dat) { W5500_SCS = 0; //置W5500的SCS为低电平 spi_write_short(reg); //通过SPI写16位寄存器地址 spi_write(FDM1|RWB_WRITE|COMMON_R); //通过SPI写控制字节,1个字节数据长度,写数据,选择通用寄存器 spi_write(dat); //写1个字节数据 W5500_SCS = 1; //置W5500的SCS为高电平 } //向W5500通用寄存器写入2个字节数据,参数1:寄存器地址,参数二:数据 static void w5500_write_short(unsigned int reg, unsigned int dat) { W5500_SCS = 0; spi_write_short(reg); //通过SPI写16位寄存器地址 spi_write(FDM2|RWB_WRITE|COMMON_R); //通过SPI写控制字节,2个字节数据长度,写数据,选择通用寄存器 spi_write_short(dat); //写16位数据 W5500_SCS = 1; } //向W5500通用寄存器写入X个字节数据,参数1:寄存器地址,参数二:数据指针,参数三:数据大小 static void w5500_write_xbit(unsigned int reg, unsigned char *pdat, unsigned int size) { unsigned int i; W5500_SCS = 0; spi_write_short(reg); spi_write(VDM|RWB_WRITE|COMMON_R); //写入可X字节,写入字节数由CS控制,FDM1写入1字节,FDM2二字节,VDM可变字节 for(i = 0; i < size; i++) { spi_write(*pdat); ++pdat; } W5500_SCS = 1; } //向W5500的SOCKET寄存器写入一个字节数据,参数1:SOCKET,参数二:寄存器地址,参数三:数据 static void w5500_wirte_sock_byte(SOCKET s, unsigned int reg, unsigned char dat) { W5500_SCS = 0; spi_write_short(reg); //通过SPI写16位寄存器地址 spi_write(FDM1|RWB_WRITE|(s*0x20+0x08)); //通过SPI写控制字节,1个字节数据长度,写数据,选择端口s的寄存器 spi_write(dat); //写1个字节数据 W5500_SCS = 1; } //向W5500的SOCKET寄存器写入2个字节数据,参数1:SOCKET,参数二:寄存器地址,参数三:数据 static void w5500_wirte_sock_short(SOCKET s, unsigned int reg, unsigned int dat) { W5500_SCS = 0; spi_write_short(reg); spi_write(FDM2|RWB_WRITE|(s*0x20+0x08)); spi_write_short(dat); W5500_SCS = 1; } //向W5500的通用寄存器读取一个字节数据,参数1:寄存器地址 static unsigned char w5500_read_byte(unsigned int reg) { unsigned char ret; W5500_SCS = 0; spi_write_short(reg); spi_write(FDM1|RWB_READ|COMMON_R); ret = spi_read(); W5500_SCS = 1; return ret; } //向W5500的SOCKET寄存器读取一个字节数据,参数1:SOCKET,参数二:寄存器地址 static unsigned char w5500_read_sock_byte(SOCKET s, unsigned int reg) { unsigned char ret; W5500_SCS = 0; spi_write_short(reg); spi_write(FDM1|RWB_READ|(s*0x20+0x08)); ret = spi_read(); W5500_SCS = 1; return ret; } //向W5500的SOCKET寄存器读取两个字节的数据,参数1:SOCKET,参数二:寄存器地址 static unsigned int w5500_read_sock_short(SOCKET s, unsigned int reg) { unsigned int ret; W5500_SCS = 0; spi_write_short(reg); spi_write(FDM2|RWB_READ|(s*0x20+0x08)); ret = spi_read(); ret <<= 8; ret |= spi_read(); W5500_SCS = 1; return ret; } //向W5500的SOCKET数据缓冲器读取接收到的数据包,参数1:SOCKET,参数二,数据缓冲区,参数三: //缓冲区最大大小 static unsigned int w5500_read_sock_buffer(SOCKET s, unsigned char *pbuf, unsigned int mxsize) { unsigned int rx_size; unsigned int offset, offset1; unsigned int i; unsigned char j; unsigned int count; W5500_NOP(); rx_size = w5500_read_sock_short(s, Sn_RX_RSR); if(rx_size == 0) return 0; //没接收到数据则返回 if(rx_size > 1460) rx_size = 1460; W5500_NOP(); offset = w5500_read_sock_short(s, Sn_RX_RD); offset1 = offset; offset &= (S_RX_SIZE-1); //计算实际的物理地址 W5500_SCS = 0; //置W5500的SCS为低电平 count = 0; spi_write_short(offset); //写16位地址 spi_write(VDM|RWB_READ|(s*0x20+0x18)); //写控制字节,N个字节数据长度,读数据,选择端口s的寄存器 //如果最大地址未超过W5500接收缓冲区寄存器的最大地址 if((offset+rx_size) < S_RX_SIZE) { //循环读取rx_size个字节数据 for(i = 0; i < rx_size; i++) { j = spi_read(); //超过mxsize的数据将被遗弃 if(++count <= mxsize) { *pbuf = j; //将读取到的数据保存到数据保存缓冲区 ++pbuf; //数据保存缓冲区指针地址自增1 } } } else { offset = S_RX_SIZE - offset; //循环读取出前offset个字节数据 for(i = 0; i < offset; i++) { j = spi_read(); if(++count <= mxsize) { *pbuf = j; ++pbuf; } } W5500_SCS = 1; W5500_SCS = 0; spi_write_short(0x00); //写16位地址 spi_write(VDM|RWB_READ|(s*0x20+0x18)); //循环读取后rx_size-offset个字节数据 for(; i < rx_size; i++) { j = spi_read(); if(++count <= mxsize) { *pbuf = j; ++pbuf; } } } offset1 += rx_size; //更新实际物理地址,即下次读取接收到的数据的起始地址 w5500_wirte_sock_short(s, Sn_RX_RD, offset1); w5500_wirte_sock_byte(s, Sn_CR, RECV); //发送启动接收命令 W5500_SCS = 1; return count < mxsize ? rx_size : mxsize; } //向W5500的SOCKET数据缓冲器写入数据,参数1:SOCKET,参数二,数据缓冲区,参数三: //数据大小 static void w5500_write_sock_buffer(SOCKET s, unsigned char *pbuf, unsigned int size) { unsigned int offset,offset1; unsigned int i; W5500_NOP(); offset = w5500_read_sock_short(s, Sn_TX_WR); offset1 = offset; offset &= (S_TX_SIZE-1); //计算实际的物理地址 W5500_SCS = 0; spi_write_short(offset); spi_write(VDM|RWB_WRITE|(s*0x20+0x10)); //如果最大地址未超过W5500发送缓冲区寄存器的最大地址 if((offset+size) < S_TX_SIZE) { for(i = 0; i < size; i++) { spi_write(*pbuf); ++pbuf; } } else { offset = S_TX_SIZE - offset; for(i = 0; i < offset; i++) { spi_write(*pbuf); ++pbuf; } W5500_SCS = 1; W5500_SCS = 0; spi_write_short(0x00); spi_write(VDM|RWB_WRITE|(s*0x20+0x10)); for(; i < size; i++) { spi_write(*pbuf); ++pbuf; } } W5500_SCS = 1; offset1 += size; //更新实际物理地址,即下次写待发送数据到发送数据缓冲区的起始地址 w5500_wirte_sock_short(s, Sn_TX_WR, offset1); w5500_wirte_sock_byte(s, Sn_CR, SEND); //发送启动发送命令 } //W5500硬重启 void w5500_hardware_reset(void) { unsigned char k; W5500_RST = 0; //拉低RST引脚电平,硬复位 delay(100); //低电平持续时间 W5500_RST = 1; //拉高RST引脚,恢复工作状态 delay(100); //引脚初始化 W5500_SCLK = 0; W5500_SCS = 1; W5500_MOSI = 0; W5500_MISO = 0; //检测PHYCFGR寄存器的第一位值,检测是否连接上网络设备 while(1) { k = w5500_read_byte(PHYCFGR); if((k & LINK) != 0) break; //连接上,就退出 } } //W5500初始化 void w5500_init(void) { unsigned char i = 0; w5500_flags = 0; w5500_write_byte(MR, RST); //发送软复位命令 delay(100); //给内部寄存器初始化时间 w5500_write_xbit(GAR, dripaddr, 4); //设置网关地址 w5500_write_xbit(SUBR, netmask, 4); //设置子网掩码 w5500_write_xbit(SHAR, ethmac, 6); //设置MAC地址 w5500_write_xbit(SIPR, ipaddr, 4); //设置设置IP地址 //32KB缓存,每个SOCKET给4K,分别给每个SOCKET的接收和发送缓冲区,具体参考 //w5500手册 for(i = 0; i < 8; i++) { w5500_wirte_sock_byte(i, Sn_RXBUF_SIZE, 0x02); w5500_wirte_sock_byte(i, Sn_TXBUF_SIZE, 0x02); } //设置重试时间,默认为2000(200ms) //每一单位数值为100微秒,初始化时值设为2000(0x07D0),等于200毫秒 w5500_write_short(RTR, 0x0fa0); //设置重试次数,默认为8次 //如果重发的次数超过设定值,则产生超时中断(相关的端口中断寄存器中的Sn_IR 超时位(TIMEOUT)置“1”) w5500_write_byte(RCR, 10); w5500_write_byte(SIMR, S0_IMR); //开启W5500的SOCKET0中断 } void socket_init(SOCKET s, unsigned int port) { switch(s) { case SOCKET0: W5500_NOP(); w5500_wirte_sock_short(SOCKET0, Sn_MSSR, 1400); //设置MTU分片 w5500_wirte_sock_short(SOCKET0, Sn_PORT, port); //打开socket0的端口 w5500_wirte_sock_byte(SOCKET0, Sn_TTL, 64); //IP数据包生存时间 break; case SOCKET1: break; case SOCKET2: break; case SOCKET3: break; case SOCKET4: break; case SOCKET5: break; case SOCKET6: break; case SOCKET7: break; } } unsigned char socket_listen(SOCKET s) { unsigned char ret; W5500_NOP(); w5500_wirte_sock_byte(s, Sn_MR, MR_TCP); //设置socket为TCP模式 w5500_wirte_sock_byte(s, Sn_CR, OPEN); //打开Socket ret = w5500_read_sock_byte(s, Sn_SR); if(ret != SOCK_INIT) { w5500_wirte_sock_byte(s, Sn_CR, CLOSE); //打开不成功,关闭Socket return 0; } w5500_wirte_sock_byte(s, Sn_CR, LISTEN); //设置Socket为侦听模式 ret = w5500_read_sock_byte(s, Sn_SR); if(ret != SOCK_LISTEN) { w5500_wirte_sock_byte(s, Sn_CR, CLOSE); return 0; } return 1; //至此完成了Socket的打开和设置侦听工作,至于远程客户端是否与它建立连接,则需要等待Socket中断, //以判断Socket的连接是否成功。参考W5500数据手册的Socket中断状态 //在服务器侦听模式不需要设置目的IP和目的端口号 } //关闭SOCKET void socket_close(SOCKET s) { W5500_NOP(); w5500_wirte_sock_byte(s, Sn_CR, CLOSE); //发送关闭命令 } //接收数据 unsigned int socket_recv(SOCKET s, unsigned char *pbuf, unsigned int mxsize) { return w5500_read_sock_buffer(s, pbuf, mxsize); } //发送数据 void socket_send(SOCKET s, unsigned char *pbuf, unsigned int buf_size) { w5500_write_sock_buffer(s, pbuf, buf_size); } //中断处理 void w5500_irq_process(void) { unsigned char i,j; W5500INT: W5500_NOP(); i = w5500_read_byte(SIR); //读取中断标志 //SOCKET0中断 if(i & S0_INT) { j = w5500_read_sock_byte(SOCKET0, Sn_IR); w5500_wirte_sock_byte(SOCKET0, Sn_IR, j); //回写中断标志,复位INT引脚 w5500_flags &= W5500_IRQ_MARK; //清除标志位 //连接成功 if(j & IR_CON) { w5500_flags |= W5500_SOCKET_CONN; } //断开连接 if(j & IR_DISCON) { w5500_flags |= W5500_SOCKET_DISCONN; } //发送成功 if(j & IR_SEND_OK) { w5500_flags |= W5500_SOCKET_SNDOK; } //接收成功 if(j & IR_RECV) { w5500_flags |= W5500_SOCKET_RECVOK; } //超时 if(j & IR_TIMEOUT) { w5500_flags |= W5500_SOCKET_TIMEOUT; } W5500_IRQ_CALLBACK(); //回调函数 } //SOCKET1中断 if(i & S1_INT) { } //SOCKET2中断 if(i & S2_INT) { } //SOCKET3中断 if(i & S3_INT) { } //SOCKET4中断 if(i & S4_INT) { } //SOCKET5中断 if(i & S5_INT) { } //SOCKET6中断 if(i & S6_INT) { } //SOCKET7中断 if(i & S7_INT) { } W5500_NOP(); i = w5500_read_byte(SIR); //检测是否又有中断触发 if(i != 0) goto W5500INT; W5500_RESET_IRQMARK(); } #ifndef _WEBSERVER_H_ #define _WEBSERVER_H_ extern void web_appcall(void); #endif #include "webserver.h" #include "w5500.h" #include <intrins.h> #define ISO_G 0x47 //"G" ascii码 #define ISO_E 0x45 //"E" ascii码 #define ISO_T 0x54 //"T" ascii码 //HTTP报文 static const unsigned char code webdata[] = { "HTTP 1.0 200 OK\r\n" "Content-Type: text/html; charset=UTF-8\r\n" "Pragma: no-cache\r\n\r\n" "<html>\r\n" "<head>\r\n" "<tiltle>test</tiltle>\r\n" "<head>\r\n" "<body>\r\n" "<center>\r\n" "<hl>test</hl>\r\n" "\r\n" "<hr>\r\n" "<font size=14>\r\n" "test\r\n" "</font>\r\n" "<hr>\r\n" "<font size=14>\r\n" "Email:huangchaomeng@qq.com\r\n" "<hr>\r\n" "<font size=24>\r\n" "null\r\n" "</font>\r\n" "</center>\r\n" "</body>\r\n" "</html>\r\n\0" }; static unsigned char buffer[350]; //数据缓冲区 //检测是否HTTP请求,加入是HTTP请求头部前三位是"GET" static unsigned char check_http_header(unsigned char *pbuf, unsigned int mxsize) { if(mxsize < 3) return 0; if(pbuf[0] != ISO_G) return 0; if(pbuf[1] != ISO_E) return 0; if(pbuf[2] != ISO_T) return 0; return 1; } static void web_reset(void) { unsigned char i; socket_close(SOCKET0); for(i = 0; i < 3; i++) _nop_(); socket_init(SOCKET0, 80); socket_listen(SOCKET0); } //获取字符串长度 static unsigned int __strlen(const unsigned char *pdat) { unsigned int ret = 0; while(*pdat != '\0') { ++pdat; ++ret; } return ret; } //回调 void web_appcall(void) { unsigned int size = 0; //连接成功 if(w5500_connect()) { } //断开连接 if(w5500_disconnect()) { web_reset(); } //发送成功 if(w5500_sendok()) { } //接收成功 if(w5500_recvok()) { //从缓冲区中读取数据 size = socket_recv(SOCKET0, buffer, 350); //检查HTTP头 if(!check_http_header(buffer, size)) { web_reset(); return; } size = __strlen(webdata); //回应HTTP请求数据 socket_send(SOCKET0, webdata, size); web_reset(); } //超时 if(w5500_timeout()) { web_reset(); } }
试试其它关键字
W5500
网卡驱动
同语言下
.
获取手机通讯录 iOS去除数字以外的所有字符
.
异步加载音乐等资源
.
交通罚单管理系统
.
freemark实现,简单的替换
.
计算斐波那契数列
.
base64解码 包括解码长度
.
图像显示
.
冒泡排序
.
输入十进制数,输出指定进制
.
链式栈
可能有用的
.
C#实现的html内容截取
.
List 切割成几份 工具类
.
SQL查询 多列合并成一行用逗号隔开
.
一行一行读取txt的内容
.
C#动态修改文件夹名称(FSO实现,不移动文件)
.
c# 移动文件或文件夹
.
c#图片添加水印
.
Java PDF转换成图片并输出给前台展示
.
网站后台修改图片尺寸代码
.
处理大图片在缩略图时的展示
Alex
贡献的其它代码
(
27
)
.
字典 Dictionary 遍历
.
读取http文件保存到本地
.
代码实现文件打包
.
用户登录过滤例子
.
HashMap中的内容进行迭代输出
.
根据银行卡账号获取所属银行
.
将HtmlTable内容导出到Excel,使用NPOI组件
.
判断页面滚动条是否到底部
.
把函数绑定到事件上
.
根据计算机硬件码生成注册码
Copyright © 2004 - 2024 dezai.cn. All Rights Reserved
站长博客
粤ICP备13059550号-3