找回密码
 加入
搜索
查看: 1128|回复: 9

[网络通信] 串口通訊無法傳送大於ASCII值128 ~255(暫時解決)

[复制链接]
发表于 2021-12-31 02:12:42 | 显示全部楼层 |阅读模式
本帖最后由 yohoboy 于 2022-1-27 10:20 编辑

最近測試一個單晶片機板,使用串口測試軟體模擬單晶片去接收串口傳來之資料。
發現校驗值如果大於ASCII值 128到255 值時,會產生錯誤,讓單晶片機板無法運作(因校驗和不對)。
因此想請教如何寫法讓資料格式是正確的。感謝大德的幫助。

以下附上簡易代碼
;Include the Serial UDF
#include 'CommMG.au3'
#include <StringConstants.au3>
#include <MsgBoxConstants.au3>
#include <Array.au3> ; _ArrayDisplay() 函数所需的包含文件.

Global $sportSetError = ''
Global $CMPort = 3  ; Port
Global $CmBoBaud = 9600   ; Baud
Global $CmboDataBits =  8  ; Data Bits
Global $CmBoParity = "none"  ; Parity
Global $CmBoStop = 1   ; Stop
Global $Text_Xor = ""
Global $setflow = 2 ; Flow ..... IS THIS CORRECT
;Local $Input_Word = Chr(2) & "___c____TXC14YC~F0~M01~D1~S1~P0訊息測試t~F0~M01~D1~S1~P0TESTM1"  ;
Local $Input_Word = Chr(2) & "___c____TXC14YC~F0~M01~D2~S2~P0訊息測試t~F0~M01~D2~S2~P0Message Test.T007S01s30M1"
Local $Send_Temp = Check_code($Input_Word)
                $Send_Temp &= Chr(3) ;加入chr(3) 完成串口傳輸
;ClipPut($Send_Temp) ;用HxD 軟體開並貼上用於顯示ASCII值
_CommSetPort($CMPort, $sportSetError, $CmBoBaud, $CmboDataBits, $CmBoParity, $CmBoStop, $setflow)
_CommSendstring($Send_Temp)
_CommSendByte($Text_Xor) ;用以對比chr(3)值前第二個byte 值是否正確,如附圖一(Xor值.jpg)
_CommClosePort()

Func Check_code($Input_Text)
        $Text_Xor = ""
        Local $Output_Text =""
        $Text_Len = StringLen($Input_Text)
                $Text_Array_Temp = StringToASCIIArray($Input_Text,0,$Text_Len,$SE_ANSI)
                ;_ArrayDisplay($Text_Array_Temp)
                ;$Text_Array_columns = UBound($Text_Array_Temp,$UBOUND_ROWS )
                ;MsgBox(0,"$Text_Array_columns",$Text_Array_columns)
                for $i = 0 to ( UBound($Text_Array_Temp) - 1) Step  1 ;計算校驗碼,採用Xor值計算
                        ;MsgBox(0,"$Text_Array_Temp[$i]",chr($Text_Array_Temp[$i]))
                        $Text_Xor = BitXOR($Text_Xor,($Text_Array_Temp[$i]))
                Next
                MsgBox(0,"$Text_Xor值",$Text_Xor & @CRLF & "Ascii字串顯示:"& chr($Text_Xor) & @CRLF & "unicode字串顯示:" & chrw($Text_Xor))

                If $Text_Xor <= 32 Then ;如果Xor 值小於32 (控制符)
                        $Output_Text = $Input_Text & Chr( ($Text_Xor + 32)) & "0"  ;將小於Xor值加上32值 改為一般字符類型,並加入識別碼 0 值,測試成功
ElseIf $Text_Xor >= 128 Then
                        ;MsgBox(0,"",CHR($Text_Xor))
                        $Output_Text = $Input_Text &  Chrw($Text_Xor) & "0"    ;大於128-ASCII值,並加入識別碼 0 值,卡在無法傳送大於Ascii值128以上到255
                Else
                        $Output_Text = $Input_Text & Chr($Text_Xor) & "0" ;直接輸出,並加入識別碼 0 值,測試成功
                EndIf
                MsgBox(0,"輸出訊息",$Output_Text)
        Return $Output_Text
EndFunc



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2022-1-1 20:36:14 | 显示全部楼层
这里问串口的问题,不太合适吧. 而且我看到你上面有大于0x80的数据啊.
 楼主| 发表于 2022-1-2 01:15:07 | 显示全部楼层
本帖最后由 yohoboy 于 2022-1-5 23:50 编辑

谢谢回覆,我的校验和是从 0x02[chr(2)]起再跟下一位元做 Xor 值运算,然后一直到校验和的位元前停止,这时 Xor值就是校验和,
该值如果是小于chr(32)就直接+32变为 一般字符,如果校验和是在chr(33)到chr(127)就不转换,但卡在chr(128)以上到chr(255)
这ASCII 扩充字源,我算的校验值是正确的,但是校验值要 "&" 串接之前要传的资料,就不明原因变成别的字元,多的是以 0x3f(?)
送到串口设备,所以才想看看怎么弄才能传送大于ascii值128到255字元。
发表于 2022-1-4 14:14:38 | 显示全部楼层
为什么要校验和?这个是起什么作用?
 楼主| 发表于 2022-1-4 23:49:06 | 显示全部楼层
