找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 5816|回復(fù): 9
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)W5500服務(wù)端模式例程(TCP/IP)Keil源程序

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
單片機(jī)源程序如下:
  1. /***************************************************************************************
  2. * 工程名  :W5500模塊-服務(wù)端模式例程
  3. * 描述    :W5500的端口0工作在服務(wù)端模式,則等待《TCP&UDP測(cè)試工具》上創(chuàng)建的客戶端主動(dòng)與服務(wù)端連接,
  4. *                         連接成功后,服務(wù)端定時(shí)給客戶端發(fā)送字符串"\r\nWelcome To ChuangWeiElec!\r\n",
  5. *                         同時(shí)將接收到客戶端發(fā)來的數(shù)據(jù)回發(fā)給客戶端。
  6. * 實(shí)驗(yàn)平臺(tái):51單片機(jī)開發(fā)板+ W5500以太網(wǎng)(TCP/IP)模塊
  7. * 硬件連接:  P3^2 -> W5500_RST   
  8. *             P3^3 -> W5500_INT(本例程沒有用到中斷,此引腳可以不接)     
  9. *             P3^6 -> W5500_SCS      
  10. *             P3^7 -> W5500_SCK   
  11. *             P3^4 -> W5500_MISO   
  12. *             P3^5 -> W5500_MOSI   
  13. * 庫版本  :ST_v3.5
  14. ***************************************************************************************/

  15. /*例程網(wǎng)絡(luò)參數(shù)*/
  16. //網(wǎng)關(guān):192.168.1.1
  17. //掩碼:        255.255.255.0
  18. //物理地址:0C 29 AB 7C 00 01
  19. //本機(jī)IP地址:192.168.1.199
  20. //端口0的端口號(hào):5000
  21. //端口0的目的IP地址:192.168.1.190
  22. //端口0的目的端口號(hào):6000

  23. #include <reg51.h>
  24. #include "W5500.h"                                
  25. #include <string.h>

  26. void Delay(unsigned int d);                        //延時(shí)函數(shù)(ms)

  27. /*******************************************************************************
  28. * 函數(shù)名  : W5500_Initialization
  29. * 描述    : W5500初始貨配置
  30. * 輸入    : 無
  31. * 輸出    : 無
  32. * 返回值  : 無
  33. * 說明    : 無
  34. *******************************************************************************/
  35. void W5500_Initialization(void)
  36. {
  37.         W5500_Init();                //初始化W5500寄存器函數(shù)
  38.         Detect_Gateway();        //檢查網(wǎng)關(guān)服務(wù)器
  39.         Socket_Init(0);                //指定Socket(0~7)初始化,初始化端口0
  40. }

  41. /*******************************************************************************
  42. * 函數(shù)名  : Load_Net_Parameters
  43. * 描述    : 裝載網(wǎng)絡(luò)參數(shù)
  44. * 輸入    : 無
  45. * 輸出    : 無
  46. * 返回值  : 無
  47. * 說明    : 網(wǎng)關(guān)、掩碼、物理地址、本機(jī)IP地址、端口號(hào)、目的IP地址、目的端口號(hào)、端口工作模式
  48. *******************************************************************************/
  49. void Load_Net_Parameters(void)
  50. {
  51.         Gateway_IP[0] = 192;//加載網(wǎng)關(guān)參數(shù)
  52.         Gateway_IP[1] = 168;
  53.         Gateway_IP[2] = 1;
  54.         Gateway_IP[3] = 1;

  55.         Sub_Mask[0]=255;//加載子網(wǎng)掩碼
  56.         Sub_Mask[1]=255;
  57.         Sub_Mask[2]=255;
  58.         Sub_Mask[3]=0;

  59.         Phy_Addr[0]=0x0c;//加載物理地址
  60.         Phy_Addr[1]=0x29;
  61.         Phy_Addr[2]=0xab;
  62.         Phy_Addr[3]=0x7c;
  63.         Phy_Addr[4]=0x00;
  64.         Phy_Addr[5]=0x01;

  65.         IP_Addr[0]=192;//加載本機(jī)IP地址
  66.         IP_Addr[1]=168;
  67.         IP_Addr[2]=1;
  68.         IP_Addr[3]=199;

  69.         S0_Port[0] = 0x13;//加載端口0的端口號(hào)5000
  70.         S0_Port[1] = 0x88;

  71. //        S0_DIP[0]=192;//加載端口0的目的IP地址
  72. //        S0_DIP[1]=168;
  73. //        S0_DIP[2]=1;
  74. //        S0_DIP[3]=190;
  75. //        
  76. //        S0_DPort[0] = 0x17;//加載端口0的目的端口號(hào)6000
  77. //        S0_DPort[1] = 0x70;

  78.         S0_Mode=TCP_SERVER;//加載端口0的工作模式,TCP服務(wù)端模式
  79. }

  80. /*******************************************************************************
  81. * 函數(shù)名  : W5500_Socket_Set
  82. * 描述    : W5500端口初始化配置
  83. * 輸入    : 無
  84. * 輸出    : 無
  85. * 返回值  : 無
  86. * 說明    : 分別設(shè)置4個(gè)端口,根據(jù)端口工作模式,將端口置于TCP服務(wù)器、TCP客戶端或UDP模式.
  87. *                        從端口狀態(tài)字節(jié)Socket_State可以判斷端口的工作情況
  88. *******************************************************************************/
  89. void W5500_Socket_Set(void)
  90. {
  91.         if(S0_State==0)//端口0初始化配置
  92.         {
  93.                 if(S0_Mode==TCP_SERVER)//TCP服務(wù)器模式
  94.                 {
  95.                         if(Socket_Listen(0)==TRUE)
  96.                                 S0_State=S_INIT;
  97.                         else
  98.                                 S0_State=0;
  99.                 }
  100.                 else if(S0_Mode==TCP_CLIENT)//TCP客戶端模式
  101.                 {
  102.                         if(Socket_Connect(0)==TRUE)
  103.                                 S0_State=S_INIT;
  104.                         else
  105.                                 S0_State=0;
  106.                 }
  107.                 else//UDP模式
  108.                 {
  109.                         if(Socket_UDP(0)==TRUE)
  110.                                 S0_State=S_INIT|S_CONN;
  111.                         else
  112.                                 S0_State=0;
  113.                 }
  114.         }
  115. }

  116. /*******************************************************************************
  117. * 函數(shù)名  : Process_Socket_Data
  118. * 描述    : W5500接收并發(fā)送接收到的數(shù)據(jù)
  119. * 輸入    : s:端口號(hào)
  120. * 輸出    : 無
  121. * 返回值  : 無
  122. * 說明    : 本過程先調(diào)用S_rx_process()從W5500的端口接收數(shù)據(jù)緩沖區(qū)讀取數(shù)據(jù),
  123. *                        然后將讀取的數(shù)據(jù)從Rx_Buffer拷貝到Temp_Buffer緩沖區(qū)進(jìn)行處理。
  124. *                        處理完畢,將數(shù)據(jù)從Temp_Buffer拷貝到Tx_Buffer緩沖區(qū)。調(diào)用S_tx_process()
  125. *                        發(fā)送數(shù)據(jù)。
  126. *******************************************************************************/
  127. void Process_Socket_Data(SOCKET s)
  128. {
  129.         unsigned short size;
  130.         size=Read_SOCK_Data_Buffer(s, Rx_Buffer);
  131.         memcpy(Tx_Buffer, Rx_Buffer, size);                        
  132.         Write_SOCK_Data_Buffer(s, Tx_Buffer, size);
  133. }

  134. /*******************************************************************************
  135. * 函數(shù)名  : main
  136. * 描述    : 主函數(shù),用戶程序從main函數(shù)開始運(yùn)行
  137. * 輸入    : 無
  138. * 輸出    : 無
  139. * 返回值  : int:返回值為一個(gè)16位整形數(shù)
  140. * 說明    : 無
  141. *******************************************************************************/
  142. int main(void)
  143. {
  144.         unsigned int W5500_Send_Delay_Counter =0;

  145.         Load_Net_Parameters();                //裝載網(wǎng)絡(luò)參數(shù)        
  146.         W5500_Hardware_Reset();                //硬件復(fù)位W5500
  147.         W5500_Initialization();                //W5500初始貨配置
  148.         while (1)
  149.         {
  150.                 W5500_Socket_Set();//W5500端口初始化配置
  151.                
  152.                 W5500_Interrupt_Process();//W5500中斷處理程序框架

  153.                 if((S0_Data & S_RECEIVE) == S_RECEIVE)//如果Socket0接收到數(shù)據(jù)
  154.                 {
  155.                         S0_Data&=~S_RECEIVE;
  156.                         Process_Socket_Data(0);//W5500接收并發(fā)送接收到的數(shù)據(jù)
  157.                 }
  158.                 else if(W5500_Send_Delay_Counter >= 3000)//定時(shí)發(fā)送字符串
  159.                 {
  160.                         if(S0_State == (S_INIT|S_CONN))
  161.                         {
  162.                                 S0_Data&=~S_TRANSMITOK;
  163.                                 memcpy(Tx_Buffer, "\r\nWelcome To ChuangWeiElec!\r\n", 27);
  164.                                 Write_SOCK_Data_Buffer(0, Tx_Buffer, 27);//指定Socket(0~7)發(fā)送數(shù)據(jù)處理,端口0發(fā)送27字節(jié)數(shù)據(jù)
  165.                         }
  166.                         W5500_Send_Delay_Counter=0;
  167.                 }
  168.                 W5500_Send_Delay_Counter++;
  169.         }
  170. }

  171. /*******************************************************************************
  172. * 函數(shù)名  : Delay
  173. * 描述    : 延時(shí)函數(shù)(ms)
  174. * 輸入    : d:延時(shí)系數(shù),單位為毫秒
  175. * 輸出    : 無
  176. * 返回    : 無
  177. * 說明    : 延時(shí)是利用Timer2定時(shí)器產(chǎn)生的1毫秒的計(jì)數(shù)來實(shí)現(xiàn)的
  178. *******************************************************************************/
  179. void Delay(unsigned int  x)
  180. {
  181.     unsigned int i,j;

  182.     for(j=0;j<5;j++)
  183.                 for(i=0;i<x;i++);
  184. }
