韦德斯 2024-05-31 16:10 采纳率: 42.9%
浏览 8
已结题

Linux C语言进行正确的串口数据读写

我使用LORA模块通过串口给测试模块发送JSON数据,将LORA模块接上串口助手,发送数据为{"frame":"LunxunData","code":2005,"SN":"2405NT00100"},测试模块就会给我的LORA模块返回数据,证明它已经收到数据。但是将LORA模块接到开发板上,自己在lvgl上写的程序进行发送测试数据,数据应该有发送出去,但是不知道是不是发送正确的,没有收到测试模块返回的数据,请问这是什么原因,我猜想有可能数据是被拆成几个小包发送出去的
以下是我的串口代码:

#define PORT "/dev/ttyS2" // 假定串口设备路径
#define BAUDRATE B115200
int serial_port;
//初始化串口函数
void init_serial(void) 
{
    serial_port = open(PORT, O_RDWR | O_NOCTTY | O_NDELAY);
    if (serial_port == -1) 
    {
        perror("Error opening serial port");
        return;
    }
    
    struct termios options;
    tcgetattr(serial_port, &options);
    cfsetispeed(&options, BAUDRATE);
    cfsetospeed(&options, BAUDRATE);
    options.c_cflag &= ~PARENB; // 无奇偶校验
    options.c_cflag &= ~CSTOPB; // 1停止位
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;     // 8位数据
    options.c_cflag &= ~CRTSCTS; // 无硬件流控
    options.c_iflag &= ~(IXON | IXOFF | IXANY); // 禁用软件流控
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // 非规范模式
    options.c_oflag &= ~OPOST;
    tcflush(serial_port, TCIFLUSH);
    tcsetattr(serial_port, TCSANOW, &options);
}
//读串口函数
void read_from_serial(void) 
{
    char buffer[256] = {0};
    ssize_t bytes_read = read(serial_port, buffer, sizeof(buffer) - 1);
    if (bytes_read > 0) 
    {
        buffer[bytes_read] = '\0';
        printf("%s",buffer);
    }
}
//写串口函数void send_data_to_ubuntu(const char *data) 
{
    write(serial_port, data, strlen(data));         
}
//打包测试数据函数
void write_data_w(void)
{
    char start_json_buffer[1024]; 
    snprintf(start_json_buffer, sizeof(start_json_buffer),  
                                        "{\"frame\":\"LunxunData\",\"code\":2005,\"SN\":\"2405NT00100\"}\n"); 
    send_data_to_ubuntu(start_json_buffer);

    lv_obj_set_style_bg_color(windows[0][0],lv_color_hex(0xff0000),LV_PART_MAIN);
}
//主函数
int main(void)
{
  init_serial();
   write_data_w();

    /*Handle LitlevGL tasks (tickless mode)*/
    while(1) {
        lv_timer_handler();
        read_from_serial();
        usleep(5000);
}
  • 写回答

2条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-05-31 16:10
    关注

    引自免费微信小程序:皆我百晓生

    从您提供的代码来看,您的串口初始化、读取和写入逻辑看起来基本正确。不过,有几个可能的问题点需要注意,我会逐一列出并提供相应的建议。

    1. 确认波特率: 确保您的开发板和测试模块都使用了相同的波特率(这里是115200)。如果它们不匹配,可能会导致接收方无法正确解析数据。

    2. 检查校验位和停止位: 您的代码中使用了8N1(8位数据,无奇偶校验,1个停止位)设置。请确保测试模块也支持这个配置。

    3. 同步字符和帧间隔: 如果LORA模块或测试模块对数据包的开始和结束有特定的标记,例如起始和终止同步字符,您需要添加这些标记到您的数据包中,并确保接收方能识别它们。

    4. 超时处理: 在发送数据后,您可以设置一个超时等待接收数据的机制。如果没有在预设时间内接收到响应,可以重试发送或考虑数据是否已正确发送。

    5. 数据长度限制: 确保接收缓冲区足够大以容纳可能接收到的最大数据包。您的read_from_serial()函数中的缓冲区大小为256字节,这可能不足以存储整个数据包。

    6. 错误检测与处理: 添加适当的错误检测和处理机制,例如检查文件描述符打开、关闭和读写操作的返回值。

    7. 日志记录: 在关键步骤增加日志输出,以便更好地了解数据发送和接收的过程。例如,在发送数据前记录发送内容,在接收数据后打印接收到的内容。

    针对以上建议,修改后的代码示例:

    #include <stdio.h>
    #include <unistd.h>
    #include <termios.h>
    #include <fcntl.h>
    #include <string.h>
    
    #define PORT "/dev/ttyS2"
    #define BAUDRATE B115200
    #define BUFFER_SIZE 1024
    #define TIMEOUT_MS 1000 // 设置超时时间
    
    int serial_port;
    
    void init_serial(void) 
    {
        serial_port = open(PORT, O_RDWR | O_NOCTTY | O_NDELAY);
        if (serial_port == -1) 
        {
            perror("Error opening serial port");
            exit(EXIT_FAILURE);
        }
    
        struct termios options;
        tcgetattr(serial_port, &options);
        cfsetispeed(&options, BAUDRATE);
        cfsetospeed(&options, BAUDRATE);
        options.c_cflag &= ~PARENB; // 无奇偶校验
        options.c_cflag &= ~CSTOPB; // 1停止位
        options.c_cflag &= ~CSIZE;
        options.c_cflag |= CS8;     // 8位数据
        options.c_cflag &= ~CRTSCTS; // 无硬件流控
        options.c_iflag &= ~(IXON | IXOFF | IXANY); // 禁用软件流控
        options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // 非规范模式
        options.c_oflag &= ~OPOST;
        tcflush(serial_port, TCIFLUSH);
        tcsetattr(serial_port, TCSANOW, &options);
    }
    
    void read_from_serial(char* received_data, size_t max_length) 
    {
        ssize_t bytes_read = read(serial_port, received_data, max_length - 1);
        if (bytes_read > 0) 
        {
            received_data[bytes_read] = '\0';
            printf("Received: %s\n", received_data);
        }
    }
    
    void send_data_to_ubuntu(const char *data) 
    {
        printf("Sending: %s\n", data);
        int sent_bytes = write(serial_port, data, strlen(data));
        if (sent_bytes != strlen(data)) 
        {
            perror("Error writing to serial port");
            exit(EXIT_FAILURE);
        }
    }
    
    void write_data_w(void)
    {
        char start_json_buffer[BUFFER_SIZE];
        snprintf(start_json_buffer, sizeof(start_json_buffer),  
                                            "{\"frame\":\"LunxunData\",\"code\":2005,\"SN\":\"2405NT00100\"}\n"); 
    
        send_data_to_ubuntu(start_json_buffer);
        lv_obj_set_style_bg_color(windows[0][0],lv_color_hex(0xff0000),LV_PART_MAIN);
    }
    
    int main(void)
    {
        init_serial();
        write_data_w();
    
        while(1) {
            char received_data[BUFFER_SIZE] = {0};
            struct timespec timeout = {0, TIMEOUT_MS * 1000000}; // 转换毫秒为微妙
            nanosleep(&timeout, NULL);
            
            read_from_serial(received_data, BUFFER_SIZE);
            if (received_data[0]) 
            {
                // 处理接收到的数据...
            }
        }
    }
    

    这里,我做了以下改动:

    • 添加了错误处理和日志记录。
    • 将接收缓冲区扩大到BUFFER_SIZE,以适应更大的数据包。
    • 添加了一个简单的超时处理机制,等待一段时间后尝试读取数据。

    如果问题仍然存在,您可能需要检查您的LORA模块和测试模块之间的连接以及它们的设置。另外,使用串口调试工具(如minicom或screen)进行交互式测试,有助于确定问题所在。如果问题依然无法解决,可能需要查看LORA模块和测试模块的文档,或者查阅相关社区论坛寻求帮助。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 6月6日
  • 已采纳回答 6月6日
  • 创建了问题 5月31日

悬赏问题

  • ¥15 Coze智能助手搭建过程中的问题请教
  • ¥15 12864只亮屏 不显示汉字
  • ¥20 三极管1000倍放大电路
  • ¥15 vscode报错如何解决
  • ¥15 前端vue CryptoJS Aes CBC加密后端java解密
  • ¥15 python随机森林对两个excel表格读取,shap报错
  • ¥15 基于STM32心率血氧监测(OLED显示)相关代码运行成功后烧录成功OLED显示屏不显示的原因是什么
  • ¥100 X轴为分离变量(因子变量),如何控制X轴每个分类变量的长度。
  • ¥30 求给定范围的全体素数p的(p-2)/p的连乘积值
  • ¥15 VFP如何使用阿里TTS实现文字转语音?