在线时间376 小时
UID3135871
注册时间2016-10-9
NXP金币97

TA的每日心情 | 怒 2025-5-29 09:38 |
---|
签到天数: 632 天 连续签到: 1 天 [LV.9]以坛为家II
版主
  
- 积分
- 4470

- 最后登录
- 2025-6-10
|
9月底那会,答应日天写9月主题月的内容。可是月底事多,加上假期回老家,一直没写,很是惭愧。
今天我有些空,就要LPC845+自制W5500模块来实现TCP的回环通讯(即TCP CLIENT 向TCP SERVER 发送信息,都会原封不动的返回)。
来打通W5500这个具有硬件IP协议的网络通讯芯片~这也是它上手简单的原因,不要去考虑软件层的诸多协议。
也算是个简单的小例子~请高手勿喷~本代码来着N年前XX32的一次代码移植。
先上板子图片:
W5500模块,改在arduino扩展板上了~(有arduino的开发板比较多,改了后,比较方便)
插在LPC845_LITE底板上面:
具体接线:
下面我们开始写W5500驱动代码,本板用SPI的方式驱动~
通过MCUXpresso配置工具配置初始化代码:
开始写SPI底层驱动函数:
spi.h
- /**
- ******************************************************************************
- * @file spi.h
- * $Author: wdluo $
- * $Revision: 17 $
- * $Date:: 2012-07-06 11:16:48 +0800 #$
- * @brief SPI驱动函数声明.
- ******************************************************************************
- * @attention
- *
- *<h3><center>© Copyright 2009-2012, ViewTool</center>
- *<center><a href="http:\\www.viewtool.com">http://www.viewtool.com</a></center>
- *<center>All Rights Reserved</center></h3>
- *
- ******************************************************************************
- */
- /* Define to prevent recursive inclusion -------------------------------------*/
- #ifndef __SPI_H
- #define __SPI_H
- /* Includes ------------------------------------------------------------------*/
- #include "sys.h"
- #include "pin_mux.h"
- #include "fsl_spi.h"
- #include "fsl_gpio.h"
- #define W5500_CS_GPIO BOARD_INITPINS_SPI1_SSEL0_GPIO /*!<@brief GPIO peripheral base pointer */
- #define W5500_CS_GPIO_PIN_MASK BOARD_INITPINS_SPI1_SSEL0_GPIO_PIN_MASK /*!<@brief GPIO pin mask */
- #define W5500_CS_PORT BOARD_INITPINS_SPI1_SSEL0_PORT /*!<@brief PORT device index: 1 */
- #define W5500_CS_PIN BOARD_INITPINS_SPI1_SSEL0_PIN /*!<@brief PORT pin number */
- #define W5500_CS_PIN_MASK BOARD_INITPINS_SPI1_SSEL0_PIN_MASK /*!<@brief PORT pin mask */
-
- /////具体引脚控制定义
- #define W5500_CS_H() GPIO_PortSet(W5500_CS_GPIO, W5500_CS_PORT,1U << W5500_CS_PIN)
- #define W5500_CS_L() GPIO_PortClear(W5500_CS_GPIO, W5500_CS_PORT,1U << W5500_CS_PIN)
- /* Exported Functions --------------------------------------------------------*/
- void SPI_Configuration(void);
- void SPI_WriteByte(uint8_t TxData);
- uint8_t SPI_ReadByte(void);
- void SPI_CrisEnter(void);
- void SPI_CrisExit(void);
- void SPI_CS_Select(void);
- void SPI_CS_Deselect(void);
- #endif /* __SPI_H */
- /*********************************END OF FILE**********************************/
复制代码
spi.c
- /* Includes ------------------------------------------------------------------*/
- #include "spi.h"
- #include "peripherals.h"
- /* Private typedef -----------------------------------------------------------*/
- /* Private define ------------------------------------------------------------*/
- /* Private macro -------------------------------------------------------------*/
- /* Private variables ---------------------------------------------------------*/
- /* Private function prototypes -----------------------------------------------*/
- /* Private functions ---------------------------------------------------------*/
- /**
- * @brief 根据外部SPI设备配置SPI相关参数
- * @retval None
- */
- void SPI_Configuration(void)
- {
- const spi_master_config_t SPI1_config = {
- .baudRate_Bps = 500000UL,
- .clockPolarity = kSPI_ClockPolarityActiveHigh,
- .clockPhase = kSPI_ClockPhaseFirstEdge,
- .direction = kSPI_MsbFirst,
- .dataWidth = 7,
- .sselNumber = kSPI_Ssel0Assert,
- .sselPolarity = kSPI_SpolActiveAllLow,
- .enableLoopback = false,
- .enableMaster = true,
- .delayConfig = {
- .preDelay = 0U,
- .postDelay = 0U,
- .frameDelay = 0U,
- .transferDelay = 0U
- }
- };
- /* Initialization function */
- SPI_MasterInit(SPI1_PERIPHERAL, &SPI1_config, SPI1_CLOCK_SOURCE);
-
- }
- //SPI读写一个字节
- u8 spi1_write_read_byte(u8 writedata)
- {
- u8 readdata=0;
- //等待发送成功
- while ((SPI1->STAT & SPI_STAT_TXRDY_MASK) == 0U)
- {
-
- }
- SPI1->TXDAT = ((uint32_t)writedata & 0x0000FFFFU);
-
- while ((SPI1->STAT & SPI_STAT_RXRDY_MASK) == 0U)
- {
- }
- readdata = SPI1->RXDAT;
-
- return readdata;
- }
- /**
- * @brief 写1字节数据到SPI总线
- * @param TxData 写到总线的数据
- * @retval None
- */
- void SPI_WriteByte(uint8_t TxData)
- {
- spi1_write_read_byte(TxData);
- }
- /**
- * @brief 从SPI总线读取1字节数据
- * @retval 读到的数据
- */
- uint8_t SPI_ReadByte(void)
- {
- return spi1_write_read_byte(0XFF);
- }
- /**
- * @brief 进入临界区
- * @retval None
- */
- void SPI_CrisEnter(void)
- {
- __set_PRIMASK(1);
- }
- /**
- * @brief 退出临界区
- * @retval None
- */
- void SPI_CrisExit(void)
- {
- __set_PRIMASK(0);
- }
- /**
- * @brief 片选信号输出低电平
- * @retval None
- */
- void SPI_CS_Select(void)
- {
- W5500_CS_L();
- }
- /**
- * @brief 片选信号输出高电平
- * @retval None
- */
- void SPI_CS_Deselect(void)
- {
- W5500_CS_H();
- }
- /*********************************END OF FILE**********************************/
复制代码 中间层及应用层代码无需改变(蓝框内),直接调用。
在main函数里面写测试代码:
main.c
- /*
- * Copyright (c) 2015, Freescale Semiconductor, Inc.
- * Copyright 2016-2019 NXP
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #include "pin_mux.h"
- #include "board.h"
- #include "peripherals.h"
- //#include "fsl_debug_console.h"
- #include "fsl_gpio.h"
- #include "stdio.h"
- #include "sys.h"
- #include "delay.h"
- #include "led.h"
- #include "key.h"
- #include "usart.h"
- #include "ctime.h"
- #include "usart1.h"
- #include "sctime.h"
- //#include "tmt.h"
- //#include "hc05.h"
- //#include "lcd_init.h"
- //#include "lcd.h"
- //#include "pic.h"
- #include "spi.h"
- #include "socket.h" // Just include one header for WIZCHIP
- /*******************************************************************************
- * Prototypes
- ******************************************************************************/
- #define SOCK_TCPS 0
- #define SOCK_UDPS 1
- #define DATA_BUF_SIZE 2048
- /*******************************************************************************
- * Variables
- ******************************************************************************/
- uint8_t gDATABUF[DATA_BUF_SIZE];
- // Default Network Configuration
- wiz_NetInfo gWIZNETINFO = { .mac = {0x00, 0x08, 0xdc,0x00, 0xab, 0xcd},
- .ip = {192, 168, 0, 123},
- .sn = {255,255,255,0},
- .gw = {192, 168, 0, 1},
- .dns = {0,0,0,0},
- .dhcp = NETINFO_STATIC };
- /*******************************************************************************
- * Code
- ******************************************************************************/
- void platform_init(void); // initialize the dependent host peripheral
- void network_init(void); // Initialize Network information and display it
- int32_t loopback_tcps(uint8_t, uint8_t*, uint16_t); // Loopback TCP server
- int32_t loopback_udps(uint8_t, uint8_t*, uint16_t); // Loopback UDP server
- /*!
- * @brief Main function
- */
- int main(void)
- {
- u8 key = 0,flg=0;
- u16 t;
- u16 len;
- u16 times=0;
- float m=0;
- u8 sendmask=0;
- u8 sendcnt=0;
- u8 sendbuf[20];
- u8 reclen=0;
-
- uint8_t tmp;
- int32_t ret = 0;
- uint8_t memsize[2][8] = {{2,2,2,2,2,2,2,2},{2,2,2,2,2,2,2,2}};
- /* Board pin, clock, debug console init */
- /* Select the main clock as source clock of USART0 (debug console) */
- CLOCK_Select(BOARD_DEBUG_USART_CLK_ATTACH);
- BOARD_InitBootPins();
- BOARD_InitBootClocks();
- BOARD_InitBootPeripherals();
- //Host dependent peripheral initialized
- platform_init();
- // First of all, Should register SPI callback functions implemented by user for accessing WIZCHIP
- /* Critical section callback */
- reg_wizchip_cris_cbfunc(SPI_CrisEnter, SPI_CrisExit); //注册临界区函数
- /* Chip selection call back */
- #if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_
- reg_wizchip_cs_cbfunc(SPI_CS_Select, SPI_CS_Deselect);//注册SPI片选信号函数
- #elif _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_
- reg_wizchip_cs_cbfunc(SPI_CS_Select, SPI_CS_Deselect); // CS must be tried with LOW.
- #else
- #if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SIP_) != _WIZCHIP_IO_MODE_SIP_
- #error "Unknown _WIZCHIP_IO_MODE_"
- #else
- reg_wizchip_cs_cbfunc(wizchip_select, wizchip_deselect);
- #endif
- #endif
- /* SPI Read & Write callback function */
- reg_wizchip_spi_cbfunc(SPI_ReadByte, SPI_WriteByte); //注册读写函数
- /* WIZCHIP SOCKET Buffer initialize */
- if(ctlwizchip(CW_INIT_WIZCHIP,(void*)memsize) == -1){
- printf("WIZCHIP Initialized fail.\r\n");
- while(1);
- }
- /* PHY link status check */
- do{
- if(ctlwizchip(CW_GET_PHYLINK, (void*)&tmp) == -1){
- printf("Unknown PHY Link stauts.\r\n");
- }
- }while(tmp == PHY_LINK_OFF);
- /* Network initialization */
- network_init();
- /*******************************/
- /* WIZnet W5500 Code Examples */
- /* TCPS/UDPS Loopback test */
- /*******************************/
- /* Main loop */
- while(1)
- {
- /* Loopback Test */
- // TCP server loopback test
- if( (ret = loopback_tcps(SOCK_TCPS, gDATABUF, 5000)) < 0) {
- printf("SOCKET ERROR : %ld\r\n", ret);
- }
- // UDP server loopback test
- if( (ret = loopback_udps(SOCK_UDPS, gDATABUF, 3000)) < 0) {
- printf("SOCKET ERROR : %ld\r\n", ret);
- }
- } // end of Main loop
- }// end of main()
- /**
- * @brief Intialize the network information to be used in WIZCHIP
- * @retval None
- */
- void network_init(void)
- {
- uint8_t tmpstr[6];
- ctlnetwork(CN_SET_NETINFO, (void*)&gWIZNETINFO);
- ctlnetwork(CN_GET_NETINFO, (void*)&gWIZNETINFO);
- // Display Network Information
- ctlwizchip(CW_GET_ID,(void*)tmpstr);
- printf("\r\n=== %s NET CONF ===\r\n",(char*)tmpstr);
- printf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n",gWIZNETINFO.mac[0],gWIZNETINFO.mac[1],gWIZNETINFO.mac[2],
- gWIZNETINFO.mac[3],gWIZNETINFO.mac[4],gWIZNETINFO.mac[5]);
- printf("SIP: %d.%d.%d.%d\r\n", gWIZNETINFO.ip[0],gWIZNETINFO.ip[1],gWIZNETINFO.ip[2],gWIZNETINFO.ip[3]);
- printf("GAR: %d.%d.%d.%d\r\n", gWIZNETINFO.gw[0],gWIZNETINFO.gw[1],gWIZNETINFO.gw[2],gWIZNETINFO.gw[3]);
- printf("SUB: %d.%d.%d.%d\r\n", gWIZNETINFO.sn[0],gWIZNETINFO.sn[1],gWIZNETINFO.sn[2],gWIZNETINFO.sn[3]);
- printf("DNS: %d.%d.%d.%d\r\n", gWIZNETINFO.dns[0],gWIZNETINFO.dns[1],gWIZNETINFO.dns[2],gWIZNETINFO.dns[3]);
- printf("======================\r\n");
- }
- /**
- * @brief Loopback Test Example Code using ioLibrary_BSD
- * @retval None
- */
- int32_t loopback_tcps(uint8_t sn, uint8_t* buf, uint16_t port)
- {
- int32_t ret;
- uint16_t size = 0, sentsize=0;
- switch(getSn_SR(sn))
- {
- case SOCK_ESTABLISHED :
- if(getSn_IR(sn) & Sn_IR_CON)
- {
- printf("%d:Connected\r\n",sn);
- setSn_IR(sn,Sn_IR_CON);
- }
- if((size = getSn_RX_RSR(sn)) > 0)
- {
- if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
- ret = recv(sn,buf,size);
- if(ret <= 0) return ret;
- sentsize = 0;
- while(size != sentsize)
- {
- ret = send(sn,buf+sentsize,size-sentsize);
- if(ret < 0)
- {
- close(sn);
- return ret;
- }
- sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
- }
- }
- break;
- case SOCK_CLOSE_WAIT :
- printf("%d:CloseWait\r\n",sn);
- if((ret=disconnect(sn)) != SOCK_OK) return ret;
- printf("%d:Closed\r\n",sn);
- break;
- case SOCK_INIT :
- printf("%d:Listen, port [%d]\r\n",sn, port);
- if( (ret = listen(sn)) != SOCK_OK) return ret;
- break;
- case SOCK_CLOSED:
- printf("%d:LBTStart\r\n",sn);
- if((ret=socket(sn,Sn_MR_TCP,port,0x00)) != sn)
- return ret;
- printf("%d:Opened\r\n",sn);
- break;
- default:
- break;
- }
- return 1;
- }
- /**
- * @brief Loopback Test Example Code using ioLibrary_BSD
- * @retval None
- */
- int32_t loopback_udps(uint8_t sn, uint8_t* buf, uint16_t port)
- {
- int32_t ret;
- uint16_t size, sentsize;
- uint8_t destip[4];
- uint16_t destport;
- //uint8_t packinfo = 0;
- switch(getSn_SR(sn))
- {
- case SOCK_UDP :
- if((size = getSn_RX_RSR(sn)) > 0)
- {
- if(size > DATA_BUF_SIZE) size = DATA_BUF_SIZE;
- ret = recvfrom(sn,buf,size,destip,(uint16_t*)&destport);
- if(ret <= 0)
- {
- printf("%d: recvfrom error. %ld\r\n",sn,ret);
- return ret;
- }
- size = (uint16_t) ret;
- sentsize = 0;
- while(sentsize != size)
- {
- ret = sendto(sn,buf+sentsize,size-sentsize,destip,destport);
- if(ret < 0)
- {
- printf("%d: sendto error. %ld\r\n",sn,ret);
- return ret;
- }
- sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero.
- }
- }
- break;
- case SOCK_CLOSED:
- printf("%d:LBUStart\r\n",sn);
- if((ret=socket(sn,Sn_MR_UDP,port,0x00)) != sn)
- return ret;
- printf("%d:Opened, port [%d]\r\n",sn, port);
- break;
- default :
- break;
- }
- return 1;
- }
- /**
- * @brief Loopback Test Example Code using ioLibrary_BSD
- * @retval None
- */
- void platform_init(void)
- {
- delay_init();
- LED_Init();
- KEY_Init();
- printf("\x0c");printf("\x0c");//超级终端清屏
- printf("\033[1;40;32m");//设置超级终端背景为黑色,字符为绿色
- printf("\r\n*******************************************************************************");
- printf("\r\n************************ Copyright 2009-2014, EmbedNet ************************");
- printf("\r\n*************************** http://www.embed-net.com **************************");
- printf("\r\n***************************** All Rights Reserved *****************************");
- printf("\r\n*******************************************************************************");
- printf("\r\n");
- //Config SPI
- SPI_Configuration();
- //延时初始化
- delay_init();
- }
复制代码 编译下载,将网线和电脑连接好,复位后我们进行连接查看:
串口输出配置信息:
当前W5500IP地址为192.168.0.123 ,我们设置连接的电脑的IP地址与其在同一个网段(选择局域网属性,选择IPV4属性,
地址改为192.168.0.x,这了我们设置为192.168.0.1。这了就不截图演示了):
打开命令,发送ping指令,发现连接正常:
打开网络调试助手,输入正确的远程地址及端号,连接好后,发送一句语句,W5500接受到后,会发回收到的语句。
好了,简单的LPC845+W5500 TCP测试就到这了。谢谢观看~
W5500数据手册中文版:
W5500_DS_v100e_CN.pdf
(1.35 MB, 下载次数: 6)
|
|