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

STM32 NUCLEO-F746ZG与BeagleBone Green UART通信故障排查求助

STM32 NUCLEO-F746ZG板卡测试

以下是用于测试Nucleo板卡PC_10、PC_11、PD_12、PD_2引脚间数据收发的代码片段,目前运行正常。

/*
  Pin PC_10 is configured as UART-TX (port CN8)
  Pin PC_11 is configured as UART-RX (port CN8)

  Pin PD_12 is configured as UART-TX (port CN7)
  Pin PD_2 is configured as UART-RX (port CN8)
 */
char msg[15] = "Hello World!";
char resc_msg;

HAL_StatusTypeDef status;

/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
    for (uint8_t i = 0; i < strlen(msg); ++i) {
        status = HAL_UART_Transmit(&huart4, (uint8_t*) (msg + i), 1, 1000);
        if (status != HAL_OK) {
            printf("UART_Receive failed with status: %d\r\n", status);
            printf("[err] could not transmit Uart tx\r\n");
        }
        HAL_Delay(100);
        status = HAL_UART_Receive(&huart5, (uint8_t*) &resc_msg, 1, 1000);
        if (status != HAL_OK) {
            printf("UART_Receive failed with status: %d\r\n", status);
            printf("[err] could not receive Uart tx\r\n");
        }
        printf("%c", resc_msg);
    }

    printf("\r\n");
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
BeagleBone Green测试
#include "uart.hpp"
#include <iostream>
#include <thread>
#include <chrono>

int main()
{
    try
    {
        // 初始化UART
        uart my_uart("/dev/ttyS1", uart::BAUD_9600, 'N', 8, 1, 1, 1);
        std::cout << "UART initialized successfully!" << std::endl;

        // 配置GPIO
        my_uart.setupGPIO(71, "in");
        //  my_uart.setupGPIO(72, "out");
        std::cout << "GPIO 71 set to input mode." << std::endl;
        //  std::cout << "GPIO 72 set to output mode." << std::endl;

        // 待发送数据
//      std::string message = "Hello, World!";
        while (true) {
            int value;
            if (my_uart.readGPIO(71, value)) {
                std::cout << "GPIO 71 value read: " << value << std::endl;
                if (value == 1) {
                    std::string receivedData;
                    ssize_t bytesRead = my_uart.readData(receivedData, 1024);

                    if (bytesRead > 0) {
                        std::cout << "Received data: " << receivedData << std::endl;
                    } 
                    else {
                        std::cerr << "Failed to read data from UART." << std::endl;
                    }

                //  std::cout << "GPIO is high. Sending message: " << message << std::endl;
                //  ssize_t bytesWritten =  my_uart.writeData(message);
                //  std::cout << "Bytes sent: " << bytesWritten << std::endl;
                }
            }
            else {
                std::cerr << "Failed to read GPIO 71 value." << std::endl;
            }

            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        }
    }
    catch (const std::exception &e) {
        std::cerr << "ERROR: " << e.what() << std::endl;
    }
    return 0;
}
问题描述

两段代码均可独立运行,但无法实现Nucleo F746ZG向BeagleBone Green发送数据。需求是让Nucleo的huart4发送"Hello World!"到BeagleBone Green的gpio71(RX引脚),目前gpio71已配置为输入模式:

debian@beaglebone:~/bbg$ cat /sys/class/gpio/gpio71/direction /sys/class/gpio/gpio71/value
in
1

已将Nucleo的PC_10(UART-TX)与BeagleBone Green的gpio71物理连接,但BeagleBone Green无法接收消息,寻求解决办法。

更新内容
/*
  Pin PC_10 is configured as UART-TX (port CN8)
 */
char msg[15] = "Hello World!";

HAL_StatusTypeDef status;

/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
    for (uint8_t i = 0; i < strlen(msg); ++i) {
        status = HAL_UART_Transmit(&huart4, (uint8_t*) (msg + i), 1, 1000);
        if (status != HAL_OK) {
            printf("UART_Receive failed with status: %d\r\n", status);
            printf("[err] could not transmit Uart tx\r\n");
        }
    }

    printf("\r\n");
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */   
BeagleBone Green测试代码(可正常运行)

uart.hpp

#ifndef UART_H
#define UART_H

#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <poll.h>
#include <chrono>
#include <iostream>
#include <string>
#include <vector>
#include <fstream>

class uart
{
    public:
        enum BaudRate
        {
            BAUD_2400 = B2400,
            BAUD_9600 = B9600,
            BAUD_19200 = B19200,
            BAUD_38400 = B38400,
            BAUD_57600 = B57600
        };

        uart(std::string path, BaudRate BaudRate, char parity, uint32_t databits, uint32_t stopbits,
                uint32_t vmin, uint32_t timeout);
        ~uart();

        bool isOpen();
        ssize_t writeData(const std::string& buff);
        ssize_t readData(std::string &buff, uint32_t sizeRead);

        // GPIO相关方法
        bool setupGPIO(int pin, const std::string& direction);
        bool readGPIO(int pin, int &value);
        bool writeGPIO(int pin, int value);

    private:
        BaudRate m_baudRate;
        char m_parity;
        uint32_t m_databits;
        uint32_t m_stopbits;
        uint32_t m_vmin;
        struct termios m_uart;

        uint32_t m_timeout;

        int m_fd;
        bool m_isOpen;

        bool openDevice(const std::string& path);
        bool closeDevice();
        bool initDevice();

        std::string gpioPath(int pin);
};

#endif

uart.cpp

