VB.Net 通过 Serial port 向 CD7220 发送十六进制代码
结论
发送 0xBC 时,应调用 SerialPort.Write(Byte(), offset, count) 直接写入一个字节:
Dim poundByte As Byte() = {CByte(&HBC)}
mySerialPort.Write(poundByte, 0, poundByte.Length)
字符串 "BC"、"&HBC" 和 ChrW(&HBC) 处理的都是文本字符。经过 SerialPort.Encoding 转换后,发送出去的字节未必是 BC。
以上写法还要求 CD7220 当前使用的字符表将字节 0xBC 映射为 £。如果设备切换过字符表,请先按照手册选用正确的字符表。
直接发送 £ 为什么可能无效
.NET 字符串中的 £ 是 Unicode 字符 U+00A3,CD7220 所需的则是设备字符表中的单字节值 0xBC,两者的编码值不同。
SerialPort.Write(String) 和 WriteLine(String) 会先根据 SerialPort.Encoding 将字符串转换成字节。默认编码通常无法将 £ 转换为设备要求的 0xBC,最终可能发送 ? 或其他字节。
下面这种写法同样不可靠:
mySerialPort.Write(ChrW(&HBC))
ChrW(&HBC) 表示 Unicode 字符 U+00BC,也就是 ¼,不是数值为 BC 的原始字节。
只发送 GBP 符号
如果只是测试 £ 能否正常显示,可以这样发送:
Imports System.IO.Ports
Using mySerialPort As New SerialPort(
"COM3",
9600,
Parity.None,
8,
StopBits.One)
mySerialPort.Open()
Dim poundByte As Byte() = {CByte(&HBC)}
mySerialPort.Write(poundByte, 0, poundByte.Length)
End Using
串口传输的是字节流,十六进制只是字节值的一种书写方式。0xBC、&HBC 和十进制 188 表示同一个字节。
在普通文本中插入 £
如果字符串中既有普通 ASCII 字符,也有 £,可以先按设备字符表进行转换,再发送数据:
Private Function EncodeCd7220(value As String) As Byte()
Dim result As New List(Of Byte)(value.Length)
For Each ch As Char In value
If ch = "£"c Then
result.Add(CByte(&HBC))
Else
Dim code As Integer = AscW(ch)
If code >= 0 AndAlso code <= &H7F Then
result.Add(CByte(code))
Else
' 当前转换函数没有定义其他非 ASCII 字符的设备编码
result.Add(CByte(AscW("?"c)))
End If
End If
Next
Return result.ToArray()
End Function
Private Sub WriteCd7220(port As IO.Ports.SerialPort, value As String)
Dim data As Byte() = EncodeCd7220(value)
port.Write(data, 0, data.Length)
End Sub
发送两行内容时,可以写成:
Imports System.IO.Ports
Dim displayText As String = If(varPassed, String.Empty)
If displayText.Length > 40 Then
displayText = displayText.Substring(0, 40)
Else
displayText = displayText.PadRight(40)
End If
Dim line1 As String = displayText.Substring(0, 20)
Dim line2 As String = displayText.Substring(20, 20)
Using mySerialPort As New SerialPort(
"COM3",
9600,
Parity.None,
8,
StopBits.One)
mySerialPort.Open()
WriteCd7220(mySerialPort, line1)
Dim crlf As Byte() = {CByte(&HD), CByte(&HA)}
mySerialPort.Write(crlf, 0, crlf.Length)
WriteCd7220(mySerialPort, line2)
End Using
例如,字符串 "TOTAL £12.50" 中的 £ 会被转换为单字节 BC,其余 ASCII 字符按原值发送。
WriteLine 与显示器换行的关系
WriteLine 不知道显示器有两行,也不会自动将每次调用对应到一行。它只会发送字符串,并在末尾追加 SerialPort.NewLine 指定的字节。
如果字符串末尾已经加入 vbCrLf,又调用了 WriteLine:
mySerialPort.WriteLine(line1 & vbCrLf)
发送的数据会先包含手动添加的 CR LF,后面再附加 WriteLine 自己的换行符,可能造成重复换行或产生多余的控制字符。
控制这类串口显示设备时,使用 Write 明确发送 0x0D、0x0A 或手册规定的光标定位命令会更稳妥。如果 CD7220 手册要求的换行序列不是 CR LF,请将示例中的:
Dim crlf As Byte() = {CByte(&HD), CByte(&HA)}
替换为手册指定的控制字节。每行可显示 20 个字符只是设备的显示容量,不表示设备会把每次串口写入都当成独立的一行。
备注:内容仅供参考。
