既然您提到您之前使用过 tcl,我将在 tcl 中给出我的答案,因为恕我直言,这是最简单的方法,因此是正确工作的正确工具。
tcl 的核心优势(也是它深受粉丝喜爱的原因之一)是它非常非常跨平台。虽然在其他语言中跨平台只是意味着“可以在多个平台上运行”但仍然需要您根据平台使用不同的 API,但 tcl 消除了平台差异,提供了跨平台的统一 API。
Tcl 将串行端口视为文件,因此您只需open
与它对话即可。当然,不同的平台提供了不同的端口命名方式。因此,在 Windows 上,要与串行端口通信,您只需执行以下操作:
set rs232 [open COM1 w+]
在 unixen(Linux、MacOSX 等)上,你会这样做:
set rs232 [open /dev/ttyS0 w+]
要设置波特率和奇偶校验位,您现在可以执行
fconfigure $rs232 -mode "9600,n,8,1"
确保还将串行端口配置为二进制模式,否则 tcl 将根据您的操作系统为您重新解释“\n”:
fconfigure $rs232 -mode "9600,n,8,1" -translation binary -blocking 0
“阻塞”位是将其设置为非阻塞模式,以便我们可以编写面向事件的代码,这对 UI 应用程序至关重要,因为我们不希望 IO 阻塞我们的 UI。
所以现在对于一个从串口读取数据的简单程序:
package require Tk ;# in case we're running in tclsh
if {[catch {set rs232 [open COM1 w+] err}]} {
tk_dialog .error Error "Could not open COM1: $err" error 0 OK
}
fconfigure $rs232 -mode "9600,n,8,1" -translation binary -blocking 0
# Draw a simple UI do dump data to:
pack [label .l -text "Gyroscope outputs:"]
pack [label .g1 -textvariable gyro1]
pack [label .g2 -textvariable gyro2]
pack [label .g3 -textvariable gyro3]
# Now the fun part, read from the serial continuously with fileevent:
set buffer ""
fileevent $rs232 readable {
append buffer [read $rs232]
# Here, you need to parse the data returned.
# Due to the byte-wise nature of serial ports the data read may not be
# complete so we need to check if it's complete. "Completeness" depends
# on you. For example the data packet may end with a newline. Or it may
# simply be a timeout between data packets.
if {[message_is_complete $buffer]} {
set gyros [parse_message $buffer]
set buffer ""
# Update the UI:
foreach x $gyros y {gyro1 gyro2 gyro2} {
set $y $x
}
}
}
减去只有 16 行代码的注释和空行。您当然可以更进一步,实现更精美的 UI 而不仅仅是文本标签。
如果您需要向微控制器发送数据,只需puts
向它发送。只要记住覆盖 tcl 的自动换行终止:
puts -nonewline $rs232 $somedata
binary
如果您需要格式化二进制文件,请使用 tcl 的命令。