C语言上位机软件开发是指使用C语言编写运行在PC端的程序,实现与嵌入式设备、传感器等下位机的数据通信、状态监控、指令下发等功能,在工业控制、物联网、测试测量等领域应用广泛。

开发环境准备
Windows平台下进行C上位机开发,常用的工具组合是Visual Studio搭配Windows SDK,也可以选择轻量级的Code::Blocks。如果是开发带图形界面的上位机,还需要了解基础的GUI开发框架,比如Windows自带的Win32 API,或者第三方轻量库如GTK、Qt的C语言绑定版本。
以Visual Studio 2022为例,安装时勾选“使用C++的桌面开发” workload即可,该组件包含Windows SDK和C语言编译环境,无需额外配置就能编写Win32程序。
基础界面搭建(Win32 API示例)
Win32 API是Windows系统原生的界面开发接口,使用C语言可以直接调用,适合开发轻量级上位机界面。下面是一个最简单的窗口创建代码:
#include <windows.h>
// 窗口过程函数,处理窗口消息
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch (msg) {
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
const char CLASS_NAME[] = "CUpperMonitorClass";
// 注册窗口类
WNDCLASS wc = {0};
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
if (!RegisterClass(&wc)) {
MessageBox(NULL, "窗口类注册失败", "错误", MB_ICONERROR);
return 0;
}
// 创建窗口
HWND hwnd = CreateWindow(CLASS_NAME, "C语言上位机", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 800, 600,
NULL, NULL, hInstance, NULL);
if (hwnd == NULL) {
MessageBox(NULL, "窗口创建失败", "错误", MB_ICONERROR);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// 消息循环
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
核心功能:串口通信实现
串口是上位机与下位机通信最常用的方式之一,Windows下可以通过文件操作的方式访问串口设备。下面是串口打开、配置、数据收发的示例代码:
#include <windows.h>
#include <stdio.h>
// 打开串口
HANDLE open_serial_port(const char* port_name, int baud_rate) {
char full_name[20];
sprintf(full_name, "\\.\%s", port_name); // 端口名格式:COM3、COM4等
HANDLE hSerial = CreateFile(full_name, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hSerial == INVALID_HANDLE_VALUE) {
printf("打开串口 %s 失败n", port_name);
return INVALID_HANDLE_VALUE;
}
// 配置串口参数
DCB dcbSerialParams = {0};
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
if (!GetCommState(hSerial, &dcbSerialParams)) {
printf("获取串口状态失败n");
CloseHandle(hSerial);
return INVALID_HANDLE_VALUE;
}
dcbSerialParams.BaudRate = baud_rate;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
if (!SetCommState(hSerial, &dcbSerialParams)) {
printf("设置串口参数失败n");
CloseHandle(hSerial);
return INVALID_HANDLE_VALUE;
}
// 设置超时参数
COMMTIMEOUTS timeouts = {0};
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 50;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (!SetCommTimeouts(hSerial, &timeouts)) {
printf("设置串口超时失败n");
CloseHandle(hSerial);
return INVALID_HANDLE_VALUE;
}
return hSerial;
}
// 发送数据
int send_serial_data(HANDLE hSerial, const char* data, int len) {
DWORD bytes_written;
if (!WriteFile(hSerial, data, len, &bytes_written, NULL)) {
printf("发送数据失败n");
return -1;
}
return bytes_written;
}
// 接收数据
int recv_serial_data(HANDLE hSerial, char* buffer, int buffer_size) {
DWORD bytes_read;
if (!ReadFile(hSerial, buffer, buffer_size, &bytes_read, NULL)) {
printf("接收数据失败n");
return -1;
}
return bytes_read;
}
int main() {
HANDLE hSerial = open_serial_port("COM3", 9600);
if (hSerial == INVALID_HANDLE_VALUE) {
return 1;
}
// 发送测试数据
const char test_data[] = "Hello MCUn";
send_serial_data(hSerial, test_data, sizeof(test_data)-1);
// 接收数据
char recv_buf[1024];
int recv_len = recv_serial_data(hSerial, recv_buf, sizeof(recv_buf)-1);
if (recv_len > 0) {
recv_buf[recv_len] = ' ';
printf("接收到数据:%sn", recv_buf);
}
CloseHandle(hSerial);
return 0;
}
开发注意事项
- 串口操作属于系统资源调用,使用完成后一定要及时调用
CloseHandle释放资源,避免端口被占用。 - GUI程序的主线程不能阻塞,串口数据接收建议放在单独的线程中处理,避免界面卡顿。
- 数据解析时要注意大小端问题,下位机发送的多字节数据可能需要做字节序转换。
- 调试时可以先使用虚拟串口工具模拟下位机设备,验证通信逻辑正确后再连接真实硬件。
功能扩展方向
掌握基础界面和串口通信后,可以进一步扩展上位机功能,比如添加数据保存功能,将接收到的数据写入CSV或TXT文件;增加图表显示功能,使用第三方绘图库如Gnuplot的C接口实时绘制数据曲线;实现网络通信功能,通过TCP/IP协议与下位机或服务器交互,满足更复杂的应用场景需求。
C上位机开发串口通信GUI编程Windows_API修改时间:2026-07-20 17:15:36