查看: 4335|回复: 4

[主题月] 【9月主题月】LPC845+W5500 TCP CLIENT 回环

[复制链接]
  • TA的每日心情

    2025-5-29 09:38
  • 签到天数: 632 天

    连续签到: 1 天

    [LV.9]以坛为家II

    94

    主题

    1639

    帖子

    2

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    4470

    热心会员

    最后登录
    2025-6-10
    发表于 2021-10-9 14:13:43 | 显示全部楼层 |阅读模式
    9月底那会,答应日天写9月主题月的内容。可是月底事多,加上假期回老家,一直没写,很是惭愧。
    今天我有些空,就要LPC845+自制W5500模块来实现TCP的回环通讯(即TCP CLIENT 向TCP SERVER 发送信息,都会原封不动的返回)。
    来打通W5500这个具有硬件IP协议的网络通讯芯片~这也是它上手简单的原因,不要去考虑软件层的诸多协议。
    也算是个简单的小例子~请高手勿喷~本代码来着N年前XX32的一次代码移植。
    先上板子图片:
    W5500模块,改在arduino扩展板上了~(有arduino的开发板比较多,改了后,比较方便)
    X1.jpg
    X2.jpg
    插在LPC845_LITE底板上面:
    X3.jpg
    X4.jpg
    具体接线:
    X6.jpg
    X5.jpg
    下面我们开始写W5500驱动代码,本板用SPI的方式驱动~
    通过MCUXpresso配置工具配置初始化代码:
    Z2.png
    Z3.png
    Z1.png
    开始写SPI底层驱动函数:
    spi.h
    1. /**
    2.   ******************************************************************************
    3.   * @file    spi.h
    4.   * $Author: wdluo $
    5.   * $Revision: 17 $
    6.   * $Date:: 2012-07-06 11:16:48 +0800 #$
    7.   * @brief   SPI驱动函数声明.
    8.   ******************************************************************************
    9.   * @attention
    10.   *
    11.   *<h3><center>© Copyright 2009-2012, ViewTool</center>
    12.   *<center><a href="http:\\www.viewtool.com">http://www.viewtool.com</a></center>
    13.   *<center>All Rights Reserved</center></h3>
    14.   *
    15.   ******************************************************************************
    16.   */
    17. /* Define to prevent recursive inclusion -------------------------------------*/
    18. #ifndef __SPI_H
    19. #define __SPI_H
    20. /* Includes ------------------------------------------------------------------*/
    21. #include "sys.h"
    22. #include "pin_mux.h"
    23. #include "fsl_spi.h"
    24. #include "fsl_gpio.h"

    25. #define W5500_CS_GPIO             BOARD_INITPINS_SPI1_SSEL0_GPIO                 /*!<@brief GPIO peripheral base pointer */
    26. #define W5500_CS_GPIO_PIN_MASK    BOARD_INITPINS_SPI1_SSEL0_GPIO_PIN_MASK /*!<@brief GPIO pin mask */
    27. #define W5500_CS_PORT             BOARD_INITPINS_SPI1_SSEL0_PORT                   /*!<@brief PORT device index: 1 */
    28. #define W5500_CS_PIN              BOARD_INITPINS_SPI1_SSEL0_PIN                    /*!<@brief PORT pin number */
    29. #define W5500_CS_PIN_MASK         BOARD_INITPINS_SPI1_SSEL0_PIN_MASK     /*!<@brief PORT pin mask */
    30.      
    31. /////具体引脚控制定义
    32. #define W5500_CS_H()              GPIO_PortSet(W5500_CS_GPIO, W5500_CS_PORT,1U << W5500_CS_PIN)
    33. #define W5500_CS_L()              GPIO_PortClear(W5500_CS_GPIO, W5500_CS_PORT,1U << W5500_CS_PIN)



    34. /* Exported Functions --------------------------------------------------------*/

    35. void SPI_Configuration(void);
    36. void SPI_WriteByte(uint8_t TxData);
    37. uint8_t SPI_ReadByte(void);
    38. void SPI_CrisEnter(void);
    39. void SPI_CrisExit(void);
    40. void SPI_CS_Select(void);
    41. void SPI_CS_Deselect(void);

    42. #endif /* __SPI_H */

    43. /*********************************END OF FILE**********************************/
    复制代码

    spi.c

    1. /* Includes ------------------------------------------------------------------*/
    2. #include "spi.h"
    3. #include "peripherals.h"
    4. /* Private typedef -----------------------------------------------------------*/
    5. /* Private define ------------------------------------------------------------*/
    6. /* Private macro -------------------------------------------------------------*/
    7. /* Private variables ---------------------------------------------------------*/
    8. /* Private function prototypes -----------------------------------------------*/
    9. /* Private functions ---------------------------------------------------------*/


    10. /**
    11.   * @brief  根据外部SPI设备配置SPI相关参数
    12.   * @retval None
    13.   */
    14. void SPI_Configuration(void)
    15. {
    16.         const spi_master_config_t SPI1_config = {
    17.   .baudRate_Bps = 500000UL,
    18.   .clockPolarity = kSPI_ClockPolarityActiveHigh,
    19.   .clockPhase = kSPI_ClockPhaseFirstEdge,
    20.   .direction = kSPI_MsbFirst,
    21.   .dataWidth = 7,
    22.   .sselNumber = kSPI_Ssel0Assert,
    23.   .sselPolarity = kSPI_SpolActiveAllLow,
    24.   .enableLoopback = false,
    25.   .enableMaster = true,
    26.   .delayConfig = {
    27.     .preDelay = 0U,
    28.     .postDelay = 0U,
    29.     .frameDelay = 0U,
    30.     .transferDelay = 0U
    31.   }
    32. };

    33.   /* Initialization function */
    34.   SPI_MasterInit(SPI1_PERIPHERAL, &SPI1_config, SPI1_CLOCK_SOURCE);
    35.        
    36. }


    37. //SPI读写一个字节
    38. u8 spi1_write_read_byte(u8 writedata)
    39. {
    40.   u8 readdata=0;
    41.   //等待发送成功
    42.   while ((SPI1->STAT & SPI_STAT_TXRDY_MASK) == 0U)
    43.   {
    44.    
    45.   }  
    46.   SPI1->TXDAT = ((uint32_t)writedata & 0x0000FFFFU);
    47.   
    48.   while ((SPI1->STAT & SPI_STAT_RXRDY_MASK) == 0U)
    49.   {
    50.   }
    51.   readdata = SPI1->RXDAT;
    52.   
    53.   return readdata;
    54. }
    55. /**
    56.   * @brief  写1字节数据到SPI总线
    57.   * @param  TxData 写到总线的数据
    58.   * @retval None
    59.   */
    60. void SPI_WriteByte(uint8_t TxData)
    61. {                                 
    62.         spi1_write_read_byte(TxData);
    63. }
    64. /**
    65.   * @brief  从SPI总线读取1字节数据
    66.   * @retval 读到的数据
    67.   */
    68. uint8_t SPI_ReadByte(void)
    69. {                         
    70.         return spi1_write_read_byte(0XFF);                                                      
    71. }
    72. /**
    73.   * @brief  进入临界区
    74.   * @retval None
    75.   */
    76. void SPI_CrisEnter(void)
    77. {
    78.         __set_PRIMASK(1);
    79. }
    80. /**
    81.   * @brief  退出临界区
    82.   * @retval None
    83.   */
    84. void SPI_CrisExit(void)
    85. {
    86.         __set_PRIMASK(0);
    87. }

    88. /**
    89.   * @brief  片选信号输出低电平
    90.   * @retval None
    91.   */
    92. void SPI_CS_Select(void)
    93. {
    94.         W5500_CS_L();
    95. }
    96. /**
    97.   * @brief  片选信号输出高电平
    98.   * @retval None
    99.   */
    100. void SPI_CS_Deselect(void)
    101. {
    102.         W5500_CS_H();
    103. }
    104. /*********************************END OF FILE**********************************/

    复制代码
    中间层及应用层代码无需改变(蓝框内),直接调用。
    A0.png
    在main函数里面写测试代码:
    main.c
    1. /*
    2. * Copyright (c) 2015, Freescale Semiconductor, Inc.
    3. * Copyright 2016-2019 NXP
    4. * All rights reserved.
    5. *
    6. * SPDX-License-Identifier: BSD-3-Clause
    7. */

    8. #include "pin_mux.h"
    9. #include "board.h"
    10. #include "peripherals.h"
    11. //#include "fsl_debug_console.h"
    12. #include "fsl_gpio.h"
    13. #include "stdio.h"

    14. #include "sys.h"
    15. #include "delay.h"
    16. #include "led.h"
    17. #include "key.h"
    18. #include "usart.h"
    19. #include "ctime.h"

    20. #include "usart1.h"
    21. #include "sctime.h"
    22. //#include "tmt.h"
    23. //#include "hc05.h"

    24. //#include "lcd_init.h"
    25. //#include "lcd.h"
    26. //#include "pic.h"

    27. #include "spi.h"
    28. #include "socket.h"        // Just include one header for WIZCHIP
    29. /*******************************************************************************
    30. * Prototypes
    31. ******************************************************************************/
    32. #define SOCK_TCPS        0
    33. #define SOCK_UDPS        1
    34. #define DATA_BUF_SIZE   2048
    35. /*******************************************************************************
    36. * Variables
    37. ******************************************************************************/
    38. uint8_t gDATABUF[DATA_BUF_SIZE];
    39. // Default Network Configuration
    40. wiz_NetInfo gWIZNETINFO = { .mac = {0x00, 0x08, 0xdc,0x00, 0xab, 0xcd},
    41.                             .ip = {192, 168, 0, 123},
    42.                             .sn = {255,255,255,0},
    43.                             .gw = {192, 168, 0, 1},
    44.                             .dns = {0,0,0,0},
    45.                             .dhcp = NETINFO_STATIC };

    46. /*******************************************************************************
    47. * Code
    48. ******************************************************************************/
    49. void platform_init(void);                                                                // initialize the dependent host peripheral
    50. void network_init(void);                                                                // Initialize Network information and display it
    51. int32_t loopback_tcps(uint8_t, uint8_t*, uint16_t);                // Loopback TCP server
    52. int32_t loopback_udps(uint8_t, uint8_t*, uint16_t);                // Loopback UDP server

    53. /*!
    54. * @brief Main function
    55. */
    56. int main(void)
    57. {
    58.   u8 key = 0,flg=0;
    59.   u16 t;  
    60.   u16 len;       
    61.   u16 times=0;
    62.   float m=0;

    63.   u8 sendmask=0;
    64.   u8 sendcnt=0;
    65.   u8 sendbuf[20];          
    66.   u8 reclen=0;
    67.   
    68.   uint8_t tmp;
    69.         int32_t ret = 0;
    70.         uint8_t memsize[2][8] = {{2,2,2,2,2,2,2,2},{2,2,2,2,2,2,2,2}};       

    71.   /* Board pin, clock, debug console init */
    72.   /* Select the main clock as source clock of USART0 (debug console) */
    73.   CLOCK_Select(BOARD_DEBUG_USART_CLK_ATTACH);

    74.   BOARD_InitBootPins();
    75.   BOARD_InitBootClocks();
    76.   BOARD_InitBootPeripherals();


    77.   //Host dependent peripheral initialized
    78.         platform_init();
    79.         // First of all, Should register SPI callback functions implemented by user for accessing WIZCHIP
    80.         /* Critical section callback */
    81.         reg_wizchip_cris_cbfunc(SPI_CrisEnter, SPI_CrisExit);        //注册临界区函数
    82.         /* Chip selection call back */
    83. #if   _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_
    84.         reg_wizchip_cs_cbfunc(SPI_CS_Select, SPI_CS_Deselect);//注册SPI片选信号函数
    85. #elif _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_
    86.         reg_wizchip_cs_cbfunc(SPI_CS_Select, SPI_CS_Deselect);  // CS must be tried with LOW.
    87. #else
    88.    #if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SIP_) != _WIZCHIP_IO_MODE_SIP_
    89.       #error "Unknown _WIZCHIP_IO_MODE_"
    90.    #else
    91.       reg_wizchip_cs_cbfunc(wizchip_select, wizchip_deselect);
    92.    #endif
    93. #endif
    94.         /* SPI Read & Write callback function */
    95.         reg_wizchip_spi_cbfunc(SPI_ReadByte, SPI_WriteByte);        //注册读写函数

    96.         /* WIZCHIP SOCKET Buffer initialize */
    97.         if(ctlwizchip(CW_INIT_WIZCHIP,(void*)memsize) == -1){
    98.                  printf("WIZCHIP Initialized fail.\r\n");
    99.                  while(1);
    100.         }

    101.         /* PHY link status check */
    102.         do{
    103.                  if(ctlwizchip(CW_GET_PHYLINK, (void*)&tmp) == -1){
    104.                                 printf("Unknown PHY Link stauts.\r\n");
    105.                  }
    106.         }while(tmp == PHY_LINK_OFF);

    107.         /* Network initialization */
    108.         network_init();

    109.         /*******************************/
    110.         /* WIZnet W5500 Code Examples  */
    111.         /* TCPS/UDPS Loopback test     */
    112.         /*******************************/
    113.   /* Main loop */
    114.         while(1)
    115.         {
    116.                 /* Loopback Test */
    117.                 // TCP server loopback test
    118.                 if( (ret = loopback_tcps(SOCK_TCPS, gDATABUF, 5000)) < 0) {
    119.                         printf("SOCKET ERROR : %ld\r\n", ret);
    120.                 }
    121.     // UDP server loopback test
    122.                 if( (ret = loopback_udps(SOCK_UDPS, gDATABUF, 3000)) < 0) {
    123.                         printf("SOCKET ERROR : %ld\r\n", ret);
    124.                 }
    125.         } // end of Main loop
    126. }// end of main()

    127. /**
    128.   * @brief  Intialize the network information to be used in WIZCHIP
    129.   * @retval None
    130.   */
    131. void network_init(void)
    132. {
    133.    uint8_t tmpstr[6];
    134.         ctlnetwork(CN_SET_NETINFO, (void*)&gWIZNETINFO);
    135.         ctlnetwork(CN_GET_NETINFO, (void*)&gWIZNETINFO);

    136.         // Display Network Information
    137.         ctlwizchip(CW_GET_ID,(void*)tmpstr);
    138.         printf("\r\n=== %s NET CONF ===\r\n",(char*)tmpstr);
    139.         printf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n",gWIZNETINFO.mac[0],gWIZNETINFO.mac[1],gWIZNETINFO.mac[2],
    140.                   gWIZNETINFO.mac[3],gWIZNETINFO.mac[4],gWIZNETINFO.mac[5]);
    141.         printf("SIP: %d.%d.%d.%d\r\n", gWIZNETINFO.ip[0],gWIZNETINFO.ip[1],gWIZNETINFO.ip[2],gWIZNETINFO.ip[3]);
    142.         printf("GAR: %d.%d.%d.%d\r\n", gWIZNETINFO.gw[0],gWIZNETINFO.gw[1],gWIZNETINFO.gw[2],gWIZNETINFO.gw[3]);
    143.         printf("SUB: %d.%d.%d.%d\r\n", gWIZNETINFO.sn[0],gWIZNETINFO.sn[1],gWIZNETINFO.sn[2],gWIZNETINFO.sn[3]);
    144.         printf("DNS: %d.%d.%d.%d\r\n", gWIZNETINFO.dns[0],gWIZNETINFO.dns[1],gWIZNETINFO.dns[2],gWIZNETINFO.dns[3]);
    145.         printf("======================\r\n");
    146. }

    147. /**
    148.   * @brief  Loopback Test Example Code using ioLibrary_BSD       
    149.   * @retval None
    150.   */
    151. int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port)
    152. {
    153.    int32_t ret;
    154.    uint16_t size = 0, sentsize=0;
    155.    switch(getSn_SR(sn))
    156.    {
    157.       case SOCK_ESTABLISHED :
    158.          if(getSn_IR(sn) & Sn_IR_CON)
    159.          {
    160.             printf("%d:Connected\r\n",sn);
    161.             setSn_IR(sn,Sn_IR_CON);
    162.          }
    163.          if((size = getSn_RX_RSR(sn)) > 0)
    164.          {
    165.             if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
    166.             ret = recv(sn,buf,size);
    167.             if(ret <= 0) return ret;
    168.             sentsize = 0;
    169.             while(size != sentsize)
    170.             {
    171.                ret = send(sn,buf+sentsize,size-sentsize);
    172.                if(ret < 0)
    173.                {
    174.                   close(sn);
    175.                   return ret;
    176.                }
    177.                sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
    178.             }
    179.          }
    180.          break;
    181.       case SOCK_CLOSE_WAIT :
    182.          printf("%d:CloseWait\r\n",sn);
    183.          if((ret=disconnect(sn)) != SOCK_OK) return ret;
    184.          printf("%d:Closed\r\n",sn);
    185.          break;
    186.       case SOCK_INIT :
    187.               printf("%d:Listen, port [%d]\r\n",sn, port);
    188.          if( (ret = listen(sn)) != SOCK_OK) return ret;
    189.          break;
    190.       case SOCK_CLOSED:
    191.          printf("%d:LBTStart\r\n",sn);
    192.          if((ret=socket(sn,Sn_MR_TCP,port,0x00)) != sn)
    193.             return ret;
    194.          printf("%d:Opened\r\n",sn);
    195.          break;
    196.       default:
    197.          break;
    198.    }
    199.    return 1;
    200. }

    201. /**
    202.   * @brief  Loopback Test Example Code using ioLibrary_BSD       
    203.   * @retval None
    204.   */
    205. int32_t loopback_udps(uint8_t sn, uint8_t* buf, uint16_t port)
    206. {
    207.    int32_t  ret;
    208.    uint16_t size, sentsize;
    209.    uint8_t  destip[4];
    210.    uint16_t destport;
    211.    //uint8_t  packinfo = 0;
    212.    switch(getSn_SR(sn))
    213.    {
    214.       case SOCK_UDP :
    215.          if((size = getSn_RX_RSR(sn)) > 0)
    216.          {
    217.             if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
    218.             ret = recvfrom(sn,buf,size,destip,(uint16_t*)&destport);
    219.             if(ret <= 0)
    220.             {
    221.                printf("%d: recvfrom error. %ld\r\n",sn,ret);
    222.                return ret;
    223.             }
    224.             size = (uint16_t) ret;
    225.             sentsize = 0;
    226.             while(sentsize != size)
    227.             {
    228.                ret = sendto(sn,buf+sentsize,size-sentsize,destip,destport);
    229.                if(ret < 0)
    230.                {
    231.                   printf("%d: sendto error. %ld\r\n",sn,ret);
    232.                   return ret;
    233.                }
    234.                sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
    235.             }
    236.          }
    237.          break;
    238.       case SOCK_CLOSED:
    239.          printf("%d:LBUStart\r\n",sn);
    240.          if((ret=socket(sn,Sn_MR_UDP,port,0x00)) != sn)
    241.             return ret;
    242.          printf("%d:Opened, port [%d]\r\n",sn, port);
    243.          break;
    244.       default :
    245.          break;
    246.    }
    247.    return 1;
    248. }

    249. /**
    250.   * @brief  Loopback Test Example Code using ioLibrary_BSD       
    251.   * @retval None
    252.   */
    253. void platform_init(void)
    254. {
    255.         delay_init();
    256.   LED_Init();
    257.   KEY_Init();
    258.         printf("\x0c");printf("\x0c");//超级终端清屏
    259.         printf("\033[1;40;32m");//设置超级终端背景为黑色,字符为绿色
    260.         printf("\r\n*******************************************************************************");
    261.         printf("\r\n************************ Copyright 2009-2014, EmbedNet ************************");
    262.         printf("\r\n*************************** http://www.embed-net.com **************************");
    263.         printf("\r\n***************************** All Rights Reserved *****************************");
    264.         printf("\r\n*******************************************************************************");
    265.         printf("\r\n");
    266.         //Config SPI
    267.         SPI_Configuration();
    268.         //延时初始化
    269.         delay_init();
    270. }
    复制代码
    编译下载,将网线和电脑连接好,复位后我们进行连接查看:
    串口输出配置信息:
    MM0.png
    当前W5500IP地址为192.168.0.123 ,我们设置连接的电脑的IP地址与其在同一个网段(选择局域网属性,选择IPV4属性,
    地址改为192.168.0.x,这了我们设置为192.168.0.1。这了就不截图演示了):
    打开命令,发送ping指令,发现连接正常:
    MM1.png
    打开网络调试助手,输入正确的远程地址及端号,连接好后,发送一句语句,W5500接受到后,会发回收到的语句。
    MM2.png
    好了,简单的LPC845+W5500 TCP测试就到这了。谢谢观看~
    W5500数据手册中文版: W5500_DS_v100e_CN.pdf (1.35 MB, 下载次数: 6)
    哎...今天够累的,签到来了~
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    12 小时前
  • 签到天数: 2382 天

    连续签到: 91 天

    [LV.Master]伴坛终老

    84

    主题

    1万

    帖子

    3

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    22108
    最后登录
    2025-7-31
    发表于 2021-10-9 14:46:08 | 显示全部楼层
    非常棒,学习学习


    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2025-5-7 08:45
  • 签到天数: 279 天

    连续签到: 1 天

    [LV.8]以坛为家I

    114

    主题

    1313

    帖子

    29

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    10975

    热心会员

    最后登录
    2025-7-30
    发表于 2021-10-9 15:17:01 | 显示全部楼层
    6666,赞一个
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    3 小时前
  • 签到天数: 1853 天

    连续签到: 4 天

    [LV.Master]伴坛终老

    203

    主题

    3万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    112646
    最后登录
    2025-7-31
    发表于 2021-10-9 16:35:38 | 显示全部楼层
    W5500确实是一款不错的TCP/IP协议栈芯片,之前还淘了一个W5500的开发板 TS1 - 副本 (2).jpg TS1 - 副本 (4).jpg TS1 - 副本 (3).jpg TS1 - 副本 (5).jpg TS1 - 副本 (9).jpg TS1 - 副本 (8).jpg TS1 - 副本 (7).jpg TS1 - 副本 (6).jpg TS1 - 副本 (10).jpg TS1.jpg
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    前天 17:40
  • 签到天数: 1503 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    97

    主题

    4691

    帖子

    12

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    10088
    最后登录
    2025-7-29
    发表于 2021-10-11 09:48:42 | 显示全部楼层
    第一次回环使用了60+ms,第三次是 8ms。
    这个是属于小数据的测试结果
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-31 23:58 , Processed in 0.091985 second(s), 24 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表