復(fù)制代碼
  1. /**********************************************************************************
  2. * 文件名  :W5500.c
  3. * 描述    :W5500 驅(qū)動(dòng)函數(shù)庫         
  4. * 庫版本  :ST_v3.5
  5. **********************************************************************************/
  6.                
  7. #include "W5500.h"        

  8. /***************----- 網(wǎng)絡(luò)參數(shù)變量定義 -----***************/
  9. unsigned char Gateway_IP[4];//網(wǎng)關(guān)IP地址
  10. unsigned char Sub_Mask[4];        //子網(wǎng)掩碼
  11. unsigned char Phy_Addr[6];        //物理地址(MAC)
  12. unsigned char IP_Addr[4];        //本機(jī)IP地址

  13. unsigned char S0_Port[2];        //端口0的端口號(hào)
  14. unsigned char S0_DIP[4];        //端口0目的IP地址
  15. unsigned char S0_DPort[2];        //端口0目的端口號(hào)

  16. unsigned char UDP_DIPR[4];        //UDP(廣播)模式,目的主機(jī)IP地址
  17. unsigned char UDP_DPORT[2];        //UDP(廣播)模式,目的主機(jī)端口號(hào)

  18. /***************----- 端口的運(yùn)行模式 -----***************/
  19. unsigned char S0_Mode =3;        //端口0的運(yùn)行模式,0:TCP服務(wù)器模式,1:TCP客戶端模式,2:UDP(廣播)模式

  20. #define TCP_SERVER        0x00        //TCP服務(wù)器模式
  21. #define TCP_CLIENT        0x01        //TCP客戶端模式
  22. #define UDP_MODE        0x02        //UDP(廣播)模式

  23. /***************----- 端口的運(yùn)行狀態(tài) -----***************/
  24. unsigned char S0_State =0;        //端口0狀態(tài)記錄,1:端口完成初始化,2端口完成連接(可以正常傳輸數(shù)據(jù))
  25. #define S_INIT                0x01        //端口完成初始化
  26. #define S_CONN                0x02        //端口完成連接,可以正常傳輸數(shù)據(jù)

  27. /***************----- 端口收發(fā)數(shù)據(jù)的狀態(tài) -----***************/
  28. unsigned char S0_Data;                //端口0接收和發(fā)送數(shù)據(jù)的狀態(tài),1:端口接收到數(shù)據(jù),2:端口發(fā)送數(shù)據(jù)完成
  29. #define S_RECEIVE         0x01        //端口接收到一個(gè)數(shù)據(jù)包
  30. #define S_TRANSMITOK 0x02        //端口發(fā)送一個(gè)數(shù)據(jù)包完成

  31. /***************----- 端口數(shù)據(jù)緩沖區(qū) -----***************/
  32. unsigned char Rx_Buffer[30];        //端口接收數(shù)據(jù)緩沖區(qū)
  33. unsigned char Tx_Buffer[30];        //端口發(fā)送數(shù)據(jù)緩沖區(qū)

  34. unsigned char W5500_Interrupt;        //W5500中斷標(biāo)志(0:無中斷,1:有中斷)

  35. /*******************************************************************************
  36. * 函數(shù)名  : SPI_ReadByte
  37. * 描述    : 讀取一個(gè)字節(jié)SPI返回的數(shù)據(jù)
  38. * 輸入    : 無
  39. * 輸出    : 無
  40. * 返回值  : 讀取到的寄存器數(shù)據(jù)
  41. * 說明    : 無
  42. *******************************************************************************/
  43. unsigned char SPI_Read_Byte(void)
  44. {
  45.         unsigned char i,rByte=0;
  46.         
  47.         W5500_SCLK=0;
  48.         for(i=0;i<8;i++)
  49.         {
  50.                 W5500_SCLK=1;
  51.                 rByte<<=1;
  52.                 rByte|=W5500_MISO;
  53.                 W5500_SCLK=0;        
  54.         }
  55.         return rByte;
  56. }


  57. /*******************************************************************************
  58. * 函數(shù)名  : Read_SOCK_Data_Buffer
  59. * 描述    : 從W5500接收數(shù)據(jù)緩沖區(qū)中讀取數(shù)據(jù)
  60. * 輸入    : s:端口號(hào),*dat_ptr:數(shù)據(jù)保存緩沖區(qū)指針
  61. * 輸出    : 無
  62. * 返回值  : 讀取到的數(shù)據(jù)長(zhǎng)度,rx_size個(gè)字節(jié)
  63. * 說明    : 無
  64. *******************************************************************************/
  65. unsigned short Read_SOCK_Data_Buffer(SOCKET s, unsigned char *dat_ptr)
  66. {
  67.         unsigned short rx_size;
  68.         unsigned short offset, offset1;
  69.         unsigned short i;
  70.         unsigned char j;

  71.         rx_size=Read_W5500_SOCK_2Byte(s,Sn_RX_RSR);
  72.         if(rx_size==0) return 0;//沒接收到數(shù)據(jù)則返回
  73.         if(rx_size>1460) rx_size=1460;

  74.         offset=Read_W5500_SOCK_2Byte(s,Sn_RX_RD);
  75.         offset1=offset;
  76.         offset&=(S_RX_SIZE-1);//計(jì)算實(shí)際的物理地址

  77.         W5500_SCS=0;//置W5500的SCS為低電平

  78.         SPI_Send_Short(offset);//寫16位地址
  79.         SPI_Send_Byte(VDM|RWB_READ|(s*0x20+0x18));//寫控制字節(jié),N個(gè)字節(jié)數(shù)據(jù)長(zhǎng)度,讀數(shù)據(jù),選擇端口s的寄存器
  80.         
  81.         if((offset+rx_size)<S_RX_SIZE)//如果最大地址未超過W5500接收緩沖區(qū)寄存器的最大地址
  82.         {
  83.                 for(i=0;i<rx_size;i++)//循環(huán)讀取rx_size個(gè)字節(jié)數(shù)據(jù)
  84.                 {
  85.                         j=SPI_Read_Byte();//讀取1個(gè)字節(jié)數(shù)據(jù)
  86.                         *dat_ptr=j;//將讀取到的數(shù)據(jù)保存到數(shù)據(jù)保存緩沖區(qū)
  87.                         dat_ptr++;//數(shù)據(jù)保存緩沖區(qū)指針地址自增1
  88.                 }
  89.         }
  90.         else//如果最大地址超過W5500接收緩沖區(qū)寄存器的最大地址
  91.         {
  92.                 offset=S_RX_SIZE-offset;
  93.                 for(i=0;i<offset;i++)//循環(huán)讀取出前offset個(gè)字節(jié)數(shù)據(jù)
  94.                 {
  95.                         j=SPI_Read_Byte();//讀取1個(gè)字節(jié)數(shù)據(jù)
  96.                         *dat_ptr=j;//將讀取到的數(shù)據(jù)保存到數(shù)據(jù)保存緩沖區(qū)
  97.                         dat_ptr++;//數(shù)據(jù)保存緩沖區(qū)指針地址自增1
  98.                 }
  99.                 W5500_SCS=1; //置W5500的SCS為高電平

  100.                 W5500_SCS=0;//置W5500的SCS為低電平

  101.                 SPI_Send_Short(0x00);//寫16位地址
  102.                 SPI_Send_Byte(VDM|RWB_READ|(s*0x20+0x18));//寫控制字節(jié),N個(gè)字節(jié)數(shù)據(jù)長(zhǎng)度,讀數(shù)據(jù),選擇端口s的寄存器

  103.                 for(;i<rx_size;i++)//循環(huán)讀取后rx_size-offset個(gè)字節(jié)數(shù)據(jù)
  104.                 {
  105.                         j=SPI_Read_Byte();//讀取1個(gè)字節(jié)數(shù)據(jù)
  106.                         *dat_ptr=j;//將讀取到的數(shù)據(jù)保存到數(shù)據(jù)保存緩沖區(qū)
  107.                         dat_ptr++;//數(shù)據(jù)保存緩沖區(qū)指針地址自增1
  108.                 }
  109.         }
  110.         W5500_SCS=1; //置W5500的SCS為高電平

  111.         offset1+=rx_size;//更新實(shí)際物理地址,即下次讀取接收到的數(shù)據(jù)的起始地址
  112.         Write_W5500_SOCK_2Byte(s, Sn_RX_RD, offset1);
  113.         Write_W5500_SOCK_1Byte(s, Sn_CR, RECV);//發(fā)送啟動(dòng)接收命令
  114.         return rx_size;//返回接收到數(shù)據(jù)的長(zhǎng)度
  115. }

  116. /*******************************************************************************
  117. * 函數(shù)名  : Write_SOCK_Data_Buffer
  118. * 描述    : 將數(shù)據(jù)寫入W5500的數(shù)據(jù)發(fā)送緩沖區(qū)
  119. * 輸入    : s:端口號(hào),*dat_ptr:數(shù)據(jù)保存緩沖區(qū)指針,size:待寫入數(shù)據(jù)的長(zhǎng)度
  120. * 輸出    : 無
  121. * 返回值  : 無
  122. * 說明    : 無
  123. *******************************************************************************/
  124. void Write_SOCK_Data_Buffer(SOCKET s, unsigned char *dat_ptr, unsigned short size)
  125. {
  126.         unsigned short offset,offset1;
  127.         unsigned short i;

  128.         //如果是UDP模式,可以在此設(shè)置目的主機(jī)的IP和端口號(hào)
  129.         if((Read_W5500_SOCK_1Byte(s,Sn_MR)&0x0f) != SOCK_UDP)//如果Socket打開失敗
  130.         {               
  131.                 Write_W5500_SOCK_4Byte(s, Sn_DIPR, UDP_DIPR);//設(shè)置目的主機(jī)IP                  
  132.                 Write_W5500_SOCK_2Byte(s, Sn_DPORTR, UDP_DPORT[0]*256+UDP_DPORT[1]);//設(shè)置目的主機(jī)端口號(hào)                                
  133.         }

  134.         offset=Read_W5500_SOCK_2Byte(s,Sn_TX_WR);
  135.         offset1=offset;
  136.         offset&=(S_TX_SIZE-1);//計(jì)算實(shí)際的物理地址

  137.         W5500_SCS=0;//置W5500的SCS為低電平

  138.         SPI_Send_Short(offset);//寫16位地址
  139.         SPI_Send_Byte(VDM|RWB_WRITE|(s*0x20+0x10));//寫控制字節(jié),N個(gè)字節(jié)數(shù)據(jù)長(zhǎng)度,寫數(shù)據(jù),選擇端口s的寄存器

  140.         if((offset+size)<S_TX_SIZE)//如果最大地址未超過W5500發(fā)送緩沖區(qū)寄存器的最大地址
  141.         {
  142.                 for(i=0;i<size;i++)//循環(huán)寫入size個(gè)字節(jié)數(shù)據(jù)
  143.                 {
  144.                         SPI_Send_Byte(*dat_ptr++);//寫入一個(gè)字節(jié)的數(shù)據(jù)               
  145.                 }
  146.         }
  147.         else//如果最大地址超過W5500發(fā)送緩沖區(qū)寄存器的最大地址
  148.         {
  149.                 offset=S_TX_SIZE-offset;
  150.                 for(i=0;i<offset;i++)//循環(huán)寫入前offset個(gè)字節(jié)數(shù)據(jù)
  151.                 {
  152.                         SPI_Send_Byte(*dat_ptr++);//寫入一個(gè)字節(jié)的數(shù)據(jù)
  153.                 }
  154.                 W5500_SCS=1; //置W5500的SCS為高電平

  155.                 W5500_SCS=0;//置W5500的SCS為低電平

  156.                 SPI_Send_Short(0x00);//寫16位地址
  157.                 SPI_Send_Byte(VDM|RWB_WRITE|(s*0x20+0x10));//寫控制字節(jié),N個(gè)字節(jié)數(shù)據(jù)長(zhǎng)度,寫數(shù)據(jù),選擇端口s的寄存器

  158.                 for(;i<size;i++)//循環(huán)寫入size-offset個(gè)字節(jié)數(shù)據(jù)
  159.                 {
  160.                         SPI_Send_Byte(*dat_ptr++);//寫入一個(gè)字節(jié)的數(shù)據(jù)
  161.                 }
  162.         }
  163.         W5500_SCS=1; //置W5500的SCS為高電平

  164.         offset1+=size;//更新實(shí)際物理地址,即下次寫待發(fā)送數(shù)據(jù)到發(fā)送數(shù)據(jù)緩沖區(qū)的起始地址
  165.         Write_W5500_SOCK_2Byte(s, Sn_TX_WR, offset1);
  166.         Write_W5500_SOCK_1Byte(s, Sn_CR, SEND);//發(fā)送啟動(dòng)發(fā)送命令                                
  167. }

  168. /*******************************************************************************
  169. * 函數(shù)名  : W5500_Hardware_Reset
  170. * 描述    : 硬件復(fù)位W5500
  171. * 輸入    : 無
  172. * 輸出    : 無
  173. * 返回值  : 無
  174. * 說明    : W5500的復(fù)位引腳保持低電平至少500us以上,才能重圍W5500
  175. *******************************************************************************/
  176. void W5500_Hardware_Reset(void)
  177. {
  178.         W5500_RST=0;//復(fù)位引腳拉低
  179.         Delay(200);
  180.         W5500_RST=1;//復(fù)位引腳拉高
  181.         Delay(200);
  182.         while((Read_W5500_1Byte(PHYCFGR)&LINK)==0);//等待以太網(wǎng)連接完成
  183. }

  184. /*******************************************************************************
  185. * 函數(shù)名  : W5500_Init
  186. * 描述    : 初始化W5500寄存器函數(shù)
  187. * 輸入    : 無
  188. * 輸出    : 無
  189. * 返回值  : 無
  190. * 說明    : 在使用W5500之前,先對(duì)W5500初始化
  191. *******************************************************************************/
  192. void W5500_Init(void)
  193. {
  194.         unsigned char i=0;

  195.         Write_W5500_1Byte(MR, RST);//軟件復(fù)位W5500,置1有效,復(fù)位后自動(dòng)清0
  196.         Delay(10);//延時(shí)10ms,自己定義該函數(shù)

  197.         //設(shè)置網(wǎng)關(guān)(Gateway)的IP地址,Gateway_IP為4字節(jié)unsigned char數(shù)組,自己定義
  198.         //使用網(wǎng)關(guān)可以使通信突破子網(wǎng)的局限,通過網(wǎng)關(guān)可以訪問到其它子網(wǎng)或進(jìn)入Internet
  199.         Write_W5500_nByte(GAR, Gateway_IP, 4);
  200.                         
  201.         //設(shè)置子網(wǎng)掩碼(MASK)值,SUB_MASK為4字節(jié)unsigned char數(shù)組,自己定義
  202.         //子網(wǎng)掩碼用于子網(wǎng)運(yùn)算
  203.         Write_W5500_nByte(SUBR,Sub_Mask,4);               
  204.         
  205.         //設(shè)置物理地址,PHY_ADDR為6字節(jié)unsigned char數(shù)組,自己定義,用于唯一標(biāo)識(shí)網(wǎng)絡(luò)設(shè)備的物理地址值
  206.         //該地址值需要到IEEE申請(qǐng),按照OUI的規(guī)定,前3個(gè)字節(jié)為廠商代碼,后三個(gè)字節(jié)為產(chǎn)品序號(hào)
  207.         //如果自己定義物理地址,注意第一個(gè)字節(jié)必須為偶數(shù)
  208.         Write_W5500_nByte(SHAR,Phy_Addr,6);               

  209.         //設(shè)置本機(jī)的IP地址,IP_ADDR為4字節(jié)unsigned char數(shù)組,自己定義
  210.         //注意,網(wǎng)關(guān)IP必須與本機(jī)IP屬于同一個(gè)子網(wǎng),否則本機(jī)將無法找到網(wǎng)關(guān)
  211.         Write_W5500_nByte(SIPR,IP_Addr,4);               
  212.         
  213.         //設(shè)置發(fā)送緩沖區(qū)和接收緩沖區(qū)的大小,參考W5500數(shù)據(jù)手冊(cè)
  214.         for(i=0;i<8;i++)
  215.         {
  216.                 Write_W5500_SOCK_1Byte(i,Sn_RXBUF_SIZE, 0x02);//Socket Rx memory size=2k
  217.                 Write_W5500_SOCK_1Byte(i,Sn_TXBUF_SIZE, 0x02);//Socket Tx mempry size=2k
  218.         }

  219.         //設(shè)置重試時(shí)間,默認(rèn)為2000(200ms)
  220.         //每一單位數(shù)值為100微秒,初始化時(shí)值設(shè)為2000(0x07D0),等于200毫秒
  221.         Write_W5500_2Byte(RTR, 0x07d0);

  222.         //設(shè)置重試次數(shù),默認(rèn)為8次
  223.         //如果重發(fā)的次數(shù)超過設(shè)定值,則產(chǎn)生超時(shí)中斷(相關(guān)的端口中斷寄存器中的Sn_IR 超時(shí)位(TIMEOUT)置“1”)
  224.         Write_W5500_1Byte(RCR,8);
  225. }

  226. /*******************************************************************************
  227. * 函數(shù)名  : Detect_Gateway
  228. * 描述    : 檢查網(wǎng)關(guān)服務(wù)器
  229. * 輸入    : 無
  230. * 輸出    : 無
  231. * 返回值  : 成功返回TRUE(0xFF),失敗返回FALSE(0x00)
  232. * 說明    : 無
  233. *******************************************************************************/
  234. unsigned char Detect_Gateway(void)
  235. {
  236.         unsigned char ip_adde[4];
  237.         ip_adde[0]=IP_Addr[0]+1;
  238.         ip_adde[1]=IP_Addr[1]+1;
  239.         ip_adde[2]=IP_Addr[2]+1;
  240.         ip_adde[3]=IP_Addr[3]+1;

  241.         //檢查網(wǎng)關(guān)及獲取網(wǎng)關(guān)的物理地址
  242.         Write_W5500_SOCK_4Byte(0,Sn_DIPR,ip_adde);//向目的地址寄存器寫入與本機(jī)IP不同的IP值
  243.         Write_W5500_SOCK_1Byte(0,Sn_MR,MR_TCP);//設(shè)置socket為TCP模式
  244.         Write_W5500_SOCK_1Byte(0,Sn_CR,OPEN);//打開Socket        
  245.         Delay(5);//延時(shí)5ms         
  246.         
  247.         if(Read_W5500_SOCK_1Byte(0,Sn_SR) != SOCK_INIT)//如果socket打開失敗
  248.         {
  249.                 Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);//打開不成功,關(guān)閉Socket
  250.                 return FALSE;//返回FALSE(0x00)
  251.         }

  252.         Write_W5500_SOCK_1Byte(0,Sn_CR,CONNECT);//設(shè)置Socket為Connect模式                                                

  253.         do
  254.         {
  255.                 unsigned char j=0;
  256.                 j=Read_W5500_SOCK_1Byte(0,Sn_IR);//讀取Socket0中斷標(biāo)志寄存器
  257.                 if(j!=0)
  258.                 Write_W5500_SOCK_1Byte(0,Sn_IR,j);
  259.                 Delay(5);//延時(shí)5ms
  260.                 if((j&IR_TIMEOUT) == IR_TIMEOUT)
  261.                 {
  262.                         return FALSE;        
  263.                 }
  264.                 else if(Read_W5500_SOCK_1Byte(0,Sn_DHAR) != 0xff)
  265.                 {
  266.                         Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);//關(guān)閉Socket
  267.                         return TRUE;                                                        
  268.                 }
  269.         }while(1);
  270. }

  271. /*******************************************************************************
  272. * 函數(shù)名  : Socket_Init
  273. * 描述    : 指定Socket(0~7)初始化
  274. * 輸入    : s:待初始化的端口
  275. * 輸出    : 無
  276. * 返回值  : 無
  277. * 說明    : 無
  278. *******************************************************************************/
  279. void Socket_Init(SOCKET s)
  280. {
  281.         //設(shè)置分片長(zhǎng)度,參考W5500數(shù)據(jù)手冊(cè),該值可以不修改        
  282.         Write_W5500_SOCK_2Byte(0, Sn_MSSR, 30);//最大分片字節(jié)數(shù)=30(0x001e)
  283.         //設(shè)置指定端口
  284.         switch(s)
  285.         {
  286.                 case 0:
  287.                         //設(shè)置端口0的端口號(hào)
  288.                         Write_W5500_SOCK_2Byte(0, Sn_PORT, S0_Port[0]*256+S0_Port[1]);        
  289.                         
  290.                         break;

  291.                 case 1:
  292.                         break;

  293.                 case 2:
  294.                         break;

  295.                 case 3:
  296.                         break;

  297.                 case 4:
  298.                         break;

  299.                 case 5:
  300.                         break;

  301.                 case 6:
  302.                         break;

  303.                 case 7:
  304.                         break;

  305.                 default:
  306.                         break;
  307.         }
  308. }

  309. /*******************************************************************************
  310. * 函數(shù)名  : Socket_Connect
  311. * 描述    : 設(shè)置指定Socket(0~7)為客戶端與遠(yuǎn)程服務(wù)器連接
  312. * 輸入    : s:待設(shè)定的端口
  313. * 輸出    : 無
  314. * 返回值  : 成功返回TRUE(0xFF),失敗返回FALSE(0x00)
  315. * 說明    : 當(dāng)本機(jī)Socket工作在客戶端模式時(shí),引用該程序,與遠(yuǎn)程服務(wù)器建立連接
  316. *                        如果啟動(dòng)連接后出現(xiàn)超時(shí)中斷,則與服務(wù)器連接失敗,需要重新調(diào)用該程序連接
  317. *                        該程序每調(diào)用一次,就與服務(wù)器產(chǎn)生一次連接
  318. *******************************************************************************/
  319. unsigned char Socket_Connect(SOCKET s)
  320. {
  321.         Write_W5500_SOCK_1Byte(s,Sn_MR,MR_TCP);//設(shè)置socket為TCP模式
  322.         Write_W5500_SOCK_1Byte(s,Sn_CR,OPEN);//打開Socket
  323.         Delay(5);//延時(shí)5ms
  324.         if(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_INIT)//如果socket打開失敗
  325.         {
  326.                 Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);//打開不成功,關(guān)閉Socket
  327.                 return FALSE;//返回FALSE(0x00)
  328.         }
  329.         Write_W5500_SOCK_1Byte(s,Sn_CR,CONNECT);//設(shè)置Socket為Connect模式
  330.         return TRUE;//返回TRUE,設(shè)置成功
  331. }

  332. /*******************************************************************************
  333. * 函數(shù)名  : Socket_Listen
  334. * 描述    : 設(shè)置指定Socket(0~7)作為服務(wù)器等待遠(yuǎn)程主機(jī)的連接
  335. * 輸入    : s:待設(shè)定的端口
  336. * 輸出    : 無
  337. * 返回值  : 成功返回TRUE(0xFF),失敗返回FALSE(0x00)
  338. * 說明    : 當(dāng)本機(jī)Socket工作在服務(wù)器模式時(shí),引用該程序,等等遠(yuǎn)程主機(jī)的連接
  339. *                        該程序只調(diào)用一次,就使W5500設(shè)置為服務(wù)器模式
  340. *******************************************************************************/
  341. unsigned char Socket_Listen(SOCKET s)
  342. {
  343.         Write_W5500_SOCK_1Byte(s,Sn_MR,MR_TCP);//設(shè)置socket為TCP模式
  344.         Write_W5500_SOCK_1Byte(s,Sn_CR,OPEN);//打開Socket        
  345.         Delay(5);//延時(shí)5ms
  346.         if(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_INIT)//如果socket打開失敗
  347.         {
  348.                 Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);//打開不成功,關(guān)閉Socket
  349.                 return FALSE;//返回FALSE(0x00)
  350.         }        
  351.         Write_W5500_SOCK_1Byte(s,Sn_CR,LISTEN);//設(shè)置Socket為偵聽模式        
  352.         Delay(5);//延時(shí)5ms
  353.         if(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_LISTEN)//如果socket設(shè)置失敗
  354.         {
  355.                 Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);//設(shè)置不成功,關(guān)閉Socket
  356.                 return FALSE;//返回FALSE(0x00)
  357.         }

  358.         return TRUE;

  359.         //至此完成了Socket的打開和設(shè)置偵聽工作,至于遠(yuǎn)程客戶端是否與它建立連接,則需要等待Socket中斷,
  360.         //以判斷Socket的連接是否成功。參考W5500數(shù)據(jù)手冊(cè)的Socket中斷狀態(tài)
  361.         //在服務(wù)器偵聽模式不需要設(shè)置目的IP和目的端口號(hào)
  362. }

  363. /*******************************************************************************
  364. * 函數(shù)名  : Socket_UDP
  365. * 描述    : 設(shè)置指定Socket(0~7)為UDP模式
  366. * 輸入    : s:待設(shè)定的端口
  367. * 輸出    : 無
  368. * 返回值  : 成功返回TRUE(0xFF),失敗返回FALSE(0x00)
  369. * 說明    : 如果Socket工作在UDP模式,引用該程序,在UDP模式下,Socket通信不需要建立連接
  370. *                        該程序只調(diào)用一次,就使W5500設(shè)置為UDP模式
  371. *******************************************************************************/
  372. unsigned char Socket_UDP(SOCKET s)
  373. {
  374.         Write_W5500_SOCK_1Byte(s,Sn_MR,MR_UDP);//設(shè)置Socket為UDP模式*/
  375.         Write_W5500_SOCK_1Byte(s,Sn_CR,OPEN);//打開Socket*/
  376.         Delay(5);//延時(shí)5ms
  377.         if(Read_W5500_SOCK_1Byte(s,Sn_SR)!=SOCK_UDP)//如果Socket打開失敗
  378.         {
  379.                 Write_W5500_SOCK_1Byte(s,Sn_CR,CLOSE);//打開不成功,關(guān)閉Socket
  380.                 return FALSE;//返回FALSE(0x00)
  381.         }
  382.         else
  383.                 return TRUE;

  384.         //至此完成了Socket的打開和UDP模式設(shè)置,在這種模式下它不需要與遠(yuǎn)程主機(jī)建立連接
  385.         //因?yàn)镾ocket不需要建立連接,所以在發(fā)送數(shù)據(jù)前都可以設(shè)置目的主機(jī)IP和目的Socket的端口號(hào)
  386.         //如果目的主機(jī)IP和目的Socket的端口號(hào)是固定的,在運(yùn)行過程中沒有改變,那么也可以在這里設(shè)置
  387. }

  388. /*******************************************************************************
  389. * 函數(shù)名  : W5500_Interrupt_Process
  390. * 描述    : W5500中斷處理程序框架
  391. * 輸入    : 無
  392. * 輸出    : 無
  393. * 返回值  : 無
  394. * 說明    : 無
  395. *******************************************************************************/
  396. void W5500_Interrupt_Process(void)
  397. {
  398.         unsigned char i,j;

  399. IntDispose:

  400.         i=Read_W5500_1Byte(SIR);//讀取端口中斷標(biāo)志寄存器        
  401.         if((i & S0_INT) == S0_INT)//Socket0事件處理
  402.         {
  403.                 j=Read_W5500_SOCK_1Byte(0,Sn_IR);//讀取Socket0中斷標(biāo)志寄存器
  404.                 Write_W5500_SOCK_1Byte(0,Sn_IR,j);
  405.                 if(j&IR_CON)//在TCP模式下,Socket0成功連接
  406.                 {
  407.                         S0_State|=S_CONN;//網(wǎng)絡(luò)連接狀態(tài)0x02,端口完成連接,可以正常傳輸數(shù)據(jù)
  408.                 }
  409.                 if(j&IR_DISCON)//在TCP模式下Socket斷開連接處理
  410.                 {
  411.                         Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);//關(guān)閉端口,等待重新打開連接
  412.                         Socket_Init(0);                //指定Socket(0~7)初始化,初始化端口0
  413.                         S0_State=0;//網(wǎng)絡(luò)連接狀態(tài)0x00,端口連接失敗
  414.                 }
  415.                 if(j&IR_SEND_OK)//Socket0數(shù)據(jù)發(fā)送完成,可以再次啟動(dòng)S_tx_process()函數(shù)發(fā)送數(shù)據(jù)
  416.                 {
  417.                         S0_Data|=S_TRANSMITOK;//端口發(fā)送一個(gè)數(shù)據(jù)包完成
  418.                 }
  419.                 if(j&IR_RECV)//Socket接收到數(shù)據(jù),可以啟動(dòng)S_rx_process()函數(shù)
  420.                 {
  421.                         S0_Data|=S_RECEIVE;//端口接收到一個(gè)數(shù)據(jù)包
  422.                 }
  423.                 if(j&IR_TIMEOUT)//Socket連接或數(shù)據(jù)傳輸超時(shí)處理
  424.                 {
  425.                         Write_W5500_SOCK_1Byte(0,Sn_CR,CLOSE);// 關(guān)閉端口,等待重新打開連接                        
  426.                         S0_State=0;//網(wǎng)絡(luò)連接狀態(tài)0x00,端口連接失敗
  427.                 }
  428.         }

  429.         if(Read_W5500_1Byte(SIR) != 0)
  430.                 goto IntDispose;
  431. }
