C#3串口调试助手

来源:互联网 发布:下载主题中心软件 编辑:程序博客网 时间:2024/04/28 09:07

这个是简单的小串口调试助手,主要是数据接收和数据发送,有些地方我也不懂,刚学C#.请大家多多指教

数据的收发都可以实现,好像十六进制显示和收发不太好,如果大家有改进的欢迎讨论。谢谢。

当时第一次做的时候,好多控件都不能用,那是因为我没绑定事件,请刚学的小伙伴们不要犯一样的错误哦。

事件就是这个了。


下面贴上代码:

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.IO.Ports;using System.IO;using System.Reflection;using System.Threading;namespace serialport{    public partial class Form1 : Form    {        #region 变量及委托声明        // 关闭标志,表示串口正在关闭        private bool closing = false;        //监听标志, 用于安全关闭串口        private bool listening = false;        //累计接收字节        private long receiveCount = 0;        //累计发送字节        private long sendCount = 0;        //委托,用于跨线程调用        delegate void InvokeTextPaly(string text);        //List,用于二进制数据包的缓存,也可用数组缓存        private List<byte> bufferRead = new List<byte>(4096);        //数组,用于缓存一个长度完整的数据包        byte[] dataCatchedArry = new byte[9];        #endregion        #region  CRC16校验码索引数组        private byte[] crcHiArry =         {   0x00,  0xC1,  0x81,  0x40,  0x01,  0xC0,  0x80,  0x41,  0x01,  0xC0,  0x80, 0x41,             0x00, 0xC1, 0x81,             0x40,  0x01,  0xC0,  0x80,  0x41,  0x00,  0xC1,  0x81,  0x40,  0x00,  0xC1, 0x81,             0x40, 0x01, 0xC0,             0x80,  0x41,  0x01,  0xC0,  0x80,  0x41,  0x00,  0xC1,  0x81,  0x40,  0x00, 0xC1,             0x81, 0x40, 0x01,             0xC0,  0x80,  0x41,  0x00,  0xC1,  0x81,  0x40,  0x01,  0xC0,  0x80,  0x41, 0x01,             0xC0, 0x80, 0x41,             0x00,  0xC1,  0x81,  0x40,  0x01,  0xC0,  0x80,  0x41,  0x00,  0xC1,  0x81, 0x40,            0x00, 0xC1, 0x81,             0x40,  0x01,  0xC0,  0x80,  0x41,  0x00,  0xC1,  0x81,  0x40,  0x01,  0xC0, 0x80,             0x41, 0x01, 0xC0,             0x80,  0x41,  0x00,  0xC1,  0x81,  0x40,  0x00,  0xC1,  0x81,  0x40,  0x01, 0xC0,             0x80, 0x41, 0x01,             0xC0,  0x80,  0x41,  0x00,  0xC1,  0x81,  0x40,  0x01,  0xC0,  0x80,  0x41, 0x00,             0xC1, 0x81, 0x40,             0x00,  0xC1,  0x81,  0x40,  0x01,  0xC0,  0x80,  0x41,  0x01,  0xC0,  0x80, 0x41,             0x00, 0xC1, 0x81,             0x40,  0x00,  0xC1,  0x81,  0x40,  0x01,  0xC0,  0x80,  0x41,  0x00,  0xC1, 0x81,             0x40, 0x01, 0xC0,             0x80,  0x41,  0x01,  0xC0,  0x80,  0x41,  0x00,  0xC1,  0x81,  0x40,  0x00, 0xC1,             0x81, 0x40, 0x01,             0xC0,  0x80,  0x41,  0x01,  0xC0,  0x80,  0x41,  0x00,  0xC1,  0x81,  0x40, 0x01,             0xC0, 0x80, 0x41,             0x00,  0xC1,  0x81,  0x40,  0x00,  0xC1,  0x81,  0x40,  0x01,  0xC0,  0x80, 0x41,             0x00, 0xC1, 0x81,             0x40,  0x01,  0xC0,  0x80,  0x41,  0x01,  0xC0,  0x80,  0x41,  0x00,  0xC1, 0x81,             0x40, 0x01, 0xC0,             0x80,  0x41,  0x00,  0xC1,  0x81,  0x40,  0x00,  0xC1,  0x81,  0x40,  0x01, 0xC0,             0x80, 0x41, 0x01,             0xC0,  0x80,  0x41,  0x00,  0xC1,  0x81,  0x40,  0x00,  0xC1,  0x81,  0x40, 0x01,             0xC0, 0x80, 0x41,             0x00,  0xC1,  0x81,  0x40,  0x01,  0xC0,  0x80,  0x41,  0x01,  0xC0,  0x80, 0x41,             0x00, 0xC1, 0x81,             0x40 };        private byte[] crcLoArry =         {         0x00,  0xC0,  0xC1,  0x01,  0xC3,  0x03,  0x02,  0xC2,  0xC6,  0x06,  0x07, 0xC7,         0x05, 0xC5, 0xC4,        0x04,  0xCC,  0x0C,  0x0D,  0xCD,  0x0F,  0xCF,  0xCE,  0x0E,  0x0A,  0xCA, 0xCB,         0x0B, 0xC9, 0x09,        0x08,  0xC8,  0xD8,  0x18,  0x19,  0xD9,  0x1B,  0xDB,  0xDA,  0x1A,  0x1E, 0xDE,         0xDF, 0x1F, 0xDD,        0x1D,  0x1C,  0xDC,  0x14,  0xD4,  0xD5,  0x15,  0xD7,  0x17,  0x16,  0xD6, 0xD2,         0x12, 0x13, 0xD3,        0x11,  0xD1,  0xD0,  0x10,  0xF0,  0x30,  0x31,  0xF1,  0x33,  0xF3,  0xF2, 0x32,         0x36, 0xF6, 0xF7,        0x37,  0xF5,  0x35,  0x34,  0xF4,  0x3C,  0xFC,  0xFD,  0x3D,  0xFF,  0x3F, 0x3E,         0xFE, 0xFA, 0x3A,        0x3B,  0xFB,  0x39,  0xF9,  0xF8,  0x38,  0x28,  0xE8,  0xE9,  0x29,  0xEB, 0x2B,         0x2A, 0xEA, 0xEE,        0x2E,  0x2F,  0xEF,  0x2D,  0xED,  0xEC,  0x2C,  0xE4,  0x24,  0x25,  0xE5, 0x27,         0xE7, 0xE6, 0x26,        0x22,  0xE2,  0xE3,  0x23,  0xE1,  0x21,  0x20,  0xE0,  0xA0,  0x60,  0x61, 0xA1,         0x63, 0xA3, 0xA2,        0x62,  0x66,  0xA6,  0xA7,  0x67,  0xA5,  0x65,  0x64,  0xA4,  0x6C,  0xAC, 0xAD,         0x6D, 0xAF, 0x6F,        0x6E,  0xAE,  0xAA,  0x6A,  0x6B,  0xAB,  0x69,  0xA9,  0xA8,  0x68,  0x78, 0xB8,         0xB9, 0x79, 0xBB,        0x7B,  0x7A,  0xBA,  0xBE,  0x7E,  0x7F,  0xBF,  0x7D,  0xBD,  0xBC,  0x7C, 0xB4,         0x74, 0x75, 0xB5,        0x77,  0xB7,  0xB6,  0x76,  0x72,  0xB2,  0xB3,  0x73,  0xB1,  0x71,  0x70, 0xB0,         0x50, 0x90, 0x91,        0x51,  0x93,  0x53,  0x52,  0x92,  0x96,  0x56,  0x57,  0x97,  0x55,  0x95, 0x94,         0x54, 0x9C, 0x5C,        0x5D,  0x9D,  0x5F,  0x9F,  0x9E,  0x5E,  0x5A,  0x9A,  0x9B,  0x5B,  0x99, 0x59,         0x58, 0x98, 0x88,        0x48,  0x49,  0x89,  0x4B,  0x8B,  0x8A,  0x4A,  0x4E,  0x8E,  0x8F,  0x4F, 0x8D,         0x4D, 0x4C, 0x8C,        0x44,  0x84,  0x85,  0x45,  0x87,  0x47,  0x46,  0x86 ,  0x82,  0x42,  0x43, 0x83,         0x41, 0x81, 0x80,        0x40};        #endregion        #region 窗口函数        public Form1()        {            InitializeComponent();        }        private void Form1_Load(object sender, EventArgs e)        {            GetPortName();            if (comboBox_portName.Text == "")                comboBox_portName.Text = "COM1";            if (comboBox_dataBits.Text == "")                comboBox_dataBits.Text = "8";            if (comboBox_stopBits.Text == "")                comboBox_stopBits.Text = "1";            if (comboBox_rate.Text == "")                comboBox_rate.Text = "9600";            if (comboBox_paity.Text == "")                comboBox_paity.Text = "None";            OpenSerialPort();            checkBox_hexSend_CheckedChanged(null, null);       //加载默认设置并配置            checkBox_autoSend_CheckedChanged(null, null);            //checkBox_wrap_CheckedChanged(null, null);        }        #endregion        #region 初始化打开串口        //获取当前串口名        private void GetPortName()        {            comboBox_portName.Items.Clear();            string[] portNames = SerialPort.GetPortNames();            foreach (string name in portNames)            {                if (name != "")                    comboBox_portName.Items.Add(name);            }            comboBox_portName.Text = global ::serialport.Properties.Settings.Default.PortName;          }        //打开串口        private void OpenSerialPort()        {            if (serialPort1.IsOpen)            {                return;            }            try            {                CheckConfig();                serialPort1.Open();                if (serialPort1.IsOpen)                {                    button_openClosePort.Text = "关闭串口";                    label_powerLed.ForeColor = Color.Lime;                    Label_mainMessage.ForeColor = Color.Green;                    Label_mainMessage.Text = serialPort1.PortName + "已打开";                }            }            catch            {                Label_mainMessage.ForeColor = Color.Red;                Label_mainMessage.Text = "串口打开失败!";            }        }        //关闭串口        private void CloseSerialPort()        {            if (!serialPort1.IsOpen)            {                return;            }            try            {                closing = true;                while (listening)                    Application.DoEvents();                serialPort1.Close();                closing = false;                if (!serialPort1.IsOpen)                {                    button_openClosePort.Text = "打开串口";                    label_powerLed.ForeColor = Color.DarkGray;                    Label_mainMessage.ForeColor = Color.Green;                    Label_mainMessage.Text = serialPort1.PortName + "已关闭";                }            }            catch            {                Label_mainMessage.ForeColor = Color.Red;                Label_mainMessage.Text = "串口关闭失败!";            }        }        //每次打开串口前需要重新检测参数并配置        private void CheckConfig()        {            comboBox_portName_TextChanged(null, null);            comboBox_rate_TextChanged(null, null);            comboBox_dataBits_TextChanged(null, null);            comboBox_stopBits_TextChanged(null, null);            comboBox_paity_TextChanged(null, null);            //  checkBox_RTS_CheckedChanged(null, null);            // checkBox_DTR_CheckedChanged(null, null);        }        //用于刷新端口名称        private void comboBox_portName_MouseDown(object sender, MouseEventArgs e)        {            GetPortName();        }        private void comboBox_portName_TextChanged(object sender, EventArgs e)        {            try            {                if (serialPort1.IsOpen)                {                    CloseSerialPort();                    CheckConfig();                    //  serialPort1.PortName = comboBox_portName.Text;                    OpenSerialPort();                }                else                {                    serialPort1.PortName = comboBox_portName.Text;                }            }            catch            {                //Label_mainMessage.ForeColor = Color.Red;                //Label_mainMessage.Text = "串口号配置错误!";            }        }        private void comboBox_rate_TextChanged(object sender, EventArgs e)        {            try            {                serialPort1.BaudRate = Convert.ToInt32(comboBox_rate.Text);            }            catch            {                Label_mainMessage.Text = "波特率配置错误!";            }        }        private void comboBox_dataBits_TextChanged(object sender, EventArgs e)        {            try            {                serialPort1.DataBits = Convert.ToInt32(comboBox_dataBits.Text);            }            catch            {                Label_mainMessage.Text = "数据位配置错误!";            }        }        private void comboBox_stopBits_TextChanged(object sender, EventArgs e)        {            try            {                if (comboBox_stopBits.Text == "1")                    serialPort1.StopBits = StopBits.One;                else if (comboBox_stopBits.Text == "1.5")                    serialPort1.StopBits = StopBits.OnePointFive;                else if (comboBox_stopBits.Text == "2")                    serialPort1.StopBits = StopBits.Two;            }            catch            {                Label_mainMessage.Text = "停止位配置错误!";            }        }        private void comboBox_paity_TextChanged(object sender, EventArgs e)        {            try            {                switch (comboBox_paity.Text)                {                    case "None":                        serialPort1.Parity = Parity.None; break;                    case "Odd":                        serialPort1.Parity = Parity.Odd; break;                    case "Even":                        serialPort1.Parity = Parity.Even; break;                    case "Mark":                        serialPort1.Parity = Parity.Mark; break;                    case "Space":                        serialPort1.Parity = Parity.Space; break;                }            }            catch            {                Label_mainMessage.Text = "校验位配置错误!";            }        }        /*     private void checkBox_RTS_CheckedChanged(object sender, EventArgs e)             {                 serialPort1.DtrEnable = checkBox_DTR.Checked;             }             private void checkBox_DTR_CheckedChanged(object sender, EventArgs e)             {                 serialPort1.RtsEnable = checkBox_RTS.Checked;             }             */        //串口开关按钮 Click事件        private void button_openClosePort_Click(object sender, EventArgs e)        {            if (button_openClosePort.Text == "打开串口")                OpenSerialPort();            else                CloseSerialPort();        }        //点击help,弹出新窗口        private void label_help_Click(object sender, EventArgs e)        {        }              #endregion        #region 数据接收        //跨线程更新控件,用于显示串口接收到的数据         private void AppenTextBox(string text)        {            if (textBox_receive.InvokeRequired)            {                InvokeTextPaly d = new InvokeTextPaly(AppenTextBox);   //声明并初始化委托                this.Invoke(d, new object[] { text });            }            else            {                Label_receiveCount.Text = receiveCount.ToString();                if (button_stopOn.Text == "恢复显示") //表示当前暂停显示,窗口不再更新数据                    return;                if (checkBox_wrap.Checked)   //每次获得的数据之间是否换行                    textBox_receive.AppendText(text + "\r\n");                else                    textBox_receive.AppendText(text);            }        }        //串口接收中断事件        //清除窗口        private void button_clear_Click(object sender, EventArgs e)        {            textBox_receive.Clear();            receiveCount = sendCount = 0;            Label_receiveCount.Text = Label_sendCount.Text = "0";        }        //显示格式 CheckedChang事件        private void check_hexPlay_CheckedChanged(object sender, EventArgs e)        {            //PS:太乱了,尝试更简单有效的代码            StringBuilder buildHexPlay = new StringBuilder();            if (textBox_receive.Text.Length == 0)  //窗口为空,不需要转换                return;            if (check_hexPlay.Checked)   //将字符转换为HEX格式显示            {                char[] bufString = new char[textBox_receive.Text.Length];                bufString = textBox_receive.Text.ToArray();                foreach (char c in bufString)                {                    if (c == '\r' || c == '\n')                        continue;  //过滤自动换行添加的回车符号,BUG:同时会把有效的回车符号也过滤掉                    buildHexPlay.Append(Convert.ToString(Convert.ToByte(c), 16) + " ");                }                textBox_receive.Text = buildHexPlay.ToString().ToUpper();            }            else  //将HEX转为字符显示            {                string[] bufString = new string[textBox_receive.Text.Length];                char[] split = { ' ', '\n', '\r' };    //将空格,回车符过滤,BUF:可能存在                bufString = textBox_receive.Text.Trim().Split(split);                foreach (string ss in bufString)                {                    if (ss != "")  //由于有回车符"\r\n"存在,所以得到的SS可能为""                        buildHexPlay.Append(Convert.ToChar(Convert.ToByte(ss, 16)));                }                textBox_receive.Text = buildHexPlay.ToString();            }        }        #endregion        #region 数据发送           //添加CRC16校验码        private void addCRC16(ref List<byte> sendhex)        {            byte crcHi = 0xff;            byte crcLo = 0xff;            byte index = 0;            for (int i = 0; i < sendhex.Count; i++)            {                index = Convert.ToByte(sendhex[i] ^ crcLo);                crcLo = Convert.ToByte(crcHi ^ crcHiArry[index]);                crcHi = crcLoArry[index];            }            sendhex.Add(crcLo);            sendhex.Add(crcHi);            //return Convert.ToUInt16((crcHi << 8 | crcLo));        }       //发送按钮 Click事件          private void button_send_Click(object sender, EventArgs e)          {              if (!serialPort1.IsOpen)              {                  Label_mainMessage.ForeColor = Color.Red;                  Label_mainMessage.Text = "串口未打开!";                  return;              }            StringBuilder buildSend = new StringBuilder();           // buildSend.Clear();               int count = 0;    //发送字符的长度              try              {                  if (checkBox_hexSend.Checked)   //发送16进制                  {                      List<byte> bufferSend = new List<byte>();                     // buildSend.Clear();                                       string sendSting = textBox_sendString.Text.Trim(); //删去前导和后置空格符                      string s = "";                      while (sendSting.Length > 1)   //奇数个16进制数据最后一个被抛弃                      {                          s = sendSting.Substring(0, 2);                          buildSend.Append(s + " ");                          bufferSend.Add(Convert.ToByte(s, 16));   //将字符s 如“1A” 转化为字节31,送入字节列表BufferSend                          sendSting = sendSting.Remove(0, 2);                          sendSting = sendSting.Trim();  //删去前导空格符                      }                      textBox_sendString.Text = buildSend.ToString().ToUpper(); //格式化显示发送的数据                    if (checkBox_CRC16.Checked)   //加上了CRC16校验码,并将完整的报文显示在另一个TEXTBOX上                      {                          addCRC16(ref bufferSend);                         // buildSend.Clear();                          foreach (byte b in bufferSend.ToArray())                          {                              buildSend.Append(b.ToString("X2") + " ");                          }                        //  textBox_dataCatched.Text = buildSend.ToString().ToUpper();                      }                      serialPort1.Write(bufferSend.ToArray(), 0, bufferSend.ToArray().Length);                      count = bufferSend.Count;                  }                  else  //asc编码直接发送,发送字符                  {                    /*  if (checkBox_sendNewLine.Checked)  //发送新行                      {                          serialPort1.WriteLine(textBox_sendString.Text);                          count = textBox_sendString.Text.Length + 2;                      }                      else                      {*/                          serialPort1.Write(textBox_sendString.Text);                          count = textBox_sendString.Text.Length;                  //    }                  }                  sendCount += count;                  Label_sendCount.Text = sendCount.ToString();                  //也可直接使用用LABEL.TEXT的值来表示,少一个全局变量,其实LABEL.TEXT对于主窗口就是一个全局变量                  //Label_sendCount.Text = Convert .ToString ( Convert.ToInt64(Label_sendCount.Text) + count );  //原来长度加上新发送的长度              }              catch              {                  MessageBox.Show("发送失败,请检查发送数据是否正确!", "提示");              }          }          //16进制发送 CheckedChanged事件          private void checkBox_hexSend_CheckedChanged(object sender, EventArgs e)          {                      }                    //自动发送 CheckedChanged事件        private void checkBox_autoSend_CheckedChanged(object sender, EventArgs e)        {            if (checkBox_autoSend.Checked)            {                numericUpDown_period.Enabled = false;                timer1.Interval = (int)numericUpDown_period.Value;                timer1.Start();            }            else            {                numericUpDown_period.Enabled = true;                timer1.Stop();            }        }        //定时器1触发事件,用于自动发送        private void timer1_Tick(object sender, EventArgs e)        {                if (serialPort1.IsOpen)                     button_send_Click(null, null);            timer1.Interval = (int)numericUpDown_period.Value;        }        //按键检测,用于检测16进制输入数据是否有效        private void textBox_sendString_KeyPress(object sender, KeyPressEventArgs e)        {            if (checkBox_hexSend.Checked)            {            }            else            {            }        }        //暂停显示按钮 Click事件        private void button_stopOn_Click(object sender, EventArgs e)        {            button_stopOn.Text = (button_stopOn.Text == "暂停显示") ? "恢复显示" : "暂停显示";        }        #endregion    }}
PS:这个代码是在师兄给我代码的基础上实现的,如果师兄看见了请不要拍我可怜



0 0
原创粉丝点击