C# SerialPort 串口通讯 通过计算机232来和外部设备通讯 DL/T1997 DL/T2007 通讯协议

来源:互联网 发布:软件应用网络安全方案 编辑:程序博客网 时间:2024/06/15 16:40
去年写的一个国家电网的抄表软件用到了SerialPort串口通讯,昨天有个网友说他遇到的问题,无法解决,我吧自己写的代码贴上来,如有问题者可以给我发微博或者 MSN haitao_kang@163.com
我写的是用的多线程来操作串口的
 
代码如下:
public class SerialPortManage
    {
        //串口资源
        private static SerialPort m_SerialPort = new SerialPort();
        //端口号
        private static string m_strPortName = "Com1";
        //停止位
        private static StopBits m_StopBits = StopBits.One;
        //校验位
        private static Parity m_Parity = Parity.Even;
        //每个字节的位数
        private static int m_iDataBits = 8;
        //波特率
        private static int m_iBaudRate = 1200;
        //
        private static int m_iCurrentRecieveByteCount = 0;
        //接收数据
        private static string inceptData = "";
        //接收数据长度
        private static int inceptDataCount = 0;
        //重复接收次数
        private static int count = 0;
        //是否执行递归
        private static Boolean flag = false;

        public enum DataMode { Text, Hex }
        public enum LogMsgType { Incoming, Outgoing, Normal, Warning, Error };
        

        /// <summary>
        /// get,set方法
        /// </summary>
        public static int InceptDataCount
        {
            get { return SerialPortManage.inceptDataCount; }
            set { SerialPortManage.inceptDataCount = value; }
        }
        public static SerialPort SerialPort
        {
            get { return SerialPortManage.m_SerialPort; }
            set { SerialPortManage.m_SerialPort = value; }
        }
        public static int IDataBits
        {
            get { return SerialPortManage.m_iDataBits; }
            set { SerialPortManage.m_iDataBits = value; }
        }
        public static string StrPortName
        {
            get { return SerialPortManage.m_strPortName; }
            set { SerialPortManage.m_strPortName = value; }
        }
        public static Parity Parity
        {
            get { return SerialPortManage.m_Parity; }
            set { SerialPortManage.m_Parity = value; }
        }
        public static int IBaudRate
        {
            get { return SerialPortManage.m_iBaudRate; }
            set { SerialPortManage.m_iBaudRate = value; }
        }
        public static StopBits StopBits
        {
            get { return SerialPortManage.m_StopBits; }
            set { SerialPortManage.m_StopBits = value; }
        }
        public static int ICurrentRecieveByteCount
        {
            get { return SerialPortManage.m_iCurrentRecieveByteCount; }
            set { SerialPortManage.m_iCurrentRecieveByteCount = value; }
        }

        public static string InceptData
        {
            get { return SerialPortManage.inceptData; }
            set { SerialPortManage.inceptData = value; }
        }

        /// <summary>
        /// 设置串口
        /// </summary>
        /// <param name="strPortName"></param>
        /// <param name="iBaudRate"></param>
        /// <returns></returns>
        public static Boolean setUpCom(string strPortName, int iBaudRate)
        {
            Boolean flag = false;
            try
            {
                if (m_SerialPort.IsOpen)
                    m_SerialPort.Close();
                //设置串口参数
                m_iBaudRate = iBaudRate;
                m_strPortName = strPortName;
                if (openCom())
                    flag = true;
            }
            catch (Exception)
            {

                throw;
            }
            return flag;
        }
        public static Boolean setUpCom()
        {
            Boolean flag = false;
            try
            {
                if (m_SerialPort.IsOpen)
                    m_SerialPort.Close();
                //设置串口参数
                //m_iBaudRate = m_iBaudRate;
                //m_strPortName = m_strPortName;
                if (openCom())
                    flag = true;
            }
            catch (Exception)
            {

                throw;
            }
            return flag;
        }



        /// <summary>
        /// 打开串口
        /// </summary>
        /// <returns></returns>
        public static Boolean openCom()
        {
            Boolean flag = false;
            try
            {
                if (m_SerialPort.IsOpen)
                    m_SerialPort.Close();

                //设置串口参数
                m_SerialPort.BaudRate = m_iBaudRate;
                m_SerialPort.DataBits = m_iDataBits;
                m_SerialPort.StopBits = m_StopBits;
                m_SerialPort.Parity = m_Parity;
                m_SerialPort.PortName = m_strPortName;
                if (m_iBaudRate <= 1200)
                    m_SerialPort.ReadTimeout = 1000;
                else if (m_iBaudRate == 2400)
                    m_SerialPort.ReadTimeout = 800;
                else if (m_iBaudRate == 4800)
                    m_SerialPort.ReadTimeout = 500;
                else if (m_iBaudRate >= 9600)
                    m_SerialPort.ReadTimeout = 200;
                // 打开串口
                m_SerialPort.Open();
                m_SerialPort.DataReceived += new SerialDataReceivedEventHandler(m_SerialPort_DataReceived);
                flag = true;
            }
            catch (Exception)
            {
                throw;
            }
            return flag;
        }


        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static int SendData(byte[] data)
        {
            //应加判断端口是否已经打开
            m_SerialPort.DataReceived += new SerialDataReceivedEventHandler(m_SerialPort_DataReceived);

            inceptData = "";
            inceptDataCount = 0;
            count = 0;
            flag = true;
            try
            {
                // 发送数据到串口
                m_SerialPort.Write(data, 0, data.Length);
            }
            catch (FormatException)
            {
                throw;
            }
            return data.Length;
        }


        /// <summary>
        /// 接收数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public static void m_SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            //lock ("myLock")
            //{
                int readCount = 0;
                // 获取字节长度
                int bytes = m_SerialPort.BytesToRead;

                // 创建字节数组
                byte[] buffer = new byte[bytes];
                //ComPort.ReadTimeout = 100;
                // 读取缓冲区的数据到数组
                readCount = m_SerialPort.Read(buffer, 0, bytes);
                Log(LogMsgType.Incoming, ByteArrayToHexString(buffer), readCount);
                if (InceptData.EndsWith("16") || count > 5)
                {
                    flag = false;
                    return;
                }
                else
                {
                    if (flag)
                    {
                        System.Threading.Thread.Sleep(200);
                        m_SerialPort_DataReceived();
                    }
                    else
                        return;
                }
            //}
        }

        /// <summary>
        /// 接收数据
        /// </summary>
        public static void m_SerialPort_DataReceived()
        {
            //m_SerialPort.DataReceived += new SerialDataReceivedEventHandler(m_SerialPort_DataReceived);
            //lock ("myLock")
            //{
                count++;
                System.Threading.Thread.Sleep(100);
                int readCount = 0;
                // 获取字节长度
                int bytes = m_SerialPort.BytesToRead;

                // 创建字节数组
                byte[] buffer = new byte[bytes];
                //ComPort.ReadTimeout = 100;
                // 读取缓冲区的数据到数组
                readCount = m_SerialPort.Read(buffer, 0, bytes);
                // 显示读取的数据到数据窗口
                if (!(buffer.Length < 2))
                {
                    Log(LogMsgType.Incoming, ByteArrayToHexString(buffer), readCount);
                }
                if (InceptData.EndsWith("16") || count > 5)
                {
                    flag = false;
                    return;
                }
                else
                {
                    if (flag)
                    {
                        System.Threading.Thread.Sleep(200);
                        m_SerialPort_DataReceived();
                    }
                    else
                        return;
                }
            //}
        }

        /// <summary>
        /// 显示数据日志
        /// </summary>
        /// <param name="msgtype"></param>
        /// <param name="msg"></param>
        /// <param name="count"></param>
        private static void Log(LogMsgType msgtype, string msg, int count)
        {
            //this.richTextBox1.Invoke(new EventHandler(delegate
            //{
            inceptData += msg;
            inceptDataCount += count;
            //this.richTextBox1.SelectedText = string.Empty;
            //this.richTextBox1.SelectionFont = new Font(this.richTextBox1.SelectionFont, FontStyle.Bold);
            //this.richTextBox1.SelectionColor = LogMsgTypeColor[(int)msgtype];
            //this.richTextBox1.AppendText(msg);
            //this.richTextBox1.ScrollToCaret();
            //}));

            //MessageBox.Show(data);
        }
        
        
        /// <summary>
        /// 十六进制转换字节数组
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        private static byte[] HexStringToByteArray(string s)
        {
            s = s.Replace(" ", "");
            byte[] buffer = new byte[s.Length / 2];
            for (int i = 0; i < s.Length; i += 2)
                buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
            return buffer;
        
        
        
   
原创粉丝点击