現實生活中,我們會經常遇到一些串口的設備,例如:IC卡、RFID等;
然后最近有一個項目用到了地磅,這里也是通過串口通訊方式進行數據交互,說實話,地磅這東西,實在有點不方便。
然而,串口的編程,不得不說下串口的DCB(Device Control Block)結構,做過串口編程的人應該都知道,而我這里也只是記錄下自己學過的東西,高手路過的請勿吐槽。
一般串口編程都是通過C/C++ 來通信,然后.Net 也封裝了SerialPort的控件,但是這里還是簡單介紹下:
首先,看看DCB的結構:
1 //Device Control Block 2 [StructLayout(LayoutKind.Sequential)] 3 private struct DCB 4 { 5 //taken from c struct in platform sdk 6 public int DCBlength; // DCB結構的長度(以字節為單位) 7 public int BaudRate; // 波特率設置 8 public int fBinary; // 二進制模式。(必須為1 ) 9 public int fParity; // TRUE時, 支持奇偶檢驗 10 public int fOutxCtsFlow; // TRUE時,支持CTS流控制。 當CTS為OFF時,停止發送。 11 public int fOutxDsrFlow; // TRUE時,支持DSR流控制。 當DSR為OFF時,停止發送。 12 public int fDtrControl; // DTR設置。 (置高/置低...) 13 public int fDsrSensitivity; // TRUE時,當DSR為OFF,則接收端忽略所有字符 14 public int fTXContinueOnXoff; // TRUE時,不管接收端是否Xoff, 本方發送端持續發送。為False 時,則當接收端buffer 達到XoffLim時,發送端發送完Xoff字符后,就停止發送。 15 public int fOutX; // 發送端支持Xon/Xoff 16 public int fInX; // 接收端支持Xon/Xoff 17 public int fErrorChar; // TRUE時,若fParity為TRUE, 則用ErrorChar替換Parity Check錯誤的字符。 18 public int fNull; // TRUE時,接收時去掉空字節(0x0) 19 public int fRtsControl; // RTS設置。 (置高/置低...) 20 public int fAbortOnError; // TRUE時,發生錯誤時停止讀寫操作。 21 public int fDummy2; // 保留 22 public ushort wReserved; // 保留 23 public ushort XonLim; // 當接收Buffer中的字符減少小XonLim規定的字符數, 就發送Xon字符,讓對方繼續發送。 24 public ushort XoffLim; // 接收Buffer達到XoffLim規定的字符數, 就發送Xoff字符, 讓對方停止發送。 25 public byte ByteSize; // 數據位設置 26 public byte Parity; // 奇偶檢驗位的設置:0-4=no,odd,even,mark,space 27 public byte StopBits; // 停止位的設置:0,1,2 = 1, 1.5, 2 28 public char XonChar; // Xon 字符 29 public char XoffChar; // Xoff 字符 30 public char ErrorChar; // Parity Check 錯誤時,替換的字符 31 public char EofChar; // EOF替代字符 32 public char EvtChar; // 事件觸發字符 33 public ushort wReserved1; // 保留 34 }
對於串口的封裝,這里有個串口通信類可以用:
http://www.cnblogs.com/tuyile006/archive/2006/09/25/514327.html
然后在打開串口時,需要設置相關的波特率、數據位與校驗位:
注意:這里的數據需要通過與 地磅的生產商 取得相應的規格。
然后在串口的選擇這里,可以通過程序讀取計算機上的硬件設備:
1 //需要引用組件:Microsoft.VisualBasic.Devices; 2 private void ParameterConfig_Load(object sender, EventArgs e) 3 { 4 cbbCom.Items.Clear(); 5 Microsoft.VisualBasic.Devices.Computer pc = new Microsoft.VisualBasic.Devices.Computer(); 6 foreach (string s in pc.Ports.SerialPortNames) //遍歷本機所有串口 7 { 8 this.cbbCom.Items.Add(s); 9 } 10 SetValue(); 11 }
通過通信類mycom對串口、波特率、數據位、校驗位的賦值:
1 ComHelper mycom = new ComHelper(); 2 mycom.PortNum = config.Port; //串口; 3 mycom.BaudRate = config.BaudRate; // 波特率; 4 mycom.ByteSize = Convert.ToByte(config.ByteSize); //數據位; 5 mycom.Parity = Convert.ToByte(config.Parity); //校驗位;
再讀取串口返回的數據:
1 //1.讀取串口數據 2 byte[] getBytes = mycom.Read(NumsBytes); 3 4 //2。獲取16進制字符串 5 receData = HexConvert.ByteToString(getBytes); 6 7 //3.處理串口連續輸出字符串 8 if (receData.Length > 0) 9 { 10 OutPutHelper helper = new OutPutHelper(); 11 result = helper.getWeight(receData).ToString(); 12 13 //4.其他處理... 14 15 }
這里獲取到的十六進制數:02 72 60 20 30 30 30 36 37 30 30 30 30 30 30 30 0D 4E
說明下,這里的地磅串口輸出格式是:
其中:
1.<STX>ASCⅡ起始符.(0 2H)
2.狀態字 A、B、C.
3.顯示重量,可能是毛重也可能是凈重,6位不帶符號和小數點的數字.
4.皮重值,6位不帶字符和小數點的數字.
5.<CR>ASCⅡ字符(0 DH).
所以,我們只需要從 第5位 開始到 第10位的 數據,即:30 30 30 36 37 30
通過解釋后,得到的重量為:670.
如果沒有東西過磅的情況下,取到的數據是:30 30 30 30 30 30
即是:0.
由於地磅是大磅,不計小數點,所以可以忽略小數點的情況。
————————————————————————————————————————————
其實這里通過SerialPort控件來實現串口編程會快捷點,而相關的使用方法,網上很多地方可以找到。
只是首次遇到串口編程的問題,想了解相關內容……