所谓串口,也叫串行接口,即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,一般命令也是十六进制的。所以转换的方法需要用到。

/// <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;         }     }

2、对串口的打开,发送命令,关闭等的类。


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;         }     }

转载于:https://blog.51cto.com/yangyoushan/1276407