STM32F103驱动W5500网络程序.docx_第1页
STM32F103驱动W5500网络程序.docx_第2页
STM32F103驱动W5500网络程序.docx_第3页
STM32F103驱动W5500网络程序.docx_第4页
STM32F103驱动W5500网络程序.docx_第5页
免费预览已结束,剩余25页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

#include W5500.h/*- 网络参数变量定义 -*/unsigned char Gateway_IP4;/网关IP地址 unsigned char Sub_Mask4;/子网掩码 unsigned char Phy_Addr6;/物理地址(MAC) unsigned char IP_Addr4;/本机IP地址 unsigned char S0_Port2;/端口0的端口号(5000) unsigned char S0_DIP4;/端口0目的IP地址 unsigned char S0_DPort2;/端口0目的端口号(6000) unsigned char UDP_DIPR4;/UDP(广播)模式,目的主机IP地址unsigned char UDP_DPORT2;/UDP(广播)模式,目的主机端口号/*- 端口的运行模式 -*/unsigned char S0_Mode =3;/端口0的运行模式,0:TCP服务器模式,1:TCP客户端模式,2:UDP(广播)模式#define TCP_SERVER0x00/TCP服务器模式#define TCP_CLIENT0x01/TCP客户端模式 #define UDP_MODE0x02/UDP(广播)模式 /*- 端口的运行状态 -*/unsigned char S0_State =0;/端口0状态记录,1:端口完成初始化,2端口完成连接(可以正常传输数据) #define S_INIT0x01/端口完成初始化 #define S_CONN0x02/端口完成连接,可以正常传输数据 /*- 端口收发数据的状态 -*/unsigned char S0_Data;/端口0接收和发送数据的状态,1:端口接收到数据,2:端口发送数据完成 #define S_RECEIVE 0x01/端口接收到一个数据包 #define S_TRANSMITOK 0x02/端口发送一个数据包完成 /*- 端口数据缓冲区 -*/unsigned char Rx_Buffer2048;/端口接收数据缓冲区 unsigned char Tx_Buffer2048;/端口发送数据缓冲区 unsigned char W5500_Interrupt;/W5500中断标志(0:无中断,1:有中断)/*外部中断4服务程序*/void EXTI4_IRQHandler(void)if(W5500_INT=0)W5500_Interrupt=1; EXTI-PR=1APB2ENR|=1APB2ENR|=1APB2ENR|=1CRL&=0XFFF0FFFF; GPIOA-CRL|=0X00030000;/PA4通用挽推输出,输出速度50MHz GPIOA-ODR|=1CRL&=0X000FFFFF; GPIOA-CRL|=0XBBB00000;/PA5.6.7复用功能挽推输出,输出速度50MHz GPIOA-ODR|=0X7CR1&=(1CR1=1CR1&=(1CR1&=(1CR1&=(1CR1|=1CR1|=1CR1|=0CR1&=(1CRCPR=0X07; SPI1-CR1|=1APB2ENR|=1CRL&=0XFF00FFFF;GPIOC-CRL|=0X00380000;GPIOC-ODR|=34;/PC4上拉,PC5输出高SPI1_Init();Ex_NVIC_Config(GPIO_C,4,FTIR); /下降沿触发 MY_NVIC_Init(2,0,EXTI4_IRQChannel,2);/抢占2,子优先级0,组2/* 函数名 : Write_W5500_1Byte* 描述 : 通过SPI1向指定地址寄存器写1个字节数据* 输入 : reg:16位寄存器地址,dat:待写入的数据* 输出 : 无* 返回值 : 无* 说明 : 无*/void Write_W5500_1Byte(u16 reg, u8 dat)W5500_CS_Low();/置W5500的SCS为低电平SPI1_Send_Short(reg);/通过SPI1写16位寄存器地址SPI1_ReadWriteByte(FDM1|RWB_WRITE|COMMON_R);/通过SPI1写控制字节,1个字节数据长度,写数据,选择通用寄存器SPI1_ReadWriteByte(dat);/写1个字节数据W5500_CS_High(); /置W5500的SCS为高电平/* 函数名 : Write_W5500_2Byte* 描述 : 通过SPI1向指定地址寄存器写2个字节数据* 输入 : reg:16位寄存器地址,dat:16位待写入的数据(2个字节)* 输出 : 无* 返回值 : 无* 说明 : 无*/void Write_W5500_2Byte(u16 reg, u16 dat)W5500_CS_Low();/置W5500的SCS为低电平SPI1_Send_Short(reg);/通过SPI1写16位寄存器地址SPI1_ReadWriteByte(FDM2|RWB_WRITE|COMMON_R);/通过SPI1写控制字节,2个字节数据长度,写数据,选择通用寄存器SPI1_Send_Short(dat);/写16位数据W5500_CS_High(); /置W5500的SCS为高电平/* 函数名 : Write_W5500_nByte* 描述 : 通过SPI1向指定地址寄存器写n个字节数据* 输入 : reg:16位寄存器地址,*dat_ptr:待写入数据缓冲区指针,size:待写入的数据长度* 输出 : 无* 返回值 : 无* 说明 : 无*/void Write_W5500_nByte(u16 reg, u8 *dat_ptr, u16 size)u16 i;W5500_CS_Low();/置W5500的SCS为低电平SPI1_Send_Short(reg);/通过SPI1写16位寄存器地址SPI1_ReadWriteByte(VDM|RWB_WRITE|COMMON_R);/通过SPI1写控制字节,N个字节数据长度,写数据,选择通用寄存器for(i=0;i1460) rx_size=1460;offset=Read_W5500_SOCK_2Byte(s,Sn_RX_RD);offset1=offset;offset&=(S_RX_SIZE-1);/计算实际的物理地址W5500_CS_Low();/置W5500的SCS为低电平SPI1_Send_Short(offset);/写16位地址j=SPI1_ReadWriteByte(VDM|RWB_READ|(s*0x20+0x18);/写控制字节,N个字节数据长度,读数据,选择端口s的寄存器/j=SPI_I2S_ReceiveData(SPI1);if(offset+rx_size)S_RX_SIZE)/如果最大地址未超过W5500接收缓冲区寄存器的最大地址for(i=0;irx_size;i+)/循环读取rx_size个字节数据/SPI1_Send_Byte(0x00);/发送一个哑数据j=SPI1_ReadWriteByte(0X00);/读取1个字节数据*dat_ptr=j;/将读取到的数据保存到数据保存缓冲区dat_ptr+;/数据保存缓冲区指针地址自增1else/如果最大地址超过W5500接收缓冲区寄存器的最大地址offset=S_RX_SIZE-offset;for(i=0;ioffset;i+)/循环读取出前offset个字节数据/SPI1_Send_Byte(0x00);/发送一个哑数据j=SPI1_ReadWriteByte(0X00);/读取1个字节数据*dat_ptr=j;/将读取到的数据保存到数据保存缓冲区dat_ptr+;/数据保存缓冲区指针地址自增1W5500_CS_High(); /置W5500的SCS为高电平W5500_CS_Low();/置W5500的SCS为低电平SPI1_Send_Short(0x00);/写16位地址j=SPI1_ReadWriteByte(VDM|RWB_READ|(s*0x20+0x18);/写控制字节,N个字节数据长度,读数据,选择端口s的寄存器/j=SPI_I2S_ReceiveData(SPI1);for(;irx_size;i+)/循环读取后rx_size-offset个字节数据/SPI1_Send_Byte(0x00);/发送一个哑数据j=SPI1_ReadWriteByte(0X00);/读取1个字节数据*dat_ptr=j;/将读取到的数据保存到数据保存缓冲区dat_ptr+;/数据保存缓冲区指针地址自增1W5500_CS_High(); /置W5500的SCS为高电平offset1+=rx_size;/更新实际物理地址,即下次读取接收到的数据的起始地址Write_W5500_SOCK_2Byte(s, Sn_RX_RD, offset1);Write_W5500_SOCK_1Byte(s, Sn_CR, RECV);/发送启动接收命令return rx_size;/返回接收到数据的长度/* 函数名 : Write_SOCK_Data_Buffer* 描述 : 将数据写入W5500的数据发送缓冲区* 输入 : s:端口号,*dat_ptr:数据保存缓冲区指针,size:待写入数据的长度* 输出 : 无* 返回值 : 无* 说明 : 无*/void Write_SOCK_Data_Buffer(SOCKET s, u8 *dat_ptr, u16 size)u16 offset,offset1;u16 i;/如果是UDP模式,可以在此设置目的主机的IP和端口号if(Read_W5500_SOCK_1Byte(s,Sn_MR)&0x0f) != SOCK_UDP)/如果Socket打开失败UDP_DIPR0 = Flash_Tab2;/UDP(广播)模式,目的主机IP地址UDP_DIPR1 = Flash_Tab3;UDP_DIPR2 = Flash_Tab4;UDP_DIPR3 = Flash_Tab5;/UDP_DPORT0 = Flash_Tab8;/UDP(广播)模式,目的主机端口号UDP_DPORT1 = Flash_Tab7;Write_W5500_SOCK_4Byte(s, Sn_DIPR, UDP_DIPR);/设置目的主机IP Write_W5500_SOCK_2Byte(s, Sn_DPORTR, UDP_DPORT0*256+UDP_DPORT1);/设置目的主机端口号offset=Read_W5500_SOCK_2Byte(s,Sn_TX_WR);offset1=offset;offset&=(S_TX_SIZE-1);/计算实际的物理地址W5500_CS_Low();/置W5500的SCS为低电平SPI1_Send_Short(offset);/写16位地址SPI1_ReadWriteByte(VDM|RWB_WRITE|(s*0x20+0x10);/写控制字节,N个字节数据长度,写数据,选择端口s的寄存器if(offset+size)S_TX_SIZE)/如果最大地址未超过W5500发送缓冲区寄存器的最大地址for(i=0;isize;i+)/循环写入size个字节数据SPI1_ReadWriteByte(*dat_ptr+);/写入一个字节的数据else/如果最大地址超过W5500发送缓冲区寄存器的最大地址offset=S_TX_SIZE-offset;for(i=0;ioffset;i+)/循环写入前offset个字节数据SPI1_ReadWriteByte(*dat_ptr+);/写入一个字节的数据W5500_CS_High(); /置W5500的SCS为高电平W5500_CS_Low();/置W5500的SCS为低电平SPI1_Send_Short(0x00);/写16位地址SPI1_ReadWriteByte(VDM|RWB_WRITE|(s*0x20+0x10);/写控制字节,N个字节数据长度,写数据,选择端口s的寄存器for(;isize;i+)/循环写入size-offset个字节数据SPI1_ReadWriteByte(*dat_ptr+);/写入一个字节的数据W5500_CS_High(); /置W5500的SCS为高电平offset1+=size;/更新实际物理地址,即下次写待发送数据到发送数据缓冲区的起始地址Write_W5500_SOCK_2Byte(s, Sn_TX_WR, offset1);Write_W5500_SOCK_1Byte(s, Sn_CR, SEND);/发送启动发送命令/* 函数名 : W5500_Hardware_Reset* 描述 : 硬件复位W5500* 输入 : 无* 输出 : 无* 返回值 : 无* 说明 : W5500的复位引脚保持低电平至少500us以上,才能重围W5500*/void W5500_Hardware_Reset(void)W5500_RST_Low();/复位引脚拉低delay_ms(50);W5500_RST_High();/复位引脚拉高delay_ms(200);/while(Read_W5500_1Byte(PHYCFGR)&LINK)=0);/等待以太网连接完成/* 函数名 : W5500_Init* 描述 : 初始化W5500寄存器函数* 输入 : 无* 输出 : 无* 返回值 : 无* 说明 : 在使用W5500之前,先对W5500初始化*/void W5500_Init(void)u8 i=0;Write_W5500_1Byte(MR, RST);/软件复位W5500,置1有效,复位后自动清0delay_ms(10);/延时10ms,自己定义该函数/设置网关(Gateway)的IP地址,Gateway_IP为4字节unsigned char数组,自己定义 /使用网关可以使通信突破子网的局限,通过网关可以访问到其它子网或进入InternetWrite_W5500_nByte(GAR, Gateway_IP, 4);/设置子网掩码(MASK)值,SUB_MASK为4字节unsigned char数组,自己定义/子网掩码用于子网运算Write_W5500_nByte(SUBR,Sub_Mask,4);/设置物理地址,PHY_ADDR为6字节unsigned char数组,自己定义,用于唯一标识网络设备的物理地址值/该地址值需要到IEEE申请,按照OUI的规定,前3个字节为厂商代码,后三个字节为产品序号/如果自己定义物理地址,注意第一个字节必须为偶数Write_W5500_nByte(SHAR,Phy_Addr,6);/设置本机的IP地址,IP_ADDR为4字节unsigned char数组,自己定义/注意,网关IP必须与本机IP属于同一个子网,否则本机将无法找到网关Write_W5500_nByte(SIPR,IP_Addr,4);/设置发送缓冲区和接收缓冲区的大小,参考W5500数据手册for(i=0;i8;i+)Write_W5500_SOCK_1Byte(i,Sn_RXBUF_SIZE, 0x02);/Socket Rx memory size=2kWrite_W5500_SOCK_1Byte(i,Sn_TXBUF_SIZE, 0x02);/Socket Tx mempry size=2k/设置重试时间,默认为2000(200ms) /每一单位数值为100微秒,初始化时值设为2000(0x07D0),等于200毫秒Write_W5500_2Byte(RTR, 0x07d0);/设置重试次数,默认为8次 /如果重发的次数超过设定值,则产生超时中断(相关的端口中断寄存器中的Sn_IR 超时位(TIMEOUT)置“1”)Write_W5500_1Byte(RCR,8);/启动中断,参考W5500数据手册确定自己需要的中断类型/IMR_CONFLICT是IP地址冲突异常中断,IMR_UNREACH是UDP通信时,地址无法到达的异常中断/其它是Socket事件中断,根据需要添加Write_W5500_1Byte(IMR,IM_IR7 | IM_IR6);Write_W5500_1Byte(SIMR,S0_IMR);Write_W5500_SOCK_1Byte(0, Sn_IMR, IMR_SENDOK | IMR_TIMEOUT | IMR_RECV | IMR_DISCON | IMR_CON);/* 函数名 : Detect_Gateway* 描述 : 检查网关服务器* 输入 : 无* 输出 : 无* 返回值 : 成功返回TRUE(0xFF),失败返回FALSE(0x00)* 说明 : 无*/u8 Detect_Gateway(void)u8 ip_adde4;ip_adde0=IP_Addr0+1;ip_adde1=IP_Addr1+1;ip_adde2=IP_Addr2+1;ip_adde3=IP_Addr3+1;/检查网关及获取网关的物理地址Write_W5500_SOCK_4Byte(0,Sn_DIPR,ip_adde);/向目的地址寄存器写入与本机IP不同的IP值Write_W5500_SOCK_1Byte(0,Sn_MR,MR_TCP);/设置socket为TCP模式Write_W5500_SOCK_1Byte(0,Sn_CR,OPEN);/打开Socketdelay_ms(5);/延时5ms if(Read_W5500_SOCK_1Byte(0,Sn_SR) != SOCK_INIT)/如果socket打开失败Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);/打开不成功,关闭Socketreturn FALSE;/返回FALSE(0x00)Write_W5500_SOCK_1Byte(0,Sn_CR,CONNECT);/设置Socket为Connect模式dou8 j=0;j=Read_W5500_SOCK_1Byte(0,Sn_IR);/读取Socket0中断标志寄存器if(j!=0)Write_W5500_SOCK_1Byte(0,Sn_IR,j);delay_ms(5);/延时5ms if(j&IR_TIMEOUT) = IR_TIMEOUT)return FALSE;else if(Read_W5500_SOCK_1Byte(0,Sn_DHAR) != 0xff)Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);/关闭Socketreturn TRUE;while(1);/* 函数名 : Socket_Init* 描述 : 指定Socket(07)初始化* 输入 : s:待初始化的端口* 输出 : 无* 返回值 : 无* 说明 : 无*/void Socket_Init(SOCKET s)/设置分片长度,参考W5500数据手册,该值可以不修改Write_W5500_SOCK_2Byte(0, Sn_MSSR, 1460);/最大分片字节数=1460(0x5b4)/设置指定端口switch(s)case 0:/设置端口0的端口号Write_W5500_SOCK_2Byte(0, Sn_PORT, S0_Port0*256+S0_Port1);break;case 1:break;case 2:break;case 3:break;case 4:break;case 5:break;case 6:break;case 7:break;default:break;/* 函数名 : Socket_Connect* 描述 : 设置指定Socket(07)为客户端与远程服务器连接* 输入 : s:待设定的端口* 输出 : 无* 返回值 : 成功返回TRUE(0xFF),失败返回FALSE(0x00)* 说明 : 当本机Socket工作在客户端模式时,引用该程序,与远程服务器建立连接*如果启动连接后出现超时中断,则与服务器连接失败,需要重新调用该程序连接*该程序每调用一次,就与服务器产生一次连接*/unsigned char Socket_Connect(SOCKET s)Write_W5500_SOCK_1Byte(s,Sn_MR,MR_TCP);/设置socket为TCP模式Write_W5500_SOCK_1Byte(s,Sn_CR,OPEN);/打开Socketdelay_ms(5);/延时5msif(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_INIT)/如果socket打开失败Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);/打开不成功,关闭Socketreturn FALSE;/返回FALSE(0x00)Write_W5500_SOCK_1Byte(s,Sn_CR,CONNECT);/设置Socket为Connect模式return TRUE;/返回TRUE,设置成功/* 函数名 : Socket_Listen* 描述 : 设置指定Socket(07)作为服务器等待远程主机的连接* 输入 : s:待设定的端口* 输出 : 无* 返回值 : 成功返回TRUE(0xFF),失败返回FALSE(0x00)* 说明 : 当本机Socket工作在服务器模式时,引用该程序,等等远程主机的连接*该程序只调用一次,就使W5500设置为服务器模式*/unsigned char Socket_Listen(SOCKET s)Write_W5500_SOCK_1Byte(s,Sn_MR,MR_TCP);/设置socket为TCP模式 Write_W5500_SOCK_1Byte(s,Sn_CR,OPEN);/打开Socketdelay_ms(5);/延时5msif(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_INIT)/如果socket打开失败Write_W5500_SOCK_1Byte(s,Sn_CR,

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论