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. 测试流程
- 启用UART1引脚
- 编译代码:
gcc uart_test.c -o uart_test - 运行程序:
sudo ./uart_test - 查看hterm是否接收到数据
内容的提问来源于stack exchange,提问作者mmkaratokus
相关产品推荐
相关产品推荐