復(fù)制代碼



Keil代碼下載: W5500模塊-服務(wù)端模式例程(51單片機(jī)).zip (86.31 KB, 下載次數(shù): 125)

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏6 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:257260 發(fā)表于 2022-7-12 17:42 | 只看該作者
這么好的文章,竟然沒有人評(píng)論。
回復(fù)

使用道具 舉報(bào)

板凳
ID:237471 發(fā)表于 2023-10-31 16:45 | 只看該作者
非常精彩的代碼,復(fù)制回去研究一下,應(yīng)該是不錯(cuò)的思路
回復(fù)

使用道具 舉報(bào)

地板
ID:337487 發(fā)表于 2023-11-1 08:17 | 只看該作者
不錯(cuò),正好在用這個(gè)芯片,可以好好學(xué)習(xí)一下。
回復(fù)

使用道具 舉報(bào)

5#
ID:308274 發(fā)表于 2024-8-9 08:29 | 只看該作者
好文章,剛接觸這個(gè)芯片,學(xué)習(xí)一下
回復(fù)

使用道具 舉報(bào)

6#
ID:433219 發(fā)表于 2024-8-9 14:06 | 只看該作者
W5500  LQFP的塊頭實(shí)在是浪費(fèi)了,實(shí)際上沒多少引腳有效使用
回復(fù)

使用道具 舉報(bào)

7#
ID:3802 發(fā)表于 2024-8-13 07:21 | 只看該作者

這么好的文章,竟然沒有人評(píng)論。
回復(fù)

使用道具 舉報(bào)

8#
ID:606277 發(fā)表于 2024-11-14 10:04 | 只看該作者
樓主無私的奉獻(xiàn)值得贊賞,希望再接再厲。
回復(fù)

使用道具 舉報(bào)

9#
ID:588044 發(fā)表于 2024-11-26 11:07 | 只看該作者
好東西,下來學(xué)習(xí)下!謝謝樓主的無私奉獻(xiàn)。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表