[MM32生态] W5500服务端模式例程

[复制链接]
1531|2
 楼主| janewood 发表于 2023-11-19 10:22 | 显示全部楼层 |阅读模式


  1. #include "W5500.h"                                
  2. #include <string.h>

  3. void Delay(unsigned int d);                        //延时函数(ms)

  4. /*******************************************************************************
  5. * 函数名  : W5500_Initialization
  6. * 描述    : W5500初始货配置
  7. * 输入    : 无
  8. * 输出    : 无
  9. * 返回值  : 无
  10. * 说明    : 无
  11. *******************************************************************************/
  12. void W5500_Initialization(void)
  13. {
  14.         W5500_Init();                //初始化W5500寄存器函数
  15.         Detect_Gateway();        //检查网关服务器
  16.         Socket_Init(0);                //指定Socket(0~7)初始化,初始化端口0
  17. }

  18. /*******************************************************************************
  19. * 函数名  : Load_Net_Parameters
  20. * 描述    : 装载网络参数
  21. * 输入    : 无
  22. * 输出    : 无
  23. * 返回值  : 无
  24. * 说明    : 网关、掩码、物理地址、本机IP地址、端口号、目的IP地址、目的端口号、端口工作模式
  25. *******************************************************************************/
  26. void Load_Net_Parameters(void)
  27. {
  28.         Gateway_IP[0] = 192;//加载网关参数
  29.         Gateway_IP[1] = 168;
  30.         Gateway_IP[2] = 1;
  31.         Gateway_IP[3] = 1;

  32.         Sub_Mask[0]=255;//加载子网掩码
  33.         Sub_Mask[1]=255;
  34.         Sub_Mask[2]=255;
  35.         Sub_Mask[3]=0;

  36.         Phy_Addr[0]=0x0c;//加载物理地址
  37.         Phy_Addr[1]=0x29;
  38.         Phy_Addr[2]=0xab;
  39.         Phy_Addr[3]=0x7c;
  40.         Phy_Addr[4]=0x00;
  41.         Phy_Addr[5]=0x01;

  42.         IP_Addr[0]=192;//加载本机IP地址
  43.         IP_Addr[1]=168;
  44.         IP_Addr[2]=1;
  45.         IP_Addr[3]=199;

  46.         S0_Port[0] = 0x13;//加载端口0的端口号5000
  47.         S0_Port[1] = 0x88;

  48. //        S0_DIP[0]=192;//加载端口0的目的IP地址
  49. //        S0_DIP[1]=168;
  50. //        S0_DIP[2]=1;
  51. //        S0_DIP[3]=190;
  52. //        
  53. //        S0_DPort[0] = 0x17;//加载端口0的目的端口号6000
  54. //        S0_DPort[1] = 0x70;

  55.         S0_Mode=TCP_SERVER;//加载端口0的工作模式,TCP服务端模式
  56. }

  57. /*******************************************************************************
  58. * 函数名  : W5500_Socket_Set
  59. * 描述    : W5500端口初始化配置
  60. * 输入    : 无
  61. * 输出    : 无
  62. * 返回值  : 无
  63. * 说明    : 分别设置4个端口,根据端口工作模式,将端口置于TCP服务器、TCP客户端或UDP模式.
  64. *                        从端口状态字节Socket_State可以判断端口的工作情况
  65. *******************************************************************************/
  66. void W5500_Socket_Set(void)
  67. {
  68.         if(S0_State==0)//端口0初始化配置
  69.         {
  70.                 if(S0_Mode==TCP_SERVER)//TCP服务器模式
  71.                 {
  72.                         if(Socket_Listen(0)==TRUE)
  73.                                 S0_State=S_INIT;
  74.                         else
  75.                                 S0_State=0;
  76.                 }
  77.                 else if(S0_Mode==TCP_CLIENT)//TCP客户端模式
  78.                 {
  79.                         if(Socket_Connect(0)==TRUE)
  80.                                 S0_State=S_INIT;
  81.                         else
  82.                                 S0_State=0;
  83.                 }
  84.                 else//UDP模式
  85.                 {
  86.                         if(Socket_UDP(0)==TRUE)
  87.                                 S0_State=S_INIT|S_CONN;
  88.                         else
  89.                                 S0_State=0;
  90.                 }
  91.         }
  92. }

  93. /*******************************************************************************
  94. * 函数名  : Process_Socket_Data
  95. * 描述    : W5500接收并发送接收到的数据
  96. * 输入    : s:端口号
  97. * 输出    : 无
  98. * 返回值  : 无
  99. * 说明    : 本过程先调用S_rx_process()从W5500的端口接收数据缓冲区读取数据,
  100. *                        然后将读取的数据从Rx_Buffer拷贝到Temp_Buffer缓冲区进行处理。
  101. *                        处理完毕,将数据从Temp_Buffer拷贝到Tx_Buffer缓冲区。调用S_tx_process()
  102. *                        发送数据。
  103. *******************************************************************************/
  104. void Process_Socket_Data(SOCKET s)
  105. {
  106.         unsigned short size;
  107.         size=Read_SOCK_Data_Buffer(s, Rx_Buffer);
  108.         memcpy(Tx_Buffer, Rx_Buffer, size);                        
  109.         Write_SOCK_Data_Buffer(s, Tx_Buffer, size);
  110. }

  111. /*******************************************************************************
  112. * 函数名  : main
  113. * 描述    : 主函数,用户程序从main函数开始运行
  114. * 输入    : 无
  115. * 输出    : 无
  116. * 返回值  : int:返回值为一个16位整形数
  117. * 说明    : 无
  118. *******************************************************************************/
  119. int main(void)
  120. {
  121.         unsigned int W5500_Send_Delay_Counter =0;

  122.         Load_Net_Parameters();                //装载网络参数        
  123.         W5500_Hardware_Reset();                //硬件复位W5500
  124.         W5500_Initialization();                //W5500初始货配置
  125.         while (1)
  126.         {
  127.                 W5500_Socket_Set();//W5500端口初始化配置
  128.                
  129.                 W5500_Interrupt_Process();//W5500中断处理程序框架

  130.                 if((S0_Data & S_RECEIVE) == S_RECEIVE)//如果Socket0接收到数据
  131.                 {
  132.                         S0_Data&=~S_RECEIVE;
  133.                         Process_Socket_Data(0);//W5500接收并发送接收到的数据
  134.                 }
  135.                 else if(W5500_Send_Delay_Counter >= 3000)//定时发送字符串
  136.                 {
  137.                         if(S0_State == (S_INIT|S_CONN))
  138.                         {
  139.                                 S0_Data&=~S_TRANSMITOK;
  140.                                 memcpy(Tx_Buffer, "\r\nWelcome To ChuangWeiElec!\r\n", 27);
  141.                                 Write_SOCK_Data_Buffer(0, Tx_Buffer, 27);//指定Socket(0~7)发送数据处理,端口0发送27字节数据
  142.                         }
  143.                         W5500_Send_Delay_Counter=0;
  144.                 }
  145.                 W5500_Send_Delay_Counter++;
  146.         }
  147. }

  148. /*******************************************************************************
  149. * 函数名  : Delay
  150. * 描述    : 延时函数(ms)
  151. * 输入    : d:延时系数,单位为毫秒
  152. * 输出    : 无
  153. * 返回    : 无
  154. * 说明    : 延时是利用Timer2定时器产生的1毫秒的计数来实现的
  155. *******************************************************************************/
  156. void Delay(unsigned int  x)
  157. {
  158.     unsigned int i,j;

  159.     for(j=0;j<5;j++)
  160.                 for(i=0;i<x;i++);
  161. }
  162. 复制代码
  163. /**********************************************************************************
  164. * 文件名  :W5500.c
  165. * 描述    :W5500 驱动函数库         
  166. * 库版本  :ST_v3.5
  167. **********************************************************************************/
  168.                
  169. #include "W5500.h"        

  170. /***************----- 网络参数变量定义 -----***************/
  171. unsigned char Gateway_IP[4];//网关IP地址
  172. unsigned char Sub_Mask[4];        //子网掩码
  173. unsigned char Phy_Addr[6];        //物理地址(MAC)
  174. unsigned char IP_Addr[4];        //本机IP地址

  175. unsigned char S0_Port[2];        //端口0的端口号
  176. unsigned char S0_DIP[4];        //端口0目的IP地址
  177. unsigned char S0_DPort[2];        //端口0目的端口号

  178. unsigned char UDP_DIPR[4];        //UDP(广播)模式,目的主机IP地址
  179. unsigned char UDP_DPORT[2];        //UDP(广播)模式,目的主机端口号

  180. /***************----- 端口的运行模式 -----***************/
  181. unsigned char S0_Mode =3;        //端口0的运行模式,0:TCP服务器模式,1:TCP客户端模式,2:UDP(广播)模式

  182. #define TCP_SERVER        0x00        //TCP服务器模式
  183. #define TCP_CLIENT        0x01        //TCP客户端模式
  184. #define UDP_MODE        0x02        //UDP(广播)模式

  185. /***************----- 端口的运行状态 -----***************/
  186. unsigned char S0_State =0;        //端口0状态记录,1:端口完成初始化,2端口完成连接(可以正常传输数据)
  187. #define S_INIT                0x01        //端口完成初始化
  188. #define S_CONN                0x02        //端口完成连接,可以正常传输数据

  189. /***************----- 端口收发数据的状态 -----***************/
  190. unsigned char S0_Data;                //端口0接收和发送数据的状态,1:端口接收到数据,2:端口发送数据完成
  191. #define S_RECEIVE         0x01        //端口接收到一个数据包
  192. #define S_TRANSMITOK 0x02        //端口发送一个数据包完成

  193. /***************----- 端口数据缓冲区 -----***************/
  194. unsigned char Rx_Buffer[30];        //端口接收数据缓冲区
  195. unsigned char Tx_Buffer[30];        //端口发送数据缓冲区

  196. unsigned char W5500_Interrupt;        //W5500中断标志(0:无中断,1:有中断)

  197. /*******************************************************************************
  198. * 函数名  : SPI_ReadByte
  199. * 描述    : 读取一个字节SPI返回的数据
  200. * 输入    : 无
  201. * 输出    : 无
  202. * 返回值  : 读取到的寄存器数据
  203. * 说明    : 无
  204. *******************************************************************************/
  205. unsigned char SPI_Read_Byte(void)
  206. {
  207.         unsigned char i,rByte=0;
  208.         
  209.         W5500_SCLK=0;
  210.         for(i=0;i<8;i++)
  211.         {
  212.                 W5500_SCLK=1;
  213.                 rByte<<=1;
  214.                 rByte|=W5500_MISO;
  215.                 W5500_SCLK=0;        
  216.         }
  217.         return rByte;
  218. }


  219. /*******************************************************************************
  220. * 函数名  : Read_SOCK_Data_Buffer
  221. * 描述    : 从W5500接收数据缓冲区中读取数据
  222. * 输入    : s:端口号,*dat_ptr:数据保存缓冲区指针
  223. * 输出    : 无
  224. * 返回值  : 读取到的数据长度,rx_size个字节
  225. * 说明    : 无
  226. *******************************************************************************/
  227. unsigned short Read_SOCK_Data_Buffer(SOCKET s, unsigned char *dat_ptr)
  228. {
  229.         unsigned short rx_size;
  230.         unsigned short offset, offset1;
  231.         unsigned short i;
  232.         unsigned char j;

  233.         rx_size=Read_W5500_SOCK_2Byte(s,Sn_RX_RSR);
  234.         if(rx_size==0) return 0;//没接收到数据则返回
  235.         if(rx_size>1460) rx_size=1460;

  236.         offset=Read_W5500_SOCK_2Byte(s,Sn_RX_RD);
  237.         offset1=offset;
  238.         offset&=(S_RX_SIZE-1);//计算实际的物理地址

  239.         W5500_SCS=0;//置W5500的SCS为低电平

  240.         SPI_Send_Short(offset);//写16位地址
  241.         SPI_Send_Byte(VDM|RWB_READ|(s*0x20+0x18));//写控制字节,N个字节数据长度,读数据,选择端口s的寄存器
  242.         
  243.         if((offset+rx_size)<S_RX_SIZE)//如果最大地址未超过W5500接收缓冲区寄存器的最大地址
  244.         {
  245.                 for(i=0;i<rx_size;i++)//循环读取rx_size个字节数据
  246.                 {
  247.                         j=SPI_Read_Byte();//读取1个字节数据
  248.                         *dat_ptr=j;//将读取到的数据保存到数据保存缓冲区
  249.                         dat_ptr++;//数据保存缓冲区指针地址自增1
  250.                 }
  251.         }
  252.         else//如果最大地址超过W5500接收缓冲区寄存器的最大地址
  253.         {
  254.                 offset=S_RX_SIZE-offset;
  255.                 for(i=0;i<offset;i++)//循环读取出前offset个字节数据
  256.                 {
  257.                         j=SPI_Read_Byte();//读取1个字节数据
  258.                         *dat_ptr=j;//将读取到的数据保存到数据保存缓冲区
  259.                         dat_ptr++;//数据保存缓冲区指针地址自增1
  260.                 }
  261.                 W5500_SCS=1; //置W5500的SCS为高电平

  262.                 W5500_SCS=0;//置W5500的SCS为低电平

  263.                 SPI_Send_Short(0x00);//写16位地址
  264.                 SPI_Send_Byte(VDM|RWB_READ|(s*0x20+0x18));//写控制字节,N个字节数据长度,读数据,选择端口s的寄存器

  265.                 for(;i<rx_size;i++)//循环读取后rx_size-offset个字节数据
  266.                 {
  267.                         j=SPI_Read_Byte();//读取1个字节数据
  268.                         *dat_ptr=j;//将读取到的数据保存到数据保存缓冲区
  269.                         dat_ptr++;//数据保存缓冲区指针地址自增1
  270.                 }
  271.         }
  272.         W5500_SCS=1; //置W5500的SCS为高电平

  273.         offset1+=rx_size;//更新实际物理地址,即下次读取接收到的数据的起始地址
  274.         Write_W5500_SOCK_2Byte(s, Sn_RX_RD, offset1);
  275.         Write_W5500_SOCK_1Byte(s, Sn_CR, RECV);//发送启动接收命令
  276.         return rx_size;//返回接收到数据的长度
  277. }

  278. /*******************************************************************************
  279. * 函数名  : Write_SOCK_Data_Buffer
  280. * 描述    : 将数据写入W5500的数据发送缓冲区
  281. * 输入    : s:端口号,*dat_ptr:数据保存缓冲区指针,size:待写入数据的长度
  282. * 输出    : 无
  283. * 返回值  : 无
  284. * 说明    : 无
  285. *******************************************************************************/
  286. void Write_SOCK_Data_Buffer(SOCKET s, unsigned char *dat_ptr, unsigned short size)
  287. {
  288.         unsigned short offset,offset1;
  289.         unsigned short i;

  290.         //如果是UDP模式,可以在此设置目的主机的IP和端口号
  291.         if((Read_W5500_SOCK_1Byte(s,Sn_MR)&0x0f) != SOCK_UDP)//如果Socket打开失败
  292.         {               
  293.                 Write_W5500_SOCK_4Byte(s, Sn_DIPR, UDP_DIPR);//设置目的主机IP                  
  294.                 Write_W5500_SOCK_2Byte(s, Sn_DPORTR, UDP_DPORT[0]*256+UDP_DPORT[1]);//设置目的主机端口号                                
  295.         }

  296.         offset=Read_W5500_SOCK_2Byte(s,Sn_TX_WR);
  297.         offset1=offset;
  298.         offset&=(S_TX_SIZE-1);//计算实际的物理地址

  299.         W5500_SCS=0;//置W5500的SCS为低电平

  300.         SPI_Send_Short(offset);//写16位地址
  301.         SPI_Send_Byte(VDM|RWB_WRITE|(s*0x20+0x10));//写控制字节,N个字节数据长度,写数据,选择端口s的寄存器

  302.         if((offset+size)<S_TX_SIZE)//如果最大地址未超过W5500发送缓冲区寄存器的最大地址
  303.         {
  304.                 for(i=0;i<size;i++)//循环写入size个字节数据
  305.                 {
  306.                         SPI_Send_Byte(*dat_ptr++);//写入一个字节的数据               
  307.                 }
  308.         }
  309.         else//如果最大地址超过W5500发送缓冲区寄存器的最大地址
  310.         {
  311.                 offset=S_TX_SIZE-offset;
  312.                 for(i=0;i<offset;i++)//循环写入前offset个字节数据
  313.                 {
  314.                         SPI_Send_Byte(*dat_ptr++);//写入一个字节的数据
  315.                 }
  316.                 W5500_SCS=1; //置W5500的SCS为高电平

  317.                 W5500_SCS=0;//置W5500的SCS为低电平

  318.                 SPI_Send_Short(0x00);//写16位地址
  319.                 SPI_Send_Byte(VDM|RWB_WRITE|(s*0x20+0x10));//写控制字节,N个字节数据长度,写数据,选择端口s的寄存器

  320.                 for(;i<size;i++)//循环写入size-offset个字节数据
  321.                 {
  322.                         SPI_Send_Byte(*dat_ptr++);//写入一个字节的数据
  323.                 }
  324.         }
  325.         W5500_SCS=1; //置W5500的SCS为高电平

  326.         offset1+=size;//更新实际物理地址,即下次写待发送数据到发送数据缓冲区的起始地址
  327.         Write_W5500_SOCK_2Byte(s, Sn_TX_WR, offset1);
  328.         Write_W5500_SOCK_1Byte(s, Sn_CR, SEND);//发送启动发送命令                                
  329. }

  330. /*******************************************************************************
  331. * 函数名  : W5500_Hardware_Reset
  332. * 描述    : 硬件复位W5500
  333. * 输入    : 无
  334. * 输出    : 无
  335. * 返回值  : 无
  336. * 说明    : W5500的复位引脚保持低电平至少500us以上,才能重围W5500
  337. *******************************************************************************/
  338. void W5500_Hardware_Reset(void)
  339. {
  340.         W5500_RST=0;//复位引脚拉低
  341.         Delay(200);
  342.         W5500_RST=1;//复位引脚拉高
  343.         Delay(200);
  344.         while((Read_W5500_1Byte(PHYCFGR)&LINK)==0);//等待以太网连接完成
  345. }

  346. /*******************************************************************************
  347. * 函数名  : W5500_Init
  348. * 描述    : 初始化W5500寄存器函数
  349. * 输入    : 无
  350. * 输出    : 无
  351. * 返回值  : 无
  352. * 说明    : 在使用W5500之前,先对W5500初始化
  353. *******************************************************************************/
  354. void W5500_Init(void)
  355. {
  356.         unsigned char i=0;

  357.         Write_W5500_1Byte(MR, RST);//软件复位W5500,置1有效,复位后自动清0
  358.         Delay(10);//延时10ms,自己定义该函数

  359.         //设置网关(Gateway)的IP地址,Gateway_IP为4字节unsigned char数组,自己定义
  360.         //使用网关可以使通信突破子网的局限,通过网关可以访问到其它子网或进入Internet
  361.         Write_W5500_nByte(GAR, Gateway_IP, 4);
  362.                         
  363.         //设置子网掩码(MASK)值,SUB_MASK为4字节unsigned char数组,自己定义
  364.         //子网掩码用于子网运算
  365.         Write_W5500_nByte(SUBR,Sub_Mask,4);               
  366.         
  367.         //设置物理地址,PHY_ADDR为6字节unsigned char数组,自己定义,用于唯一标识网络设备的物理地址值
  368.         //该地址值需要到IEEE申请,按照OUI的规定,前3个字节为厂商代码,后三个字节为产品序号
  369.         //如果自己定义物理地址,注意第一个字节必须为偶数
  370.         Write_W5500_nByte(SHAR,Phy_Addr,6);               

  371.         //设置本机的IP地址,IP_ADDR为4字节unsigned char数组,自己定义
  372.         //注意,网关IP必须与本机IP属于同一个子网,否则本机将无法找到网关
  373.         Write_W5500_nByte(SIPR,IP_Addr,4);               
  374.         
  375.         //设置发送缓冲区和接收缓冲区的大小,参考W5500数据手册
  376.         for(i=0;i<8;i++)
  377.         {
  378.                 Write_W5500_SOCK_1Byte(i,Sn_RXBUF_SIZE, 0x02);//Socket Rx memory size=2k
  379.                 Write_W5500_SOCK_1Byte(i,Sn_TXBUF_SIZE, 0x02);//Socket Tx mempry size=2k
  380.         }

  381.         //设置重试时间,默认为2000(200ms)
  382.         //每一单位数值为100微秒,初始化时值设为2000(0x07D0),等于200毫秒
  383.         Write_W5500_2Byte(RTR, 0x07d0);

  384.         //设置重试次数,默认为8次
  385.         //如果重发的次数超过设定值,则产生超时中断(相关的端口中断寄存器中的Sn_IR 超时位(TIMEOUT)置“1”)
  386.         Write_W5500_1Byte(RCR,8);
  387. }

  388. /*******************************************************************************
  389. * 函数名  : Detect_Gateway
  390. * 描述    : 检查网关服务器
  391. * 输入    : 无
  392. * 输出    : 无
  393. * 返回值  : 成功返回TRUE(0xFF),失败返回FALSE(0x00)
  394. * 说明    : 无
  395. *******************************************************************************/
  396. unsigned char Detect_Gateway(void)
  397. {
  398.         unsigned char ip_adde[4];
  399.         ip_adde[0]=IP_Addr[0]+1;
  400.         ip_adde[1]=IP_Addr[1]+1;
  401.         ip_adde[2]=IP_Addr[2]+1;
  402.         ip_adde[3]=IP_Addr[3]+1;

  403.         //检查网关及获取网关的物理地址
  404.         Write_W5500_SOCK_4Byte(0,Sn_DIPR,ip_adde);//向目的地址寄存器写入与本机IP不同的IP值
  405.         Write_W5500_SOCK_1Byte(0,Sn_MR,MR_TCP);//设置socket为TCP模式
  406.         Write_W5500_SOCK_1Byte(0,Sn_CR,OPEN);//打开Socket        
  407.         Delay(5);//延时5ms         
  408.         
  409.         if(Read_W5500_SOCK_1Byte(0,Sn_SR) != SOCK_INIT)//如果socket打开失败
  410.         {
  411.                 Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);//打开不成功,关闭Socket
  412.                 return FALSE;//返回FALSE(0x00)
  413.         }

  414.         Write_W5500_SOCK_1Byte(0,Sn_CR,CONNECT);//设置Socket为Connect模式                                                

  415.         do
  416.         {
  417.                 unsigned char j=0;
  418.                 j=Read_W5500_SOCK_1Byte(0,Sn_IR);//读取Socket0中断标志寄存器
  419.                 if(j!=0)
  420.                 Write_W5500_SOCK_1Byte(0,Sn_IR,j);
  421.                 Delay(5);//延时5ms
  422.                 if((j&IR_TIMEOUT) == IR_TIMEOUT)
  423.                 {
  424.                         return FALSE;        
  425.                 }
  426.                 else if(Read_W5500_SOCK_1Byte(0,Sn_DHAR) != 0xff)
  427.                 {
  428.                         Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);//关闭Socket
  429.                         return TRUE;                                                        
  430.                 }
  431.         }while(1);
  432. }

  433. /*******************************************************************************
  434. * 函数名  : Socket_Init
  435. * 描述    : 指定Socket(0~7)初始化
  436. * 输入    : s:待初始化的端口
  437. * 输出    : 无
  438. * 返回值  : 无
  439. * 说明    : 无
  440. *******************************************************************************/
  441. void Socket_Init(SOCKET s)
  442. {
  443.         //设置分片长度,参考W5500数据手册,该值可以不修改        
  444.         Write_W5500_SOCK_2Byte(0, Sn_MSSR, 30);//最大分片字节数=30(0x001e)
  445.         //设置指定端口
  446.         switch(s)
  447.         {
  448.                 case 0:
  449.                         //设置端口0的端口号
  450.                         Write_W5500_SOCK_2Byte(0, Sn_PORT, S0_Port[0]*256+S0_Port[1]);        
  451.                         
  452.                         break;

  453.                 case 1:
  454.                         break;

  455.                 case 2:
  456.                         break;

  457.                 case 3:
  458.                         break;

  459.                 case 4:
  460.                         break;

  461.                 case 5:
  462.                         break;

  463.                 case 6:
  464.                         break;

  465.                 case 7:
  466.                         break;

  467.                 default:
  468.                         break;
  469.         }
  470. }

  471. /*******************************************************************************
  472. * 函数名  : Socket_Connect
  473. * 描述    : 设置指定Socket(0~7)为客户端与远程服务器连接
  474. * 输入    : s:待设定的端口
  475. * 输出    : 无
  476. * 返回值  : 成功返回TRUE(0xFF),失败返回FALSE(0x00)
  477. * 说明    : 当本机Socket工作在客户端模式时,引用该程序,与远程服务器建立连接
  478. *                        如果启动连接后出现超时中断,则与服务器连接失败,需要重新调用该程序连接
  479. *                        该程序每调用一次,就与服务器产生一次连接
  480. *******************************************************************************/
  481. unsigned char Socket_Connect(SOCKET s)
  482. {
  483.         Write_W5500_SOCK_1Byte(s,Sn_MR,MR_TCP);//设置socket为TCP模式
  484.         Write_W5500_SOCK_1Byte(s,Sn_CR,OPEN);//打开Socket
  485.         Delay(5);//延时5ms
  486.         if(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_INIT)//如果socket打开失败
  487.         {
  488.                 Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);//打开不成功,关闭Socket
  489.                 return FALSE;//返回FALSE(0x00)
  490.         }
  491.         Write_W5500_SOCK_1Byte(s,Sn_CR,CONNECT);//设置Socket为Connect模式
  492.         return TRUE;//返回TRUE,设置成功
  493. }

  494. /*******************************************************************************
  495. * 函数名  : Socket_Listen
  496. * 描述    : 设置指定Socket(0~7)作为服务器等待远程主机的连接
  497. * 输入    : s:待设定的端口
  498. * 输出    : 无
  499. * 返回值  : 成功返回TRUE(0xFF),失败返回FALSE(0x00)
  500. * 说明    : 当本机Socket工作在服务器模式时,引用该程序,等等远程主机的连接
  501. *                        该程序只调用一次,就使W5500设置为服务器模式
  502. *******************************************************************************/
  503. unsigned char Socket_Listen(SOCKET s)
  504. {
  505.         Write_W5500_SOCK_1Byte(s,Sn_MR,MR_TCP);//设置socket为TCP模式
  506.         Write_W5500_SOCK_1Byte(s,Sn_CR,OPEN);//打开Socket        
  507.         Delay(5);//延时5ms
  508.         if(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_INIT)//如果socket打开失败
  509.         {
  510.                 Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);//打开不成功,关闭Socket
  511.                 return FALSE;//返回FALSE(0x00)
  512.         }        
  513.         Write_W5500_SOCK_1Byte(s,Sn_CR,LISTEN);//设置Socket为侦听模式        
  514.         Delay(5);//延时5ms
  515.         if(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_LISTEN)//如果socket设置失败
  516.         {
  517.                 Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);//设置不成功,关闭Socket
  518.                 return FALSE;//返回FALSE(0x00)
  519.         }

  520.         return TRUE;

  521.         //至此完成了Socket的打开和设置侦听工作,至于远程客户端是否与它建立连接,则需要等待Socket中断,
  522.         //以判断Socket的连接是否成功。参考W5500数据手册的Socket中断状态
  523.         //在服务器侦听模式不需要设置目的IP和目的端口号
  524. }

  525. /*******************************************************************************
  526. * 函数名  : Socket_UDP
  527. * 描述    : 设置指定Socket(0~7)为UDP模式
  528. * 输入    : s:待设定的端口
  529. * 输出    : 无
  530. * 返回值  : 成功返回TRUE(0xFF),失败返回FALSE(0x00)
  531. * 说明    : 如果Socket工作在UDP模式,引用该程序,在UDP模式下,Socket通信不需要建立连接
  532. *                        该程序只调用一次,就使W5500设置为UDP模式
  533. *******************************************************************************/
  534. unsigned char Socket_UDP(SOCKET s)
  535. {
  536.         Write_W5500_SOCK_1Byte(s,Sn_MR,MR_UDP);//设置Socket为UDP模式*/
  537.         Write_W5500_SOCK_1Byte(s,Sn_CR,OPEN);//打开Socket*/
  538.         Delay(5);//延时5ms
  539.         if(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_UDP)//如果Socket打开失败
  540.         {
  541.                 Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);//打开不成功,关闭Socket
  542.                 return FALSE;//返回FALSE(0x00)
  543.         }
  544.         else
  545.                 return TRUE;

  546.         //至此完成了Socket的打开和UDP模式设置,在这种模式下它不需要与远程主机建立连接
  547.         //因为Socket不需要建立连接,所以在发送数据前都可以设置目的主机IP和目的Socket的端口号
  548.         //如果目的主机IP和目的Socket的端口号是固定的,在运行过程中没有改变,那么也可以在这里设置
  549. }

  550. /*******************************************************************************
  551. * 函数名  : W5500_Interrupt_Process
  552. * 描述    : W5500中断处理程序框架
  553. * 输入    : 无
  554. * 输出    : 无
  555. * 返回值  : 无
  556. * 说明    : 无
  557. *******************************************************************************/
  558. void W5500_Interrupt_Process(void)
  559. {
  560.         unsigned char i,j;

  561. IntDispose:

  562.         i=Read_W5500_1Byte(SIR);//读取端口中断标志寄存器        
  563.         if((i & S0_INT) == S0_INT)//Socket0事件处理
  564.         {
  565.                 j=Read_W5500_SOCK_1Byte(0,Sn_IR);//读取Socket0中断标志寄存器
  566.                 Write_W5500_SOCK_1Byte(0,Sn_IR,j);
  567.                 if(j&IR_CON)//在TCP模式下,Socket0成功连接
  568.                 {
  569.                         S0_State|=S_CONN;//网络连接状态0x02,端口完成连接,可以正常传输数据
  570.                 }
  571.                 if(j&IR_DISCON)//在TCP模式下Socket断开连接处理
  572.                 {
  573.                         Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);//关闭端口,等待重新打开连接
  574.                         Socket_Init(0);                //指定Socket(0~7)初始化,初始化端口0
  575.                         S0_State=0;//网络连接状态0x00,端口连接失败
  576.                 }
  577.                 if(j&IR_SEND_OK)//Socket0数据发送完成,可以再次启动S_tx_process()函数发送数据
  578.                 {
  579.                         S0_Data|=S_TRANSMITOK;//端口发送一个数据包完成
  580.                 }
  581.                 if(j&IR_RECV)//Socket接收到数据,可以启动S_rx_process()函数
  582.                 {
  583.                         S0_Data|=S_RECEIVE;//端口接收到一个数据包
  584.                 }
  585.                 if(j&IR_TIMEOUT)//Socket连接或数据传输超时处理
  586.                 {
  587.                         Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);// 关闭端口,等待重新打开连接                        
  588.                         S0_State=0;//网络连接状态0x00,端口连接失败
  589.                 }
  590.         }

  591.         if(Read_W5500_1Byte(SIR) != 0)
  592.                 goto IntDispose;
  593. }


daichaodai 发表于 2023-11-20 09:04 来自手机 | 显示全部楼层
W5500是啥?通信模块?

评论

微知纳特的以太网芯片  发表于 2023-11-21 09:55
您需要登录后才可以回帖 登录 | 注册

本版积分规则

61

主题

1548

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部