我是一个新鲜的tcl用户,我最近在使用串口的脚本上工作。到目前为止,我最大的问题是我无法有效地读取我的串口。 我正在使用fileevent来阅读,但它捕获了之前发送的内容。但是,如果我之前没有发送任何内容,它会等待外部数据并抓住它。我的代码:
global forever
proc read_serial {serial} {
set msg [read $serial]
set listOfLetters [split $msg {} ]
set serialIPinHex ""
foreach iChar $listOfLetters { ;#conversion to hex
scan $iChar "%c" decimalValue
set hexValue [format "%02X" $decimalValue ]
set hexValue "0x$hexValue"
set serialIPinHex "$serialIPinHex $hexValue"
}
puts "MCU RESPONSE: $serialIPinHex"
global forever
set forever 1 ;# end event loop
}
set serial [open com1 r+]
fconfigure $serial -mode "19200,n,8,1"
fconfigure $serial -blocking 0 -buffering none
fconfigure $serial -translation binary -encoding binary
fileevent $serial readable [list read_serial $serial ]
global forever
puts -nonewline $serial \x31\xce
flush $serial
delay 10
vwait forever
flush $serial
close $serial
效果是“MCU响应:x31 xce”,而它应该等待串口(根据我的理解)。我确定另一端没有回声功能。在此先感谢您的帮助。我希望我的虫子没有尴尬,我花了几个小时寻找它...
答案 0 :(得分:1)
关于串口的主要注意事项是它们 慢 。真的很慢。在串口通过一个字符之前(好吧,比喻),现代计算机可以在块上运行三次。这意味着您将一次一个人,并且您必须处理这个问题。
建议您使用read $serial 1
并将其附加到要保留的缓冲区,或者编写代码以一次处理一个字节。如果您使用的是面向行的消息传递,则可以利用gets
在非阻塞模式下的良好行为(fblocked
命令旨在支持此行为),但{{1并非如此友好(因为它对记录分隔符一无所知)。
如果您使用read
,请不要担心丢失一个字节;如果剩下一个,你的回调将立即再次被召唤来处理它。