auto 发表于 2022-1-4 14:14
为什么要校验和?这个是起什么作用?

检验和(checksum),在数据处理和数据通信领域中,用于校验目的地一组数据项的和。它通常是以十六进制为数制表示的形式。如果校验和的数值超过十六进制的FF,也就是255。就要求其补码作为校验和。通常用来在通信中,尤其是远距离通信中保证数据的完整性和准确性。
发表于 2022-1-5 08:19:34 | 显示全部楼层
看看,学习一下
发表于 2022-1-5 09:32:58 | 显示全部楼层
yohoboy 发表于 2022-1-4 23:49
检验和(checksum),在数据处理和数据通信领域中,用于校验目的地一组数据项的和。它通常是以十六进制为 ...

你的校验和在本地正确吗?正确的话应该是没有问题的
 楼主| 发表于 2022-1-5 23:20:04 | 显示全部楼层
本帖最后由 yohoboy 于 2022-1-5 23:53 编辑
auto 发表于 2022-1-5 09:32
你的校验和在本地正确吗?正确的话应该是没有问题的

校验和经运算在本地是正确的,可由一楼简易代码第35行的 $Text_Xor 最后一笔运算得到的Xor值是正确的
就是卡在第43行串接其他字串后会有校验和显示异常情况,何况透过_CommSendstring(Send_Temp)后
用串口软体接收rs232 资料后,校验和的栏位会变成 3F(也就是?),只要大于ascii值128以上都会这样。
就是卡在这,只要校验值不对,终端设备就舍弃资料,所以很苦恼这样。
 楼主| 发表于 2022-1-5 23:43:45 | 显示全部楼层
本帖最后由 yohoboy 于 2022-1-5 23:57 编辑

偷吃步的方法,此方法暫可解決透過串口傳輸ASCII大於128以上的問題,還是不完美。
lude the Serial UDF
#include 'CommMG.au3'
#include <StringConstants.au3>
#include <MsgBoxConstants.au3>
#include <Array.au3> ; _ArrayDisplay() 函数所需的包含文件.

Global $sportSetError = ''
Global $CMPort = 3  ; Port
Global $CmBoBaud = 9600   ; Baud
Global $CmboDataBits =  8  ; Data Bits
Global $CmBoParity = "none"  ; Parity
Global $CmBoStop = 1   ; Stop
Global $Text_Xor = "", $Send_Output= ""
Global $setflow = 2 ; Flow ..... IS THIS CORRECT
;Local $Input_Word = Chr(2) & "___c____TXC14YC~F0~M01~D1~S1~P0訊息測試t~F0~M01~D1~S1~P0TESTM1"  ;
Local $Input_Word = Chr(2) & "___c____TXC14YC~F0~M01~D2~S2~P0訊息測試t~F0~M01~D2~S2~P0Message Test.T007S01s30M1"
Check_code($Input_Word)

_CommSetPort($CMPort, $sportSetError, $CmBoBaud, $CmboDataBits, $CmBoParity, $CmBoStop, $setflow) ;設定串口

_CommClearOutputBuffer()
_CommSendstring($Input_Word) ;先傳輸字串資料至終端設備
Sleep(150) ;暫停150毫秒,讓終端設備先讀取已傳輸的資料,數值可修改,以配合終端設備接收狀態調整
If $Text_Xor <= 32 Then
        _CommClearOutputBuffer()
        $Send_Output = Chr( Int($Text_Xor + 32)) & "0" & chr(3)
        _CommSendString ($Send_Output)
ElseIf $Text_Xor >= 128 Then
        _CommClearOutputBuffer()
        _CommSendByte($Text_Xor) ;先使用Byte 強制送大於Ascii >=128
        $Send_Output = "0" & Chr(3)
        _CommSendString ($Send_Output)
Else
        _CommClearOutputBuffer()
        $Send_Output = Chr( Int($Text_Xor)) & "0" & chr(3)
        _CommSendString ($Send_Output)
EndIf


_CommSendByte($Text_Xor) ;用以對比chr(3)值前第二個byte 值是否正確,如附圖一(Xor值.jpg)
_CommClosePort()

Func Check_code($Input_Text)
        $Text_Xor = ""
        Local $Output_Text =""
        $Text_Len = StringLen($Input_Text)
                $Text_Array_Temp = StringToASCIIArray($Input_Text,0,$Text_Len,$SE_ANSI)
                ;_ArrayDisplay($Text_Array_Temp)
                ;$Text_Array_columns = UBound($Text_Array_Temp,$UBOUND_ROWS )
                ;MsgBox(0,"$Text_Array_columns",$Text_Array_columns)
                for $i = 0 to ( UBound($Text_Array_Temp) - 1) Step  1 ;計算校驗碼,採用Xor值計算
                        ;MsgBox(0,"$Text_Array_Temp[$i]",chr($Text_Array_Temp[$i]))
                        $Text_Xor = BitXOR($Text_Xor,($Text_Array_Temp[$i]))
                Next
                MsgBox(0,"$Text_Xor值",$Text_Xor & @CRLF & "Ascii字串顯示:"& chr($Text_Xor) & @CRLF & "unicode字串顯示:" & chrw($Text_Xor))
EndFunc

发表于 2022-2-2 09:33:26 | 显示全部楼层
支持楼主,最近也在用autoit折腾串口的单片机
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-3 22:39 , Processed in 0.074988 second(s), 20 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表