使用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(空调制解调器连接)。另一种可能性是终端是行缓冲的,因此在 以上是关于使用Linux终端从STM32的串口读取数据的主要内容,如果未能解决你的问题,请参考以下文章