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
- C#3串口调试助手
- C#串口调试助手
- C#串口调试助手
- C#串口调试助手代码
- VS2010 C#串口调试助手
- c# 串口调试小助手(有源码)
- c#的串口开发调试助手
- C#编写的串口调试助手
- C# 串口编程二 应用--串口调试助手
- 串口调试助手源程序
- 串口调试助手源程序
- 串口调试助手源程序
- 串口调试助手源程序
- 串口调试助手使用说明
- 串口调试助手源程序
- WINCE 串口调试助手
- 几个串口调试助手
- 串口调试助手
- TopCoder入门教程 -- sqybi完善版
- 送给23岁的风华年少
- TypeScript编译器性能提升
- STL 中map的使用
- C#数据类型之引用类型
- C#3串口调试助手
- vs 中 cocos2d-x 中文乱码
- spring技术内幕18-Spring使用Hessian实现远程调用
- linux下解压命令大全
- 如何不同的是从JavaScript的Java
- mysq 语句l常见优化
- 一个百度员工的辞职后感
- 经纬财富:辽源做空的几招
- 用 jsp 写的 ajax 技术实现省市县等 n 级联动