当前位置: 首页 > ops >正文

STM32+w5500+TcpClient学习笔记

文章目录

      • 参考文章
      • 本地和远程IP连接的配置(重点)
      • TCP发送

参考文章

注意: SPI的CS RST脚这些都是通过cubeMX自定义的可以自行修改。用的是SPI1
项目地址

//MyTcpClient.h
#ifndef MYTCPCLIENT_H
#define MYTCPCLIENT_H
#include "main.h"
#include "w5500.h"
#include "socket.h"
#include "wizchip_conf.h"
#include "spi.h"
#include <string.h>  // memcmp
#define SOCK_TCPS  0
extern  uint8_t buff[128];   //定义缓冲区   
extern uint8_t TCP_send_buff[128];   //定义UDP发送缓冲区                                            
extern uint8_t remote_ip[4]; //远程IP地址
extern uint16_t remote_port; //远程端口号void TcpClientInit(void);
void do_tcp_client(void);
void Analysis(uint8_t *buf);
#endif // MYTCPCLIENT_H
//MyTcpClient.c
#include "MyTcpClient.h"
#include "main.h"
#include "w5500.h"
#include "socket.h"
#include "wizchip_conf.h"
#include "spi.h"
#include <string.h>  // memcmpuint8_t buff[128];  
uint8_t TCP_send_buff[128]; 
//需配置                                                    
uint8_t remote_ip[4] = {192, 168, 6, 151}; //远程IP地址
uint16_t remote_port = 8080; //远程端口号//片选
void W5500_Select(void) {HAL_GPIO_WritePin(W5500_CS_GPIO_Port, W5500_CS_Pin, GPIO_PIN_RESET);
}
void W5500_Unselect(void) {HAL_GPIO_WritePin(W5500_CS_GPIO_Port, W5500_CS_Pin, GPIO_PIN_SET);
}
void W5500_Restart(void) {HAL_GPIO_WritePin(W5500_RST_GPIO_Port, W5500_RST_Pin, GPIO_PIN_RESET);HAL_Delay(1);  // delay 1msHAL_GPIO_WritePin(W5500_RST_GPIO_Port, W5500_RST_Pin, GPIO_PIN_SET);HAL_Delay(1600);  // delay 1600ms
}void W5500_ReadBuff(uint8_t* buff, uint16_t len) {HAL_SPI_Receive(&hspi1, buff, len, HAL_MAX_DELAY);
}void W5500_WriteBuff(uint8_t* buff, uint16_t len) {HAL_SPI_Transmit(&hspi1, buff, len, HAL_MAX_DELAY);
}uint8_t W5500_ReadByte(void) {uint8_t byte;W5500_ReadBuff(&byte, sizeof(byte));return byte;
}void W5500_WriteByte(uint8_t byte) {W5500_WriteBuff(&byte, sizeof(byte));
}//配置W5500网络信息(需配置)
wiz_NetInfo gSetNetInfo = {.mac  = {0x00, 0x08, 0xdc, 0x11, 0x11, 0x11},.ip   = {192, 168, 6, 15},.sn   = {255, 255, 255, 0},.gw   = {192, 168, 6, 1},.dns  = {8,8,8,8},.dhcp = NETINFO_STATIC};wiz_NetInfo gGetNetInfo;enum Status
{Failed = 0,Success = 1
};/*** @brief valid the result of set net info* @return 1: Success*         0: Failed
*/
uint8_t validSetNetInfoResult(wiz_NetInfo* _set, wiz_NetInfo* _get)
{return (!memcmp(_set, _get, sizeof(wiz_NetInfo)));  // if same, memcmp return 0
}//进入临界区
void SPI_CrisEnter(void)
{__set_PRIMASK(1);
}
//退出临界区
void SPI_CrisExit(void)
{__set_PRIMASK(0);
}void SPI_CS_Select(void)
{HAL_GPIO_WritePin(W5500_CS_GPIO_Port, W5500_CS_Pin, GPIO_PIN_RESET);
}
void SPI_CS_Deselect(void)
{HAL_GPIO_WritePin(W5500_CS_GPIO_Port, W5500_CS_Pin, GPIO_PIN_SET);
}void TcpClientInit(void)
{reg_wizchip_cris_cbfunc(SPI_CrisEnter, SPI_CrisExit);	//注册临界区函数reg_wizchip_cs_cbfunc(W5500_Select, W5500_Unselect);reg_wizchip_spi_cbfunc(W5500_ReadByte, W5500_WriteByte);W5500_Restart();  // hardware restart through RESET pinctlnetwork(CN_SET_NETINFO, (void*)&gSetNetInfo);  // set net info// maybe need delayctlnetwork(CN_GET_NETINFO, (void*)&gGetNetInfo);  // get net info// W5500 has 8 channel, 32k buffer, 2 means 2KBytesuint8_t buffer_size_8channel_tx_rx[16] = {2, 2, 2, 2, 2, 2, 2, 2,  // 8 channel tx2, 2, 2, 2, 2, 2, 2, 2}; // 8 channel rxif(ctlwizchip(CW_INIT_WIZCHIP,(void*)buffer_size_8channel_tx_rx)){// failed}uint8_t sta = getSn_SR(SOCK_TCPS);if(sta == SOCK_CLOSED){socket(SOCK_TCPS, Sn_MR_TCP, 5001, 0x00);}HAL_Delay(100);}void do_tcp_client(void)
{uint16_t len=0;switch(getSn_SR(SOCK_TCPS))														// 获取socket0的状态{case SOCK_INIT:															// Socket处于初始化完成(打开)状态	connect(SOCK_TCPS,remote_ip,remote_port);break;case SOCK_ESTABLISHED:											// Socket处于连接建立状态if(getSn_IR(SOCK_TCPS) & Sn_IR_CON)   					{setSn_IR(SOCK_TCPS, Sn_IR_CON);								// Sn_IR的CON位置1,通知W5500连接已建立}// 数据回环测试程序:数据从上位机服务器发给W5500,W5500接收到数据后再回给服务器len=getSn_RX_RSR(SOCK_TCPS);										// len=Socket0接收缓存中已接收和保存的数据大小					if(len){recv(SOCK_TCPS,buff,len);		send(SOCK_TCPS,buff,len);							}											break;case SOCK_CLOSE_WAIT:												  // Socket处于等待关闭状态disconnect(SOCK_TCPS);	break;case SOCK_CLOSED:														// Socket处于关闭状态socket(SOCK_TCPS,Sn_MR_TCP,5001,0x00);		// 打开Socket0,打开一个本地端口break;}
}//分析数据
void Analysis(uint8_t *buf)
{}

主函数(我用的是freeRTOS以线程的方式)

//freertos.c
/* USER CODE BEGIN Includes */
#include "MyTcpClient.h" //添加头文件
/* USER CODE END Includes */
//freertos.c
void W5500_Task_TCP(void const * argument)
{/* USER CODE BEGIN W5500_Task_TCP */TcpClientInit();/* Infinite loop */for(;;){do_tcp_client();//osDelay(1);}/* USER CODE END W5500_Task_TCP */
}

大伙注意的是参考文章中没提到的

//MyTcpClient.c
//进入临界区
void SPI_CrisEnter(void)
{__set_PRIMASK(1);
}
//退出临界区
void SPI_CrisExit(void)
{__set_PRIMASK(0);
}

还有就是

本地和远程IP连接的配置(重点)

//配置W5500网络信息(需配置)
wiz_NetInfo gSetNetInfo = {.mac  = {0x00, 0x08, 0xdc, 0x11, 0x11, 0x11},.ip   = {192, 168, 6, 15},.sn   = {255, 255, 255, 0},.gw   = {192, 168, 6, 1},.dns  = {8,8,8,8},.dhcp = NETINFO_STATIC};

这些是w5500的配置和

//需配置                                                    
uint8_t remote_ip[4] = {192, 168, 6, 151}; //远程IP地址
uint16_t remote_port = 8080; //远程端口号

需要大伙额外注意

TCP发送

//MyTcpClient.c
void TCP_SendData(uint8_t *data, uint16_t len) {// 创建Socketsocket(SOCKET_ID, Sn_MR_TCP, local_port, 0); // 本地端口(local_port:5001)// 连接服务器//uint8_t dest_ip[4] = {192, 168, 6, 151}; // 服务器IPif (connect(SOCKET_ID, remote_ip, SERVER_PORT) != SOCK_OK) {// 连接失败处理return;}// 等待连接成功(可选)while(getSn_SR(SOCKET_ID) != SOCK_ESTABLISHED) {HAL_Delay(10);}// 发送数据send(SOCKET_ID, data, len);// 关闭Socket(非必需,可保持连接)disconnect(SOCKET_ID);close(SOCKET_ID);
}

应用线程函数

//freertos.c
/* USER CODE END Header_W5500_Task_01 */
//发送的数据体
uint8_t msg1[] = "Hello TCP Server!";
void W5500_Task_01(void const * argument)
{/* USER CODE BEGIN W5500_Task_01 */TcpClientInit();/* Infinite loop */for(;;){do_tcp_client();TCP_SendData(msg1,strlen((char*)msg1));osDelay(3000);}/* USER CODE END W5500_Task_01 */
}
http://www.xdnf.cn/news/15593.html

相关文章:

  • JAVA中StringBuilder类,StringJoiner类构造函数方法简单介绍
  • [2025CVPR-目标检测方向] CorrBEV:多视图3D物体检测
  • 基于 HT 的 3D 可视化智慧矿山开发实现
  • 短视频矩阵系统哪家好?全面解析与推荐
  • 无人机传感器模组运行与技术难点分析
  • 嵌入式数据结构之顺序表总结
  • 自学力扣:最长连续序列
  • 小结:Spring MVC 的 XML 的经典配置方式
  • 【每日算法】专题十三_队列 + 宽搜(bfs)
  • 详解Linux(Ubuntu/RedHat/CentOS)及国产服务器统一加域管理方案
  • 一款实用的.NET Core加密解密工具类库
  • 纯前端html实现图片坐标与尺寸(XY坐标及宽高)获取
  • 贴吧项目总结二
  • 神经网络常见激活函数 15-B-SiLU 函数
  • 如何在银河麒麟桌面系统中启用 sudo 密码的星号反馈
  • 数据结构排序算法总结(C语言实现)
  • Planning Agent:基于大模型的动态规划与ReAct机制,实现复杂问题自适应执行求解
  • 【软件测试】软件测试分类与方法解析:目标到工具
  • 【Dv3Admin】菜单管理集成阿里巴巴自定义矢量图标库
  • Linux手动安装Nginx(基于Centos 7)
  • 网络通信之基础知识
  • 项目的存量接口怎么低成本接入MCP?
  • 暑期算法训练.3
  • Android设备标识符详解:IMEI、ANDROID_ID与OAID
  • 针对教育行业的网络安全方案有哪些
  • 软件测试面试常见问题【含答案】
  • Effective Modern C++ 条款13:优先考虑const_iterator而非iterator
  • docker安装、启动jenkins服务,创建接口自动化定时任务(mac系统)
  • Python基础--嵌套循环
  • vuex的理解以及应用