TCP 的逻辑实现,可以和客户端连接发送数据
This commit is contained in:
135
README.md
135
README.md
@@ -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** 工具链进行编译。
|
||||
- 源文件采用 **UTF‑8 编码并包含中文注释**,`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`。
|
||||
|
||||
Reference in New Issue
Block a user