TCP 的逻辑实现,可以和客户端连接发送数据

This commit is contained in:
2026-03-04 10:29:20 +08:00
parent f32d91c424
commit f45b571162
16 changed files with 14027 additions and 2 deletions

135
README.md
View File

@@ -1,3 +1,134 @@
# DTU-HMI
# PC_HMI 本地 HMI 菜单逻辑的 PC 端模拟
PC 模拟 DTU 的人机交互逻辑
本目录提供一个 **纯 C 语言的控制台程序**,在 PC 模拟嵌入式 HMI 的菜单交互逻辑,方便调试和理解 `Menu_Route` / `Menu_Show_Proc` 的行为。
## 环境搭建
### 1. 安装 CMake
1. 访问 CMake 官网下载页:[`https://cmake.org/download/`](https://cmake.org/download/)
2. 下载适用于 Windows 的安装包(通常为 `cmake-*-windows-x86_64.msi`),安装时**勾选将 CMake 添加到 PATH**。
3. 安装完成后打开终端PowerShell / CMD执行
```powershell
cmake --version
```
能看到版本信息即表示安装成功。
### 2. 编译器与编码说明
- Windows 下默认使用 **Visual Studio / MSVC** 工具链进行编译。
- 源文件采用 **UTF8 编码并包含中文注释**`CMakeLists.txt` 中已经为 MSVC 打开 `/utf-8` 选项,无需额外配置即可正常编译。
## 目录结构
- `CMakeLists.txt` CMake 构建配置
- `include/menu.h` 菜单数据结构与接口声明
- `include/tcp.h` TCP 通信接口(客户端/服务端)
- `src/menu.c` 简单菜单树与菜单调度逻辑PC 版)
- `src/main.c` 主程序入口,从键盘读取按键并驱动菜单
- `src/tcp.c` TCP 实现Windows Winsock / Linux socket
## 构建步骤
### 1. Windows 示例(当前工程默认方式)
在仓库根目录下执行(注意路径中有空格时要加引号):
```powershell
mkdir build
cd "D:\Code\DTU 程序\DTU-HMI\build"
cmake ..
cmake --build .
```
### 2. 通用Linux / macOS 等)
```bash
mkdir build
cd build
cmake ../
cmake --build .
```
生成的可执行文件名为:
```text
pc_hmi # Windows / Linux 下均可
```
## 运行与按键映射
```bash
./pc_hmi
```
在控制台中使用以下按键进行菜单操作:
- `W` / `w` 上(对应嵌入式的 `CN_KEY_U`
- `S` / `s` 下(`CN_KEY_D`
- `A` / `a` 左(`CN_KEY_L`
- `D` / `d` 右(`CN_KEY_R`
- `Enter` 确认 / 进入子菜单(`CN_KEY_ENT`
- `Esc` 返回上一级(`CN_KEY_ESC`
界面中会用 `[*名称*]` 标出当前选中的菜单项,并在底部显示对应的提示信息。
> 注意:当前只是一个 **最小化演示环境**,菜单树结构与嵌入式工程中的 `g_tMenuModelTab` 不完全一致,但交互方式相仿,可作为移植和调试时的参考。
## TCP 通信
项目已集成 **跨平台 TCP 模块**`include/tcp.h` + `src/tcp.c`),可用于与设备或上位机进行 TCP 通信。
- **Windows**:使用 Winsock2已自动链接 `ws2_32`。
- **Linux**:使用 BSD socket无需额外库。
### 使用前初始化
程序入口已调用 `Tcp_Init()`,退出前会调用 `Tcp_Cleanup()`。若在其它线程或模块中使用 TCP无需重复初始化。
### TCP 客户端示例
```c
#include "../include/tcp.h"
/* 连接服务器 */
int sock = TcpClient_Connect("192.168.1.100", 502);
if (sock == TCP_INVALID_SOCKET) {
/* 连接失败 */
return;
}
/* 发送数据 */
const char *msg = "hello";
int sent = TcpClient_Send(sock, msg, strlen(msg));
/* 接收数据 */
char buf[256];
int n = TcpClient_Recv(sock, buf, sizeof(buf) - 1);
if (n > 0) {
buf[n] = '\0';
printf("recv: %s\n", buf);
}
/* 关闭连接 */
TcpClient_Close(sock);
```
### TCP 服务端示例
```c
int server = TcpServer_Listen(8080);
if (server == TCP_INVALID_SOCKET) return;
int client = TcpServer_Accept(server); /* 阻塞等待客户端 */
if (client != TCP_INVALID_SOCKET) {
TcpClient_Send(client, "welcome", 7);
TcpClient_Close(client);
}
TcpServer_Close(server);
```
接口说明见 `include/tcp.h`。