现实生活中,我们会经常遇到一些串口的设备,例如: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控件来实现串口编程会快捷点,而相关的使用方法,网上很多地方可以找到。
只是首次遇到串口编程的问题,想了解相关内容……