關於串口編程的(一)

來源:互聯網
上載者:User

所謂串口,也叫串列介面,即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;        }    }

詳細代碼下載:http://download.csdn.net/detail/yysyangyangyangshan/5516631

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.