上位机发送数据给下位机

本文详细描述了使用C++编写的上位机程序如何通过COM5与单片机进行串口通信,包括创建串口连接、设置参数、数据发送以及单片机接收和处理数据的过程,同时提及了使用HAL库中的函数操作UART接口。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.这里的上位机是c++语言写的

#include <iostream>
#include <Windows.h>

int main()
{
    HANDLE serialPort = CreateFile("COM5", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
    //尝试打开一个串行端口(COM5)来建立一个与该串行端口的连接
    if (serialPort == INVALID_HANDLE_VALUE) {
        std::cerr << "Error: Could not open serial port." << std::endl;
        return 1;
    }//判断是否打开了串口

    DCB dcbSerialParams = { 0 };
    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
    dcbSerialParams.BaudRate = CBR_9600; // 设置波特率
    dcbSerialParams.ByteSize = 8;
    dcbSerialParams.StopBits = ONESTOPBIT;
    dcbSerialParams.Parity = NOPARITY;

    SetCommState(serialPort, &dcbSerialParams);

    // 发送数据给单片机
    const char dataToSend[] = "okokok\r\n";
    DWORD bytesWritten;
    WriteFile(serialPort, dataToSend, sizeof(dataToSend), &bytesWritten, NULL);

    std::cout << "Data sent to MCU: " << dataToSend << std::endl;

    // 关闭串口
    CloseHandle(serialPort);

    return 0;
}

2.单片机接收串口打印的数据

下面的代码是hal库生成的while循环里的,由于上位机发送数据给下位机时占用串口5,所以延时5s打印,在这5s里需要尽快打开串口。

while (1)
{
		uint8_t data;
    uint16_t index = 0;

    /* 接收数据 */
    while (1)
			{
        if(HAL_UART_Receive(&huart1, &data, 1, HAL_MAX_DELAY) == HAL_OK) 
					{
            if (data == '\n' || data == '\r') 
							{ // 判断是否接收到换行符或回车符
                buffer[index] = '\0'; // 在字符串末尾加上结束符
                break; // 结束接收
							}
            else 
							{
                buffer[index] = data; // 将接收到的字符存入缓冲区
                index++;
							}
					}
			}
		HAL_Delay(3000); // 每隔1秒进行一次数据接收和处理
		HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);
    HAL_UART_Transmit(&huart1, (uint8_t *)"\r\n", 2, HAL_MAX_DELAY); // 打印回车换行
}

 

在同一界面下放上所有的按钮去控制,按钮间的逻辑关系有点复杂。即使做出来用户用着也会感觉有些别扭,据此我们干脆分成几个界面来做。(总控与退出按钮不要也行) 第一界面:楼体、环境、退出; 第二界面:楼体1、楼体2、返回、退出; 第三界面:户型A01---A04、B01---B04、返回、退出; 第四界面:户型2-01---2-04、返回、退出。 按钮1>>楼体, 按钮2>>环境; 按钮3>>楼体1, 按钮4>>楼体2, 按钮5>>返回; 按钮6---按钮13>>[A01---A04][B01---B04], 按钮14>>返回; 按钮15---按钮18>>[2-01---2-04],按钮19>>返回; (0-F路为16继电器输出) 程序动作如下: 第一界面: 1. 按钮1开-开[0]路>>弹出第二界面;按钮1关-关[0]。 2. 按钮2开-开[1]路,按钮2关-关[1]路。 第二界面: 1. 点击按钮3-开[2]路,>>弹出第三界面。 2. 点击按钮4-开[3]路,>>弹出第四界面。 3. 点击按钮5>>返回第一界面。 第三界面: 1. 按钮6开-开[4]路,按钮6关-关[4]路。 2. 按钮7开-开[5]路,按钮7关-关[5]路。 3. 按钮8开-开[6]路,按钮8关-关[6]路。 4. 按钮9开-开[7]路,按钮9关-关[7]路。 5. 按钮10开-开[8]路,按钮10关-关[8]路。 6. 按钮11开-开[9]路,按钮11关-关[9]路。 7. 按钮12开-开[A]路,按钮12关-关[A]路。 8. 按钮13开-开[B]路,按钮13关-关[B]路。 9. 点击按钮14-关[2][4-B]路>>返回第二界面。 第四界面: 1. 按钮15开-开[C]路,按钮15关-关[C]路。 2. 按钮16开-开[D]路,按钮16关-关[D]路。 3. 按钮17开-开[E]路,按钮17关-关[E]路。 4. 按钮18开-开[F]路,按钮18关-关[F]路。 9. 点击按钮19-关[3][C-F]路>>返回第二界面。
### Matlab 上位机下位的数据通信实现 #### 1. 使用串口通信 Matlab 支持通过 `serial` 对象建立与下位的连接。创建并配置串口对象时需指定端口号波特率等参数。 ```matlab s = serial('COM3'); % 创建串口对象,假设使用 COM3 端口 set(s,'BaudRate',9600); % 设置波特率为 9600 bps fopen(s); % 打开串口连接 ``` 向串口写入命令字符串或字节数组可发送指令给下位设备[^1]。 ```matlab fprintf(s, 'START\r\n'); % 发送启动命令至下位 fwrite(s,uint8([0x01 0x02])); % 或者直接发送十六进制数据流 ``` 接收来自下位返回的信息同样简单: ```matlab data = fscanf(s,'%c'); % 接收字符形式的数据 binaryData = fread(s,inf,'uint8'); % 获取原始二进制数据 fclose(s); % 关闭串口链接 delete(s); % 清除串口资源 clear s; ``` #### 2. 利用 UDP 进行网络传输 对于基于UDP协议的情况,则需要用到MATLAB中的udp类来进行编程操作[^2]。 ```matlab u = udp('localhost','LocalPort',5000); fopen(u); % 构造要发送的消息体 message = uint8(['Hello from MATLAB']); write(u,message); % 读取消息队列里的响应报文 response = read(u,length(message)); disp(char(response)); % 显示接收到的内容 fclose(u); delete(u); clear u; ``` #### 3. 自定义帧格式解析 针对特定应用场景下的自定义帧结构(如 ESP8266 WiFi 物联网智能插座),可以通过构建相应的结构体模板来处理复杂的数据交换过程[^3]。 ```matlab typeDef SendUpdataState struct { DeviceHead uint8; DeviceLen int16; DeviceId int16; SoftwareVersion string(15); HardwareVersion string(15); UpdataIp string(64); UpdataPort int16; Crc int16; }; function sendUpdateRequest(ipAddress,portNumber) packet = SendUpdataState(); packet.DeviceHead = hex2dec('A0'); packet.DeviceLen = size(packet)*sizeof(uint8()); packet.DeviceId = hex2dec('0001'); packet.SoftwareVersion= "SMART_SW_A1_1.0"; packet.HardwareVersion= "SMART_HW_A1_1.0"; packet.UpdataIp = ipAddress; packet.UpdataPort = portNumber; packet.Crc = calculateCRC(packet); end ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值