使用Linux终端从STM32的串口读取数据

Posted

技术标签:

【中文标题】使用Linux终端从STM32的串口读取数据【英文标题】:Reading data from the serial port of a STM32 using the Linux terminal 【发布时间】:2021-11-30 15:25:41 【问题描述】:

我正在尝试使用 RS232-USB 电缆通过 STM32F429ZI 读取和发送数据。

对于硬件,我使用了一个 RS232 DB9 到 TTL MAX3232 转换器,连接到 STM32 的 UART2 端口 PA2 和 PA3。我不知道这是否相关,但我正在使用一对 10 厘米长的电缆将 RS232 模块的 TX-RX 连接到 STM32。

然后,我尝试使用 Kubuntu 上的 Linux 终端从 uC 发送和读取数据。这些是我配置连接的步骤:

使用ls -lah /dev/ 我查看RS232-USB 的连接位置。就我而言,我可以看到它连接到 /dev/ttyUSB0。 然后我授予我的用户使用 sudo chmod o+rw /dev/ttyUSB0 读写 USB 端口的权限。 之后,我使用stty 命令配置连接的波特率。就我而言,我将 STM32 配置为每秒 9600 波特,所以 stty -F /dev/ttyUSB0 9600。使用stty -F /dev/ttyUSB0 -a,我可以看到速度实际上是每秒9600波特。

到目前为止一切顺利。我可以毫无问题地将数据从我的计算机发送到 STM32。为了对此进行测试,我正在执行以下操作:

我有一个连接到 STM32 的 2x16 LCD 显示器,用于打印我从计算机发送的数据。 要从终端发送数据,我只是在做echo -n 'a' > /dev/ttyUSB。这似乎工作得很好,因为我可以在 LCD 显示屏上正确打印数据。 我什至测试了一个程序来计算文件上的字符和操作所需的时间,以证实 9600 波特率。为此,我创建了一个包含 9600 个字符的文件,并使用cat test.txt | tr '\n' '#' > /dev/ttyUSB0 将文件发送到 STM32。这工作得很好,我通常会得到正确的答案,但其他时候我没有。尽管如此,它不工作的时间非常少,所以我假设这是由于噪音。

所以,经过测试,我实际上可以将数据从我的计算机发送到 STM32,我尝试做相反的事情:将数据从 STM32 发送到我的计算机。但这似乎不起作用,因为我无法真正阅读计算机中的任何内容。

我在几个论坛上读到,要在 Linux 控制台上从串口读取数据,只需在设备上使用 cat 命令即可。所以,我尝试了几种方法,但我什么也看不懂:

cat /dev/ttyUSB0 什么都没有显示,我必须用 Ctrl+C 退出。 cat -v /dev/ttyUSB0 什么都没有显示,我必须用 Ctrl+C 退出。 cat < /dev/ttyUSB0 什么都没有显示,我必须用 Ctrl+C 退出。 cat /dev/ttyUSB0 & 只显示一个数字就结束了。

所以,我不知道我只是使用了cat 命令错误,还是硬件问题,或者为什么我可以从我的计算机发送数据但无法读取。

这是我在 STM32 中用于读取和发送数据的程序部分(C 语言):

while(1)
    
        if (USART_GetFlagStatus(USART2, USART_FLAG_RXNE) != RESET)
        
            Data = USART_ReceiveData(USART2);

            while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
                USART_SendData(USART2, Data);
        
    

如果有人需要,我可以上传 USART 端口的配置,但考虑到我可以正常读取数据,我不知道这是否相关。

感谢任何帮助。

提前致谢。

编辑:这是当前项目 - https://github.com/AugustoRiedinger/06TP_E02 ;以及读取数据的项目https://github.com/AugustoRiedinger/06TP_E01

【问题讨论】:

"那我给我的用户读写USB端口的权限..." -- 不正确;而是将您的用户名添加到拥有该设备的组中,例如dialout 组。 "我配置波特率..." -- 你还需要匹配字符大小、奇偶校验、停止位和流控制(又名握手)。您可能需要使用示波器检查串行线路信号,以验证您的 MAX3232 是否安装正确 @sawdust 我该如何进行握手?而如果我在STM32上能接收到数据,那是不是说明MAX3232安装正确了呢?还是您认为错误可能只是在 TX 上? 握手有硬件(例如 RTS/CTS)和软件(XON/XOFF)版本。您只会使用握手来控制吞吐量;无需握手即可测试。您大概没有在 STM32 上实现任何东西;对 PC 使用stty raw -F /dev/ttyUSB0。接收不验证传输; RS-232 对每个方向使用独立的通道。检查范围将是缩小可能问题范围的最快方法。对于某些问题,只有“范围”才能揭示它们。 我建议您使用比cat 更具“交互性”的东西进行调试。例如,developer.toradex.com/knowledge-base/serial-terminal-emulator 建议的几个选项。 您是否执行了所有必要的 USART、RCC 和 GPIO 初始化? 【参考方案1】:

你的循环说“只要不能发送一个字节,就反复尝试发送它,一旦可以发送一个字节,就丢弃它而不发送”

变化:

       while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET)
            USART_SendData(USART2, Data);

收件人:

       while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
       USART_SendData(USART2, Data);

【讨论】:

我试过了,但不幸的是没有用。在一个控制台上,我只是用echo -n 'a' > /dev/ttyUSB0 向STM 发送字符,这些字符存储在定义为char Data;Data 变量中。然后,我在显示器上打印了Data,这很好,STM 正确识别了这些字符。在另一个控制台上,我只有cat /dev/ttyUSB0,然后是cat < /dev/ttyUSB0,但看不到Data 上的字符。我什至尝试了主循环while(1)USART_SendData(USART2, Data);,但使用cat /dev/ttyUSB0 在控制台中也看不到任何内容。 或者最好是while(...) NEW LINE 然后(缩进); 以便代码变成自我记录 - 分号或 是故意添加到那里的,我们可以规则出一个可能意外的分号。好的编译器会警告马虎的单行循环。 @Lundin 你的意思是这样的Screenshot吗?我正在使用 Atollic TRUE Studio 调试 STM。 @riedaug :建议此更改“不好”是不正确的。如果按照建议更正代码后 仍然 不起作用,那么显然你有不止一个问题。应用适当的调试技术首先验证接收和传输字符的代码是否实际执行。然后以适当的波特率验证数据线上是否有信号。验证您已正确连接 Rx/Tx(空调制解调器连接)。另一种可能性是终端是行缓冲的,因此在 . 之前没有任何输入或输出 @riedaug 我认为如果电压发生变化并且您可以在 picocom 上看到内容,那么根据我在上面的答案中对您的代码建议的更改解决了原始问题。如果您同意,请接受左侧打勾​​的答案。如果您想问 picocom 没有什么 cat 不做,那么这应该是一个单独的新问题,而不是 cmets 的答案。

以上是关于使用Linux终端从STM32的串口读取数据的主要内容,如果未能解决你的问题,请参考以下文章

wt901怎么用stm32读取数据

stm32dma串口没有收到包头

linux下shell脚本实现串口的读取以及报文的解析

单片机STM32 串口一次能发和接收几个字节数据?大神正解

STM32CubeMX-输入捕获读取超声波模块数据

STM32单片机如何处理QT上位机串口中发过来的数据?