MyCollege1999 2025-11-27 18:52 采纳率: 65.8%
浏览 5
已结题

c程序读不到单片机发的UART1串口消息

调试中发现一个问题,python和c程序都会打开一个串口设备/dev/ttyAMA1, 这个设备是通过UART1和单片机通信的。当单片机发一个字符串比如bt时,python程序能读到,但是c程序却read阻塞了(正常情况下期望c程序了也读到单片机发的消息),这个是什么情况?

  • 写回答

3条回答 默认 最新

  • 紫雾凌寒 新星创作者: 人工智能技术领域 2025-11-27 18:58
    关注

    让 “紫雾凌寒” 来帮你回答,本回答结合 DeepSeek

    如果还有问题,请评论或点击头像私信,如果有帮助到您, 请关注、采纳、点赞

    1. 关键点分析:
      - 两个程序都打开了相同的串口设备 /dev/ttyAMA1
      - Python程序能正常读取到单片机发送的字符串“bt”,而C程序读取失败。这可能涉及到C程序中串口读取的具体实现问题,比如读取函数的使用、缓冲区设置、读取时机等。
    2. 解决方案:
      - 以下是一个简单的C语言示例,使用POSIX函数来读取串口数据:
    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <termios.h>
    
    #define BAUDRATE B9600
    #define MODEMDEVICE "/dev/ttyAMA1"
    #define _POSIX_SOURCE 1 /* POSIX compliant source */
    #define FALSE 0
    #define TRUE 1
    
    volatile int STOP=FALSE;
    
    int main()
    {
        int fd,c, res;
        struct termios oldtio, newtio;
        char buf[255];
    
        // 打开串口设备
        fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
        if (fd <0) {perror(MODEMDEVICE); exit(-1); }
    
        // 获取当前串口设置
        if (tcgetattr(fd,&oldtio)==-1) { /* save current port settings */
            perror("tcgetattr");
            exit(-1);
        }
    
        bzero(&newtio, sizeof(newtio));
        newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
        newtio.c_iflag = IGNPAR;
        newtio.c_oflag = OPOST;
    
        // 设置超时读取
        newtio.c_cc[VTIME]=0;
        newtio.c_cc[VMIN]=1;
    
        // 激活新配置
        if (tcsetattr(fd,TCSANOW,&newtio)==-1) {
            perror("tcsetattr");
            exit(-1);
        }
    
        while(1) {
            // 读取串口数据
            res = read(fd, buf, sizeof(buf));
            if (res > 0) {
                printf("Received: %s\n", buf);
            } else if (res < 0) {
                perror("read error");
            }
        }
    
        // 恢复旧配置
        if (tcsetattr(fd,TCSANOW,&oldtio)==-1) {
            perror("tcsetattr");
            exit(-1);
        }
    
        close(fd);
        return 0;
    }
    
    • 检查要点:
      • 确保串口设备权限正确,一般需要有相应的读权限。
      • 确认单片机发送数据的格式和波特率等设置与C程序中一致。
      • 注意读取函数的返回值,res 小于0表示读取出错,需要检查错误原因。
        3. 不同解决方案优缺点:
    • 上述使用POSIX函数的方案:
      • 优点:
      • 跨平台性较好,在类Unix系统上都能使用。
      • 直接使用系统提供的底层函数,对串口操作较为灵活。
      • 缺点:
      • 代码相对复杂,需要了解一些底层的串口设置知识。
      • 对于一些初学者来说,理解起来可能有一定难度。
    • 另一种方案是使用第三方库,如 libserialport
      • 优点:
      • 提供了更简洁的接口,代码量可能会减少。
      • 封装了底层操作,使用起来更方便。
      • 缺点:
      • 依赖该库的安装和配置,如果系统中没有安装,需要先进行安装。
      • 可能存在兼容性问题,不同版本的库在不同系统上表现可能不同。
        4. 总结:C程序读不到单片机通过UART1串口发送的消息,可能是由于串口读取实现不正确。通过上述代码示例展示了一种基本的串口读取方法,同时分析了不同解决方案的优缺点。在实际调试中,需要仔细检查串口设置、读取函数调用以及设备权限等方面,以确保C程序能够正确读取串口数据。

    希望以上解答对您有所帮助。如果您有任何疑问,欢迎在评论区提出。

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

报告相同问题?

问题事件

  • 系统已结题 1月7日
  • 已采纳回答 12月30日
  • 创建了问题 11月27日