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