关于串口编程的(一)

所谓串口,也叫串行接口,即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
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值