串口收发数据

 串口收发数据

一、串口收发数据的类
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace zhouxl.MyCom
{
    class MyCom
    {
        private int iPort; //端口号:0-8
        private int iRate; //波特率
        private int bSize; //数据位:5-8
        private byte bParity; // 校验位 0-4=no,odd,even,mark,space
        private byte bStopBits; // 0,1,2 = 1, 1.5, 2
        private int iTimeout = 2000; //超时时间

        public int IPort  //端口属性外露
        {
            get { return iPort; }
            set { iPort = value; }
        }

        public int IRate //波特率属性外露
        {
            get { return iRate; }
            set { iRate = value; }
        }

        public int BSize //数据位属性外露
        {
            get { return bSize; }
            set { bSize = value; }
        }

        public byte BParity //奇偶校验属性外露
        {
            get { return bParity; }
            set { bParity = value; }
        }

        public byte BStopBits //停止位属性外露
        {
            get { return bStopBits; }
            set { bStopBits = value; }
        }

        public MyCom() //无参构造函数
        {
            iPort = 0;//串口1
            iRate = 9600;//波特率9600
            bSize = 8;//数据位8
            bParity = 2;//无效验
            bStopBits = 0;//停止位1
        }

        public MyCom(int com, int rate, int size, byte parity, byte stopbits)//构造函数
        {
            iPort = com;
            iRate = rate;
            bSize = size;
            bParity = parity;
            bStopBits = stopbits;
        }
        
        
        //public mycom mycom1 = new mycom();
        //public byte[] recb;

        //comm port win32 file handle
        private int hComm = -1;

        public bool Opened = false;

        //win32 api constants
        private const uint GENERIC_READ = 0x80000000;
        private const uint GENERIC_WRITE = 0x40000000;
        private const int OPEN_EXISTING = 3;
        private const int INVALID_HANDLE_VALUE = -1;

        [StructLayout(LayoutKind.Sequential)]
        private struct DCB
        {
            //taken from c struct in platform sdk
            public int DCBlength;           // sizeof(DCB)
            public int BaudRate;            // current baud rate
            public int fBinary;          // binary mode, no EOF check
            public int fParity;          // enable parity checking
            public int fOutxCtsFlow;      // CTS output flow control
            public int fOutxDsrFlow;      // DSR output flow control
            public int fDtrControl;       // DTR flow control type
            public int fDsrSensitivity;   // DSR sensitivity
            public int fTXContinueOnXoff; // XOFF continues Tx
            public int fOutX;          // XON/XOFF out flow control
            public int fInX;           // XON/XOFF in flow control
            public int fErrorChar;     // enable error replacement
            public int fNull;          // enable null stripping
            public int fRtsControl;     // RTS flow control
            public int fAbortOnError;   // abort on error
            public int fDummy2;        // reserved
            public ushort wReserved;          // not currently used
            public ushort XonLim;             // transmit XON threshold
            public ushort XoffLim;            // transmit XOFF threshold
            public byte ByteSize;           // number of bits/byte, 4-8
            public byte Parity;             // 0-4=no,odd,even,mark,space
            public byte StopBits;           // 0,1,2 = 1, 1.5, 2
            public char XonChar;            // Tx and Rx XON character
            public char XoffChar;           // Tx and Rx XOFF character
            public char ErrorChar;          // error replacement character
            public char EofChar;            // end of input character
            public char EvtChar;            // received event character
            public ushort wReserved1;         // reserved; do not use
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct COMMTIMEOUTS
        {
            public int ReadIntervalTimeout;
            public int ReadTotalTimeoutMultiplier;
            public int ReadTotalTimeoutConstant;
            public int WriteTotalTimeoutMultiplier;
            public int WriteTotalTimeoutConstant;
        }

        [StructLayout(LayoutKind.Sequential)]
        private struct OVERLAPPED
        {
            public int Internal;
            public int InternalHigh;
            public int Offset;
            public int OffsetHigh;
            public int hEvent;
        }

        [DllImport("kernel32.dll")]
        private static extern int CreateFile(
         string lpFileName,                         // file name
         uint dwDesiredAccess,                      // access mode
         int dwShareMode,                          // share mode
         int lpSecurityAttributes, // SD
         int dwCreationDisposition,                // how to create
         int dwFlagsAndAttributes,                 // file attributes
         int hTemplateFile                        // handle to template file
         );
        [DllImport("kernel32.dll")]
        private static extern bool GetCommState(
         int hFile,  // handle to communications device
         ref DCB lpDCB    // device-control block
         );
        [DllImport("kernel32.dll")]
        private static extern bool BuildCommDCB(
         string lpDef,  // device-control string
         ref DCB lpDCB     // device-control block
         );
        [DllImport("kernel32.dll")]
        private static extern bool SetCommState(
         int hFile,  // handle to communications device
         ref DCB lpDCB    // device-control block
         );
        [DllImport("kernel32.dll")]
        private static extern bool GetCommTimeouts(
         int hFile,                  // handle to comm device
         ref COMMTIMEOUTS lpCommTimeouts  // time-out values
         );
        [DllImport("kernel32.dll")]
        private static extern bool SetCommTimeouts(
         int hFile,                  // handle to comm device
         ref COMMTIMEOUTS lpCommTimeouts  // time-out values
         );
        [DllImport("kernel32.dll")]
        private static extern bool ReadFile(
         int hFile,                // handle to file
         byte[] lpBuffer,             // data buffer
         int nNumberOfBytesToRead,  // number of bytes to read
         ref int lpNumberOfBytesRead, // number of bytes read
         ref OVERLAPPED lpOverlapped    // overlapped buffer
         );
        [DllImport("kernel32.dll")]
        private static extern bool WriteFile(
         int hFile,                    // handle to file
         byte[] lpBuffer,                // data buffer
         int nNumberOfBytesToWrite,     // number of bytes to write
         ref int lpNumberOfBytesWritten,  // number of bytes written
         ref OVERLAPPED lpOverlapped        // overlapped buffer
         );
        [DllImport("kernel32.dll")]
        private static extern bool CloseHandle(
         int hObject   // handle to object
         );

        /// <summary>
        /// 打开串口
        /// </summary>
        public void Open()
        {

            DCB dcbCommPort = new DCB();
            COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS();


            // OPEN THE COMM PORT.


            hComm = CreateFile("COM" + iPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
            // IF THE PORT CANNOT BE OPENED, BAIL OUT.
            if (hComm == INVALID_HANDLE_VALUE)
            {
                Opened= false;
                throw (new ApplicationException("打开所选串口失败!!"));
            }
            else
            {
                // SET THE COMM TIMEOUTS.

                GetCommTimeouts(hComm, ref ctoCommPort);
                ctoCommPort.ReadTotalTimeoutConstant = iTimeout;
                ctoCommPort.ReadTotalTimeoutMultiplier = 0;
                ctoCommPort.WriteTotalTimeoutMultiplier = 0;
                ctoCommPort.WriteTotalTimeoutConstant = 0;
                SetCommTimeouts(hComm, ref ctoCommPort);

                // SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.
                // THERE ARE OTHER WAYS OF DOING SETTING THESE BUT THIS IS THE EASIEST.
                // IF YOU WANT TO LATER ADD CODE FOR OTHER BAUD RATES, REMEMBER
                // THAT THE ARGUMENT FOR BuildCommDCB MUST BE A POINTER TO A STRING.
                // ALSO NOTE THAT BuildCommDCB() DEFAULTS TO NO HANDSHAKING.

                dcbCommPort.DCBlength = Marshal.SizeOf(dcbCommPort);
                GetCommState(hComm, ref dcbCommPort);
                dcbCommPort.BaudRate =iRate ;
                dcbCommPort.Parity = bParity;
                dcbCommPort.ByteSize = (byte)bSize;
                dcbCommPort.StopBits = bStopBits;
                SetCommState(hComm, ref dcbCommPort);
                Opened= true;
            }
        }

        /// <summary>
        /// 关闭串口
        /// </summary>
        public void Close()
        {
            if (hComm != INVALID_HANDLE_VALUE)
            {
                CloseHandle(hComm);
                Opened = false;
            }
        }

        /// <summary>
        /// 从串口读取数据(返回读到的字节数组)
        /// </summary>
        /// <param name="NumBytes"></param>
        /// <returns></returns>
        public byte[] Read(int NumBytes)
        {
            byte[] BufBytes;
            byte[] OutBytes;
            BufBytes = new byte[NumBytes];
            if (hComm != INVALID_HANDLE_VALUE)
            {
                OVERLAPPED ovlCommPort = new OVERLAPPED();
                int BytesRead = 0;
                ReadFile(hComm, BufBytes, NumBytes, ref BytesRead, ref ovlCommPort);
                OutBytes = new byte[BytesRead];
                Array.Copy(BufBytes, OutBytes, BytesRead);
            }
            else
            {
                throw (new ApplicationException("串口没有打开"));
            }
            return OutBytes;
        }

        public string ReadS(int NumBytes)
        {
            byte[] BufBytes;
            byte[] OutBytes;
            BufBytes = new byte[NumBytes];
            if (hComm != INVALID_HANDLE_VALUE)
            {
                OVERLAPPED ovlCommPort = new OVERLAPPED();
                int BytesRead = 0;
                ReadFile(hComm, BufBytes, NumBytes, ref BytesRead, ref ovlCommPort);
                OutBytes = new byte[BytesRead];
                Array.Copy(BufBytes, OutBytes, BytesRead);
            }
            else
            {
                throw (new ApplicationException("串口没有打开"));
            }
            return System.Text.Encoding.Default.GetString(OutBytes);
        }

        /// <summary>
        /// 向串口发送指定数据(发送字节)
        /// </summary>
        /// <param name="WriteBytes"></param>
        /// <returns></returns>
        public int Write(byte[] WriteBytes)
        {
            int BytesWritten = 0;
            if (hComm != INVALID_HANDLE_VALUE)
            {
                OVERLAPPED ovlCommPort = new OVERLAPPED();
                WriteFile(hComm, WriteBytes, WriteBytes.Length, ref BytesWritten, ref ovlCommPort);
            }
            else
            {
                throw (new ApplicationException("串口没有打开"));
            }
            return BytesWritten;
        }

        /// <summary>
        /// 向串口发送指定数据(发送字符串)
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public int Write(string s)
        {
            byte[] WriteBytes = System.Text.Encoding.Default.GetBytes(s);
            int BytesWritten = 0;
            if (hComm != INVALID_HANDLE_VALUE)
            {
                OVERLAPPED ovlCommPort = new OVERLAPPED();
                WriteFile(hComm, WriteBytes, WriteBytes.Length, ref BytesWritten, ref ovlCommPort);
            }
            else
            {
                throw (new ApplicationException("串口没有打开"));
            }
            return BytesWritten;
        }
    }
}

二、测试实例
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using zhouxl.MyCom;
using System.IO;
namespace CommTest
{
    public partial class Form1 : Form
    {
        private MyCom mycom1;
        public byte[] recb;
        public Form1()
        {
            InitializeComponent();
        }

        //显示包信息
        public string dis_package(byte[] reb)
        {
            string temp = "";
            foreach (byte b in reb)
                temp += b.ToString("X2")+" ";
            return temp;
        }
        //打开串口
        public bool OpenCom()
        {
            try
            {
                if (mycom1.Opened)
                {
                    mycom1.Close();
                    mycom1.Open(); //打开串口
                }
                else
                {
                    mycom1.Open();//打开串口
                }
                return true;
            }
            catch (Exception e)
            {
                MessageBox.Show("错误:" + e.Message);
                return false;
            }

        }

        private void comboBox5_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //初始化端口列表
            ComPort.Items.Clear();
            ComPort.Items.Add("Com1");
            ComPort.Items.Add("Com2");
            ComPort.Items.Add("Com3");
            ComPort.Items.Add("Com4");
            ComPort.Items.Add("Com5");
            ComPort.Items.Add("Com6");
            ComPort.Items.Add("Com7");
            ComPort.Items.Add("Com8");
            ComPort.Items.Add("Com9");
            ComPort.DropDownStyle = ComboBoxStyle.DropDownList;
            ComPort.MaxDropDownItems = 9;
            ComPort.SelectedIndex = 0;

            //初始化波特率列表
            BaudRate.Items.Clear();
            BaudRate.Items.Add(110);
            BaudRate.Items.Add(300);
            BaudRate.Items.Add(1200);
            BaudRate.Items.Add(2400);
            BaudRate.Items.Add(4800);
            BaudRate.Items.Add(9600);
            BaudRate.Items.Add(19200);
            BaudRate.Items.Add(38400);
            BaudRate.Items.Add(57600);
            BaudRate.Items.Add(115200);
            BaudRate.Items.Add(230400);
            BaudRate.Items.Add(460800);
            BaudRate.Items.Add(921600);
            BaudRate.DropDownStyle = ComboBoxStyle.DropDownList;
            BaudRate.MaxDropDownItems = 13;
            BaudRate.SelectedIndex = 5;

            //初始化数据位
            DatBit.Items.Clear();
            DatBit.Items.Add(5);
            DatBit.Items.Add(6);
            DatBit.Items.Add(7);
            DatBit.Items.Add(8);
            DatBit.DropDownStyle = ComboBoxStyle.DropDownList;
            DatBit.MaxDropDownItems = 4;
            DatBit.SelectedIndex = 3;

            //初始化停止位
            Stopbit.Items.Clear();
            Stopbit.Items.Add(1);
            Stopbit.Items.Add(1.5);
            Stopbit.Items.Add(2);
            Stopbit.DropDownStyle = ComboBoxStyle.DropDownList;
            Stopbit.MaxDropDownItems = 3;
            Stopbit.SelectedIndex = 0;

            //初始化校验位 0-4=no,odd,even,mark,space
            Parity.Items.Clear();
            Parity.Items.Add("0-无(no)");
            Parity.Items.Add("1-奇(odd)");
            Parity.Items.Add("2-偶(even)");
            Parity.Items.Add("3-标识(mark)");
            Parity.Items.Add("4-空格(space)");
            Parity.DropDownStyle = ComboBoxStyle.DropDownList;
            Parity.MaxDropDownItems = 5;
            Parity.SelectedIndex = 0;

            //初始化流控制
            Flowctrl.Items.Clear();
            Flowctrl.Items.Add("Xon / Xoff");
            Flowctrl.Items.Add("硬件");
            Flowctrl.Items.Add("无");
            Flowctrl.DropDownStyle = ComboBoxStyle.DropDownList;
            Flowctrl.MaxDropDownItems = 3;
            Flowctrl.SelectedIndex = 2;

            //初始化串口
            mycom1 = new MyCom();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int c,b,d;
            byte p,s;
            c=ComPort.SelectedIndex; //串口号
            b=int.Parse(BaudRate.SelectedItem.ToString());//波特率
            d=int.Parse(DatBit.SelectedItem.ToString());//数据位
            p=byte.Parse(Parity.SelectedIndex.ToString());//奇偶校验位
            s=byte.Parse(Stopbit.SelectedIndex.ToString());//停止位
            
            //mycom1 = new MyCom();
            mycom1.IPort = c+1;
            mycom1.IRate = b;
            mycom1.BSize = d;
            mycom1.BParity = p;
            mycom1.BStopBits = s;

            if (OpenCom())
            {
                textBox3.AppendText("打开串口成功。。。/r/n");
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            mycom1.Close();
            textBox3.AppendText("/r/n串口被关闭……");
        }
        
        //字节转换为字符串
        private string byteTostring(byte[] bytes)
        {
            string s="";
            s = System.Text.Encoding.Default.GetString(bytes);
            return s;

        }
        //字符串转换成字节
        private byte[] stringTobyte(string s)
        {
            ArrayList al = new ArrayList();
            for (int i = 0; i < s.Length; i++)
            {
                al.Add((byte)s[i]);
            }
            return (byte[])al.ToArray(System.Type.GetType("System.Byte"));

            //或用下面语句
            //return System.Text.Encoding.Default.GetBytes(s);
        }
        //去掉发送数组中的空格
        public string delspace(string putin)
        {
            string putout = "";
            for (int i = 0; i < putin.Length; i++)
            {
                if (putin[i] != ' ')
                    putout += putin[i];
            }
            return putout;
        }

        //提取数据包
        public byte[] mysendb(string s)
        {
            string temps = delspace(s);
            if (temps.Length % 2 != 0)
                temps ="0"+temps;
            byte[] tempb = new byte[50];
            int j = 0;
            for (int i = 0; i < temps.Length; i = i + 2, j++)
                tempb[j] = Convert.ToByte(temps.Substring(i, 2), 16);
            byte[] send = new byte[j];
            Array.Copy(tempb, send, j);
            return send;
        }
        private void button3_Click(object sender, EventArgs e)
        {
                if (textBox1.Text=="")
                { MessageBox.Show("发送数据为空!"); return; }
                int sendnumb = 0;
                try
                {
                    if (checkBox1.Checked)
                    {
                        byte[] temp1 = mysendb(delspace(textBox1.Text)); //发送十六进制字符时用这行
                        sendnumb = mycom1.Write(temp1);
                        textBox3.AppendText("/r/n字节方式发送数据(" + sendnumb + "):" + dis_package(temp1));
                    }
                    else
                    {
                        sendnumb = mycom1.Write(textBox1.Text);
                        byte[] bytes = System.Text.Encoding.Default.GetBytes(textBox1.Text);//这行主要是为了显示编用。先编成字节数组,显示时再从数组解析成字符
                        textBox3.AppendText("/r/n字符串方式发送数据(" + sendnumb + "):" + System.Text.Encoding.Default.GetString(bytes));
                    }
                    
                }
                catch (Exception ex)
                { textBox3.AppendText(ex.Message + "/r/n"); return; }

        }

        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                byte[] recbs = mycom1.Read(1024);
                if (recbs.Length != 0)
                { textBox4.AppendText("/r/n接收到数据包:" + dis_package(recbs)); }
                else
                { textBox4.AppendText("/r/n接收到数据包("+recbs.Length.ToString()+"):" + dis_package(recbs)); }
            }
            catch (Exception ex)
            {
                textBox4.AppendText(ex.Message);
            }
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值