版权声明:本文为博主原创文章,未经博主允许不得转载。
所谓串口,也叫串行接口,即COM口,采用串行通讯方式(即数据一位一位的传送)的接口。也就是电脑后面D形9针插口。
最近做了两个都和串口编程有关的功能,一个是不间断电源,一个是RS232型串口打印机。因为是串口所以主要的用法都不难,难点是对设备的相应命令的理解和使用上。因为不同类型的、不同厂家的设备命令是不同的,因为也没法总一个总结。那就对于串口的简单用法做一些总结吧。
主要用到的类是SerialPort,在System.IO.Ports下。传设备的基本使用步骤如下:
1、设置串口的参数。因为不同的设备对串口的参数要求是不同的,最常见就是波特率,一般好像都是9600。
2、打开串口。也就是SerialPort的Open()方法。
3、想串口写命令或写文本内容。一般情况下,如果是数字类型的命令都是十六进制的,当然也有十进制的,不过如果有十六进制和十进制两种,我觉得最好用十六进制的,因为十六进制好转换为byte数组。
向串口写命令的方法是SerialPort的Write(byte[] buffer, int offset, int count)。比如一个命令,十六进制下:00 FF,十进制下:00 255;那么这段命令最终转为byte[]时,00和FF分别转换,但是对于00和255显然就不怎么方便了。看一下后面的一个例子就明白了。
4,接收返回值。向串口发送命令,有的是指示执行操作的,有的是查询状态的,因此需要读取返回值。
下面对于某一个串口设备的控制,写一个简单的例子。
1、字符操作类,因为串口写入的须要是byte数组型,读出又要将byte数组转为string,一般命令也是十六进制的。所以转换的方法需要用到。
2、对串口的打开,发送命令,关闭等的类。
使用
详细代码下载:
http://download.csdn.net/detail/yysyangyangyangshan/5516631
最近做了两个都和串口编程有关的功能,一个是不间断电源,一个是RS232型串口打印机。因为是串口所以主要的用法都不难,难点是对设备的相应命令的理解和使用上。因为不同类型的、不同厂家的设备命令是不同的,因为也没法总一个总结。那就对于串口的简单用法做一些总结吧。
主要用到的类是SerialPort,在System.IO.Ports下。传设备的基本使用步骤如下:
1、设置串口的参数。因为不同的设备对串口的参数要求是不同的,最常见就是波特率,一般好像都是9600。
2、打开串口。也就是SerialPort的Open()方法。
3、想串口写命令或写文本内容。一般情况下,如果是数字类型的命令都是十六进制的,当然也有十进制的,不过如果有十六进制和十进制两种,我觉得最好用十六进制的,因为十六进制好转换为byte数组。
向串口写命令的方法是SerialPort的Write(byte[] buffer, int offset, int count)。比如一个命令,十六进制下:00 FF,十进制下:00 255;那么这段命令最终转为byte[]时,00和FF分别转换,但是对于00和255显然就不怎么方便了。看一下后面的一个例子就明白了。
4,接收返回值。向串口发送命令,有的是指示执行操作的,有的是查询状态的,因此需要读取返回值。
下面对于某一个串口设备的控制,写一个简单的例子。
1、字符操作类,因为串口写入的须要是byte数组型,读出又要将byte数组转为string,一般命令也是十六进制的。所以转换的方法需要用到。
- /// <summary>
- /// 串口字符类
- /// </summary>
- public class CharOperated
- {
- public static string ByteArrayToHexString(byte[] byteData)
- {
- StringBuilder result = new StringBuilder(byteData.Length * 3);
- foreach (byte b in byteData)
- {
- result.Append(Convert.ToString(b, 16).PadLeft(2, '0').PadRight(3, ' '));
- }
- return result.ToString().ToUpper();
- }
- /// <summary>
- /// 十六进制的字符串转成byte数组
- /// </summary>
- /// <returns></returns>
- public static byte[] HexStringToByteArray(string content)
- {
- content = content.Replace(" ", "");
- byte[] buffer = new byte[content.Length / 2];
- for (int i = 0; i < content.Length; i += 2)//因为十六进制命令一般都是两位十六进制一起。
- {
- buffer[i / 2] = (byte)Convert.ToByte(content.Substring(i, 2), 16);
- }
- return buffer;
- }
- /// <summary>
- /// 16进制编码的字串解析成 ascii码
- /// </summary>
- /// <param name="statusCode"></param>
- /// <returns></returns>
- public static string DecodeHexToAsc(string statusCode)
- {
- string rtn = "";
- statusCode = statusCode.Replace(" ", "");
- for (int i = 0; i < (statusCode.Length / 2); i++)
- {
- string key = statusCode.Substring(2 * i, 2);
- int asii = Convert.ToInt32(key, 16);//将16进制字符串转换成其ASCII码(实际是Unicode码)
- rtn += Chr(asii);
- }
- return rtn;
- }
- /// <summary>
- /// ascii码转字符
- /// </summary>
- /// <param name="asciiCode"></param>
- /// <returns></returns>
- public static string Chr(int asciiCode)
- {
- if (asciiCode >= 0 && asciiCode <= 255)
- {
- System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
- byte[] byteArray = new byte[] { (byte)asciiCode };
- string strCharacter = asciiEncoding.GetString(byteArray);
- return (strCharacter);
- }
- return string.Empty;
- }
- }
- public class ComManager
- {
- private SerialPort comm = null;
- private static string currentPortName = string.Empty;
- private static object sendCommandLock = new object();
- public ComManager(SerialPort comm)
- {
- if (this.comm == null)
- {
- this.comm = comm;
- }
- }
- /// <summary>
- /// 串口参数设定
- /// </summary>
- private void SetSerialPort()
- {
- //根据设备要求设置参数,比如某一设备要求参数如下:
- comm.BaudRate = 9600;
- comm.Encoding = System.Text.Encoding.GetEncoding("GB2312");
- comm.RtsEnable = true;
- }
- /// <summary>
- /// 打开串口设备
- /// </summary>
- private void SerialPortOpen()
- {
- try
- {
- if (comm.IsOpen)
- {
- comm.Close();
- }
- currentPortName = "COM1";//此处可指定串口,也可以实时读取设备到底连接在那个串口,实际情况根据设备情况而定。
- //currentPortName = DoGetUPSPortName();以某一设备为例遍历所有串口,找到连接该设备的串口
- SetSerialPort();
- if (string.IsNullOrEmpty(currentPortName))
- {
- return;
- }
- comm.PortName = currentPortName;
- comm.Open();
- }
- catch
- {
- }
- }
- /// <summary>
- /// 向串口发送命令
- /// </summary>
- /// <param name="sendstring"></param>
- public void SendDatastring(string sendstring)
- {
- lock (sendCommandLock)
- {
- //16进制转二进制
- byte[] data = CharOperated.HexStringToByteArray(sendstring);
- //打开口串口设备
- SerialPortOpen();
- //发送命令到串口设备
- if (comm.IsOpen)
- {
- comm.DiscardInBuffer();
- comm.Write(data, 0, data.Length);
- }
- }
- }
- /// <summary>
- /// 向串口写字符串
- /// </summary>
- /// <param name="sendstring"></param>
- public void WriteLingContent(string content)
- {
- lock (sendCommandLock)
- {
- //打开口串口设备
- SerialPortOpen();
- //发送报文到串口设备
- if (comm.IsOpen)
- {
- comm.WriteLine(content);
- comm.DiscardInBuffer();
- }
- }
- }
- /// <summary>
- /// 读取端口返回值
- /// </summary>
- /// <returns></returns>
- private string DoReadPortResult()
- {
- string resultString = string.Empty;
- try
- {
- int bytes = comm.BytesToRead;
- byte[] buffer = new byte[bytes];
- comm.Read(buffer, 0, bytes);
- string rtnStrPort = CharOperated.ByteArrayToHexString(buffer);
- resultString = CharOperated.DecodeHexToAsc(rtnStrPort);
- if (comm.IsOpen)
- {
- comm.DiscardInBuffer();
- }
- }
- catch
- {
- }
- return resultString;
- }
- /// <summary>
- /// 获取某一设备的端口号
- /// </summary>
- /// <returns></returns>
- private string DoGetUPSPortName()
- {
- string commName = string.Empty;
- try
- {
- Computer localComputer = new Computer();
- foreach (string portItem in localComputer.Ports.SerialPortNames)
- {
- try
- {
- if (string.IsNullOrEmpty(portItem))
- {
- continue;
- }
- commName = portItem;
- byte[] data = CharOperated.HexStringToByteArray("发送的命令");
- comm.Close();
- SetSerialPort();
- comm.PortName = portItem;
- comm.Open();
- //发送报文到串口设备
- if (comm.IsOpen)
- {
- comm.DiscardInBuffer();
- comm.Write(data, 0, data.Length);
- }
- Thread.Sleep(500);
- //if (条件)
- //{
- //}
- //else
- //{
- // commName = string.Empty;
- //}
- }
- catch
- {
- }
- finally
- {
- if (comm.IsOpen)
- {
- comm.Close();
- }
- }
- }
- }
- catch
- {
- }
- finally
- {
- if (comm.IsOpen)
- {
- comm.Close();
- }
- }
- return commName;
- }
- }
- class Program
- {
- private static SerialPort serialPortCom = new SerialPort();//串口定义 。
- private static string receiveResult = string.Empty; //接收数据。
- static void Main(string[] args)
- {
- ComManager cm = new ComManager(serialPortCom);
- cm.SendDatastring("00FF");//命令
- cm.WriteLingContent("内容");
- Thread.Sleep(200);//停几百毫秒,然后读取
- string result = SerialPortComDataReceived();
- }
- private static string SerialPortComDataReceived()
- {
- if (serialPortCom == null || !serialPortCom.IsOpen)
- {
- return string.Empty;
- }
- int bytes = serialPortCom.BytesToRead;
- byte[] buffer = new byte[bytes];
- serialPortCom.Read(buffer, 0, bytes);
- receiveResult = string.Empty;
- receiveResult = CharOperated.ByteArrayToHexString(buffer);
- receiveResult = receiveResult.Trim();
- return receiveResult;
- }
- }