現實生活中,我們會經常遇到一些串口的裝置,例如: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/Xoff17 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,space27 public byte StopBits; // 停止位的設定:0,1,2 = 1, 1.5, 228 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控制項來實現串口編程會快捷點,而相關的使用方法,網上很多地方可以找到。
只是首次遇到串口編程的問題,想瞭解相關內容……