You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BeagleBone Black Debian下UART通信C程序无输出求助

问题

我正在运行嵌入式Linux系统,是新手。我的BeagleBone安装了Debian发行版,想通过P9-24和P9-26引脚使用UART1实现UART通信,但运行编写的C程序后没有任何输出。已经将TTL转换器连接到上述引脚,用hterm监控串口,波特率设为9600,转换器本身正常,但连接引脚运行程序后看不到输出。附上使用的C代码,求协助解决。

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>

int open_uart(const char *port) {
    int uart_fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
    if (uart_fd == -1) {
        perror("Error opening UART");
        return -1;
    }

    struct termios options;
    tcgetattr(uart_fd, &options);
    options.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
    options.c_cflag &= ~PARENB;   // Parity disable
    options.c_cflag &= ~CSTOPB;   // 1 stop bit
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;       // 8 data bits
    options.c_iflag = IGNPAR;
    options.c_oflag = 0;
    options.c_lflag = 0;
    tcflush(uart_fd, TCIFLUSH);
    tcsetattr(uart_fd, TCSANOW, &options);

    return uart_fd;
}

void send_data(int uart_fd, const char *data) {
    write(uart_fd, data, strlen(data));
}

int main() {
    const char *uart_port = "/dev/ttyS0"; // Bu portun doğru olup olmadığını kontrol et
    int uart_fd = open_uart(uart_port);

    if (uart_fd != -1) {
        printf("açıldı");
        const char *data_to_send = "Muhammed";
        send_data(uart_fd, data_to_send);
        close(uart_fd); // İşiniz bittiğinde portu kapatmayı unutmayın
    }

    return 0;
}
排查与解决步骤

1. 确认UART设备节点正确性

BeagleBone的UART1对应设备节点通常是/dev/ttyO1,而非代码中的/dev/ttyS0(ttyS0一般是调试串口)。执行以下命令确认系统中的UART节点:

ls /dev/ttyO*

将代码中的uart_port修改为/dev/ttyO1。

2. 启用UART1引脚复用

BeagleBone引脚默认可能未分配给UART1,需手动启用:

  • 查看当前引脚状态:
cat /sys/kernel/debug/pinctrl/44e10800.pinmux/pins | grep -E "(P9_24|P9_26)"
  • 临时启用引脚(重启后失效):
echo 0 > /sys/devices/platform/ocp/ocp:P9_24_pinmux/state
echo 0 > /sys/devices/platform/ocp/ocp:P9_26_pinmux/state

若已安装config-pin工具,可执行更简洁的命令:

config-pin P9_24 uart
config-pin P9_26 uart

3. 修复串口访问权限

普通用户可能无UART设备访问权限,可通过两种方式解决:

  • 运行程序时加sudo:sudo ./uart_test
  • 将当前用户加入dialout组(需重新登录生效):
sudo usermod -aG dialout $USER

4. 优化串口配置代码

原代码存在配置冗余、无发送等待等问题,修改后的代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>

int open_uart(const char *port) {
    int uart_fd = open(port, O_RDWR | O_NOCTTY);
    if (uart_fd == -1) {
        perror("Error opening UART");
        return -1;
    }

    struct termios options;
    tcgetattr(uart_fd, &options);

    // 配置波特率
    cfsetispeed(&options, B9600);
    cfsetospeed(&options, B9600);
    // 配置数据位、停止位、校验位
    options.c_cflag &= ~PARENB;    // 无校验
    options.c_cflag &= ~CSTOPB;    // 1位停止位
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;        // 8位数据位
    options.c_cflag |= CLOCAL | CREAD; // 忽略调制解调器状态,允许读取输入

    // 禁用软件流控与特殊字符处理
    options.c_iflag = IGNPAR;
    options.c_oflag = 0;
    options.c_lflag = 0;

    // 刷新缓冲区并应用配置
    tcflush(uart_fd, TCIOFLUSH);
    if (tcsetattr(uart_fd, TCSANOW, &options) != 0) {
        perror("Error setting UART attributes");
        close(uart_fd);
        return -1;
    }

    return uart_fd;
}

void send_data(int uart_fd, const char *data) {
    ssize_t bytes_written = write(uart_fd, data, strlen(data));
    if (bytes_written == -1) {
        perror("Error writing to UART");
    } else {
        printf("Sent %zd bytes: %s\n", bytes_written, data);
    }
    // 等待数据发送完成再关闭串口
    tcdrain(uart_fd);
}

int main() {
    const char *uart_port = "/dev/ttyO1";
    int uart_fd = open_uart(uart_port);

    if (uart_fd != -1) {
        printf("UART opened successfully\n");
        const char *data_to_send = "Muhammed\n"; // 添加换行符方便终端查看
        send_data(uart_fd, data_to_send);
        close(uart_fd);
    }

    return 0;
}

修改说明:

  • 移除O_NDELAY标志,避免非阻塞模式导致写入异常
  • 使用cfsetispeed/cfsetospeed规范配置波特率
  • 添加tcdrain(uart_fd)确保数据发送完成后再关闭串口
  • 增加写入错误检查与发送反馈
  • 在发送数据中添加换行符,方便终端识别输出

5. 测试流程

  1. 启用UART1引脚
  2. 编译代码:gcc uart_test.c -o uart_test
  3. 运行程序:sudo ./uart_test
  4. 查看hterm是否接收到数据

内容的提问来源于stack exchange,提问作者mmkaratokus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 04:35:58