#include "uart.hpp"
#include <stdexcept>
#include <unistd.h>
#include <fcntl.h>
#include <cstring>
#include <sstream>
#include <sys/stat.h>

uart::uart(std::string path, BaudRate BaudRate, char parity, uint32_t databits, uint32_t stopbits,
        uint32_t vmin, uint32_t timeout)
{
    m_baudRate = BaudRate;
    m_parity = parity;
    m_databits = databits;
    m_stopbits = stopbits;
    m_vmin = vmin;
    m_timeout = timeout;

    m_fd = -1;
    m_isOpen = false;

    if (!openDevice(path))
    {
        throw std::runtime_error("Failed to open port");
    }

    m_isOpen = true;

    if (!initDevice())
    {
        closeDevice();
        throw std::runtime_error("Failed to initialize uart");
    }
}

uart::~uart()
{
    closeDevice();
}

bool uart::isOpen()
{
    return m_isOpen;
}

ssize_t uart::writeData(const std::string& buff)
{
    return write(m_fd, buff.c_str(), buff.length());
}

ssize_t uart::readData(std::string &buff, uint32_t sizeRead)
{
    buff.resize(sizeRead);
    return read(m_fd, &buff[0], sizeRead);
}

bool uart::openDevice(const std::string& path)
{
    m_fd = open(path.c_str(), O_RDWR | O_NOCTTY);
    if (m_fd == -1)
    {
        return false;
    }

    m_isOpen = true;
    return true;
}

bool uart::closeDevice()
{
    if (isOpen() && close(m_fd) == 0)
    {
        m_isOpen = false;
        return true;
    }
    return false;
}

bool uart::initDevice()
{
    if (tcgetattr(m_fd, &m_uart))
    {
        return false;
    }

    cfsetispeed(&m_uart, m_baudRate);
    cfsetospeed(&m_uart, m_baudRate);

    m_uart.c_cflag &= ~PARENB;     // 清除奇偶校验使能
    m_uart.c_cflag &= ~CSTOP;      // 清除停止位设置
    m_uart.c_cflag &= ~CSIZE;      // 清除数据位设置

    m_uart.c_iflag = IGNBRK;       // 
    m_uart.c_lflag = 0;            // 
    m_uart.c_oflag = 0;            // 

    m_uart.c_cflag |= ~PARENB;     // 设置奇偶校验位
    m_uart.c_cflag |= ~CSTOP;      // 设置停止位
    m_uart.c_cflag |= ~CSIZE;      // 设置数据位

    m_uart.c_iflag &= ~(IXON | IXOFF | IXANY);

    m_uart.c_cc[VTIME] = m_timeout;
    m_uart.c_cc[VMIN] = m_vmin;

    m_uart.c_cflag |= (CLOCAL | CREAD);

    if (tcsetattr(m_fd, TCSANOW, &m_uart))
    {
        return false;
    }

    return true;
}

bool uart::setupGPIO(int pin, const std::string& direction)
{
    std::string path = gpioPath(pin) + "/direction";
    std::ofstream gpio_dir(path);
    if (!gpio_dir.is_open())
        return false;
    gpio_dir << direction;
    gpio_dir.close();
    return true;
}

bool uart::readGPIO(int pin, int &value)
{
    std::string path = gpioPath(pin) + "/value";
    std::ifstream gpio_value(path);
    if (!gpio_value.is_open())
        return false;
    gpio_value >> value;
    gpio_value.close();
    return true;
}

bool uart::writeGPIO(int pin, int value)
{
    std::string path = gpioPath(pin) + "/value";
    std::ofstream gpio_value(path);
    if (!gpio_value.is_open())
        return false;
    gpio_value << value;
    gpio_value.close();
    return true;
}

std::string uart::gpioPath(int pin)
{
    std::stringstream ss;
    ss << "/sys/class/gpio/gpio" << pin;
    return ss.str();
}

main.cpp

#include "uart.hpp"
#include <iostream>
#include <thread>
#include <chrono>

int main()
{
    try
    {
        // 初始化UART
        uart my_uart("/dev/ttyS1", uart::BAUD_9600, 'N', 8, 1, 1, 1);
        std::cout << "UART initialized successfully!" << std::endl;

        // 配置说明
        // 发送配置:
        // /sys/class/gpio/gpio72/direction /sys/class/gpio/gpio72/value
        // direction需设为: out
        // value需设为: 1
        //
        // 接收配置:
        // /sys/class/gpio/gpio71/direction /sys/class/gpio/gpio71/value
        // direction需设为: in
        // value需设为: 0
        //                                 ^
        //                                 |
        //                    引脚断开连接时,main.c会将其值改为1


        // 配置GPIO
        my_uart.setupGPIO(71, "in");
        my_uart.setupGPIO(72, "out");

        std::cout << "GPIO 71 set to input mode." << std::endl;
        std::cout << "GPIO 72 set to output mode." << std::endl;

        // 待发送数据
        std::string message = "Hello, World!";
        while (true)
        {
            int value;
            if (my_uart.readGPIO(71, value))
            {
                std::cout << "GPIO 71 value read: " << value << std::endl;
                if (value == 1)
                {
                    std::cout << "GPIO is high. Sending message: " << message << std::endl;
                    ssize_t bytesWritten =  my_uart.writeData(message);
                    std::cout << "Bytes sent: " << bytesWritten << std::endl;
                }
            }
            else
            {
                std::cerr << "Failed to read GPIO 71 value." << std::endl;
            }

            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        }

    }
    catch (const std::exception &e)
    {
        std::cerr << "ERROR: " << e.what() << std::endl;

    }

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 15:00:53