实例介绍
【实例简介】
串口 调试助手,实现了 接收、发送串口消息 功能
【实例截图】
【核心代码】
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.IO.Ports; namespace SerialComm { public partial class Form1 : Form { //=================================================== //申明全局变量。 public int CmdIdx = 0; //命令发送指针初始为0。 bool IsReceving = false; //接收数据标志。 bool DoingStr = false; //处理字符串标志。 bool DoingHex = false; //处理十六进制标志。 //=================================================== public Form1() { InitializeComponent(); } private void IntToHex() { try { int Int = int.Parse(tbDec.Text); string TempStr = Convert.ToString(Int, 16); while(TempStr.Length < 8 ) TempStr = '0' TempStr; tbHex.Text = TempStr.ToUpper(); tbDec.SelectAll(); } catch (Exception Err) { tbDec.SelectAll(); MessageBox.Show(Err.Message, "串口调试助手"); } } private void HexToInt() { try { int Int = Convert.ToInt32(tbHex.Text,16); tbDec.Text = Int.ToString(); tbHex.SelectAll(); } catch (Exception Err) { tbHex.SelectAll(); MessageBox.Show(Err.Message, "串口调试助手"); } } private void CmdClick(int idx) { //发送命令。 try { //自动打开端口。 if (!sComm.IsOpen) btOpen_Click(null, null); string TempStr = string.Empty; switch(idx) { case 1: TempStr = tbCmd1.Text; break; case 2: TempStr = tbCmd2.Text; break; case 3: TempStr = tbCmd3.Text; break; case 4: TempStr = tbCmd4.Text; break; case 5: TempStr = tbCmd5.Text; break; default: return; } TempStr = DelSpace(TempStr); if (cbDefFrm.Checked) //自动添加帧头帧尾和校验 { TempStr=DelSpace(tbStart.Text) TempStr; //加入头。 //转换为字节数组。 int Len=TempStr.Length; //待校验的字符串长度。 byte[] VerBin = new byte[Len / 2]; int j=0; for(int i=0;i<Len;i =2,j ) { VerBin[j] = Convert.ToByte(TempStr.Substring(i, 2), 16); } //计算校验字节。 byte VerByte=0; if (rdXor.Checked) { for (int i = 0; i < VerBin.Length; i ) VerByte ^= VerBin[i]; //异或校验。 } else if (rdAdd.Checked) { for (int i = 0; i < VerBin.Length; i ) VerByte = VerBin[i]; //和校验。 } //校验字节转为HEX字符串。 string VerStr = Convert.ToString(VerByte, 16); //合成一帧。 TempStr = TempStr DelSpace(VerStr) DelSpace(tbEnd.Text); } SendAsHex(TempStr); } catch (Exception err) { TimeHex.Stop(); TimeHex.Enabled = false; MessageBox.Show(err.Message, "串口调试助手"); cbTimeHex.Checked = false; } } private void ClrEncode() { lbHexData.Text = string.Empty; tbByte1.Text = string.Empty; tbByte2.Text = string.Empty; tbByte3.Text = string.Empty; tbByte4.Text = string.Empty; tbUInt16L.Text = string.Empty; tbUInt16R.Text = string.Empty; tbUInt32.Text = string.Empty; tbSByte1.Text = string.Empty; tbSByte2.Text = string.Empty; tbSByte3.Text = string.Empty; tbSByte4.Text = string.Empty; tbInt16L.Text = string.Empty; tbInt16R.Text = string.Empty; tbInt32.Text = string.Empty; } private void SendAsHex(string str) { int Len = str.Length; //组包发送。 byte[] send = new byte[Len / 2]; int j = 0; for (int i = 0; i < Len; i = i 2, j ) send[j] = Convert.ToByte(str.Substring(i, 2), 16); sComm.Write(send, 0, send.Length); } //清除空格。 private string DelSpace(string str) { string TempStr = string.Empty; int Len = str.Length; for (int i = 0; i < Len; i ) { if (str[i] != ' ') TempStr = str[i]; } //Hex 位数检查。 Len = TempStr.Length; if (Len % 2 != 0) TempStr = '0' TempStr; return TempStr; } //重新打开端口。 private void ReOpenPort() { try { btClose_Click(null,null); //重新打开通讯端口。 if (!sComm.IsOpen) btOpen_Click(null, null); } catch (Exception Err) { MessageBox.Show(Err.Message, "串口调试助手"); } } private void Form1_Load(object sender, EventArgs e) { try { foreach (string com in System.IO.Ports.SerialPort.GetPortNames()) //自动获取串行口名称 this.cmPort.Items.Add(com); cmPort.SelectedIndex = 0; } catch { MessageBox.Show("找不到通讯端口!", "串口调试助手"); } } private void OpenPort() { //***避免串口死锁*** sComm.WriteTimeout = 1000; //写超时,如果底层串口驱动效率问题,能有效的避免死锁。 sComm.ReadTimeout = 1000; //读超时,同上。 sComm.NewLine = "\r\n"; //回车换行。 sComm.DataReceived = new System.IO.Ports.SerialDataReceivedEventHandler(this.sComm_DataReceived); //注册事件。 //***避免串口死锁*** sComm.PortName = cmPort.Text; sComm.BaudRate = int.Parse(cmBaudRate.Text); sComm.DataBits = int.Parse(cmDataBit.Text); sComm.Parity = (Parity)Enum.Parse(typeof(Parity), cmParity.Text); sComm.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cmStopBit.Text); sComm.Open(); } private void ClosePort() { //安全关闭当前串口。 //***避免串口死锁*** sComm.DataReceived -= this.sComm_DataReceived; //注销串口中断接收事件,避免下次再执行进来,造成死锁。 while(IsReceving) Application.DoEvents(); //处理串口接收事件及其它系统消息。 sComm.Close(); //现在没有死锁,可以关闭串口。 //***避免串口死锁*** } private void StopAutoSend() { //停止自动发送字符串。 TimeStr.Stop(); TimeStr.Enabled = false; tbTimeStr.Enabled = true; cbTimeStr.Checked = false; //停止自动发送命令。 TimeHex.Stop(); TimeHex.Enabled = false; tbTimeHex.Enabled = true; cbTimeHex.Checked = false; } //=================================================== private void btOpen_Click(object sender, EventArgs e) { try { OpenPort(); //安全打开串口。 if (sComm.IsOpen) { btClose.Enabled = true; btOpen.Enabled = false; lbComStat.Text = "已打开 " Convert.ToString(sComm.PortName) ' ' Convert.ToString(sComm.BaudRate) ' ' Convert.ToString(sComm.DataBits) ' ' Convert.ToString(sComm.Parity) ' ' Convert.ToString(sComm.StopBits); tbSendStr.Focus(); } } catch (Exception er) { StopAutoSend(); //停止自动发送。 ClosePort(); //安全关闭当前串口。 MessageBox.Show("端口打开失败!" er.Message, "串口调试助手"); lbComStat.Text = "已关闭"; } } private void btSend_Click(object sender, EventArgs e) { //自动打开端口。 if (!sComm.IsOpen) btOpen_Click(null, null); //发送文本。 try { string txt = tbSendStr.Text; Byte[] EncodeByte = new byte[txt.Length * 2]; EncodeByte = Encoding.GetEncoding("GB2312").GetBytes(txt); int Len = EncodeByte.Length; sComm.Write(EncodeByte, 0, Len); } catch (Exception err) { MessageBox.Show(err.Message, "串口调试助手"); } } private void btClrSend_Click(object sender, EventArgs e) { tbSendStr.Text = string.Empty; } private void cmPort_MouseDown(object sender, MouseEventArgs e) { try { cmPort.Items.Clear(); foreach (string com in System.IO.Ports.SerialPort.GetPortNames()) //自动获取串行口名称 this.cmPort.Items.Add(com); } catch { MessageBox.Show("找不到通讯端口!", "串口调试助手"); } } private void sComm_DataReceived(object sender, SerialDataReceivedEventArgs e) { try { IsReceving = true; //***正在接收状态指示。 //读入收到的数据。 int Len = sComm.BytesToRead; if (Len < 1) { IsReceving = false; //***接收完成状态指示。 return; } byte[] data = new byte[Len]; sComm.Read(data, 0, Len); //字符串处理。 string Str = Encoding.GetEncoding("GB2312").GetString(data); //数据转十六进制字符串。 string Hex = string.Empty; for (int i = 0; i < data.Length; i ) { string tempstr = Convert.ToString(data[i], 16); if (tempstr.Length < 2) tempstr = '0' tempstr; Hex = tempstr ' '; } Hex = Hex.ToUpper(); //使用委托跨线程读取数据。 rtbRecStr.Invoke(new EventHandler(delegate { DoingStr = true; //***正在处理字符串。 rtbRecStr.AppendText(Str); if (cbAutoClr.Checked && rtbRecStr.Text.Length > 10000) rtbRecStr.Text = string.Empty; rtbRecStr.ScrollToCaret(); //将控件的内容滚动到当前位置。 DoingStr = false; } )); rtbRecHex.Invoke(new EventHandler(delegate { DoingHex = true; //***正在处理十六进制数据。 rtbRecHex.AppendText(Hex); if (cbAutoClr.Checked && rtbRecHex.Text.Length > 10000) rtbRecHex.Text = string.Empty; rtbRecHex.ScrollToCaret(); //将控件的内容滚动到当前位置。 DoingHex = false; } )); while(DoingStr || DoingHex) Application.DoEvents(); //处理串口接收事件及其它系统消息。 IsReceving =false; //***接收完成状态指示。 } catch (Exception Err) { MessageBox.Show(Err.Message, "串口调试助手"); } } private void btClrRec_Click(object sender, EventArgs e) { rtbRecStr.Text = string.Empty; rtbRecHex.Text = string.Empty; ClrEncode(); } private void rtbRecHex_MouseClick(object sender, MouseEventArgs e) { try { int idx = rtbRecHex.SelectionStart / 3; idx *= 3; if (rtbRecHex.Text.Length >= idx 4 * 3) { rtbRecHex.Select(idx, 4 * 3); string SubStr = rtbRecHex.Text.Substring(idx, 4 * 3); lbHexData.Text = SubStr; string[] TempStr = SubStr.Split(' '); string[] Frm=new string[4]; if(rdBig.Checked) { //直接拷贝。 Array.Copy(TempStr, Frm, Frm.Length); } else { //前后交换。 Frm[0] = TempStr[3]; Frm[1] = TempStr[2]; Frm[2] = TempStr[1]; Frm[3] = TempStr[0]; } //数据解码。 tbByte1.Text = Convert.ToString(Convert.ToByte(Frm[0], 16), 10); tbByte2.Text = Convert.ToString(Convert.ToByte(Frm[1], 16), 10); tbByte3.Text = Convert.ToString(Convert.ToByte(Frm[2], 16), 10); tbByte4.Text = Convert.ToString(Convert.ToByte(Frm[3], 16), 10); tbUInt16L.Text = Convert.ToString(Convert.ToUInt16(Frm[0] Frm[1], 16), 10); tbUInt16R.Text = Convert.ToString(Convert.ToUInt16(Frm[2] Frm[3], 16), 10); tbUInt32.Text = Convert.ToString(Convert.ToUInt32(Frm[0] Frm[1] Frm[2] Frm[3], 16), 10); tbSByte1.Text = Convert.ToString(Convert.ToSByte(Frm[0], 16), 10); tbSByte2.Text = Convert.ToString(Convert.ToSByte(Frm[1], 16), 10); tbSByte3.Text = Convert.ToString(Convert.ToSByte(Frm[2], 16), 10); tbSByte4.Text = Convert.ToString(Convert.ToSByte(Frm[3], 16), 10); tbInt16L.Text = Convert.ToString(Convert.ToInt16(Frm[0] Frm[1], 16), 10); tbInt16R.Text = Convert.ToString(Convert.ToInt16(Frm[2] Frm[3], 16), 10); tbInt32.Text = Convert.ToString(Convert.ToInt32(Frm[0] Frm[1] Frm[2] Frm[3], 16), 10); } else { ClrEncode(); } } catch (Exception Err) { MessageBox.Show(Err.Message, "串口调试助手"); } } private void rdBig_CheckedChanged(object sender, EventArgs e) { rtbRecHex_MouseClick(null, null); //重新刷新数据解码。 } private void cbDefFrm_CheckedChanged(object sender, EventArgs e) { if (cbDefFrm.Checked) { gpDefFrm.Enabled = true; } else { gpDefFrm.Enabled = false; } } private void cbTimeHex_CheckedChanged(object sender, EventArgs e) { try { if (cbTimeHex.Checked) { //禁止Str自动发送。 cbTimeStr.Checked = false; int t=int.Parse(tbTimeHex.Text); if (t < 5) { t = 5; tbTimeHex.Text = Convert.ToString(t,10); } //起动Hex自动发送。 tbTimeHex.Enabled = false; TimeHex.Enabled = true; TimeHex.Interval = t; TimeHex.Start(); } else { TimeHex.Stop(); TimeHex.Enabled = false; tbTimeHex.Enabled = true; } } catch (Exception Err) { MessageBox.Show("定时值不正确!" Err.Message, "串口调试助手"); } } private void cbTimeStr_CheckedChanged(object sender, EventArgs e) { try { if (cbTimeStr.Checked) { //禁止Hex自动发送。 cbTimeHex.Checked = false; int t = int.Parse(tbTimeStr.Text); if (t < 5) { t = 5; tbTimeStr.Text = Convert.ToString(t,10); } //启动Str自动发送。 tbTimeStr.Enabled = false; TimeStr.Enabled = true; TimeStr.Interval = t; TimeStr.Start(); } else { TimeStr.Stop(); TimeStr.Enabled = false; tbTimeStr.Enabled = true; } } catch (Exception Err) { MessageBox.Show("定时值不正确!" Err.Message, "串口调试助手"); } } private void btCmd1_Click(object sender, EventArgs e) { CmdClick(1); } private void btCmd2_Click(object sender, EventArgs e) { CmdClick(2); } private void btCmd3_Click(object sender, EventArgs e) { CmdClick(3); } private void btCmd4_Click(object sender, EventArgs e) { CmdClick(4); } private void btCmd5_Click(object sender, EventArgs e) { CmdClick(5); } private void cmPort_SelectedIndexChanged(object sender, EventArgs e) { ReOpenPort(); } private void cmBaudRate_SelectedIndexChanged(object sender, EventArgs e) { ReOpenPort(); } private void cmDataBit_SelectedIndexChanged(object sender, EventArgs e) { ReOpenPort(); } private void cmParity_SelectedIndexChanged(object sender, EventArgs e) { ReOpenPort(); } private void cmStopBit_SelectedIndexChanged(object sender, EventArgs e) { ReOpenPort(); } private void TimeHex_Tick(object sender, EventArgs e) { try { int[] Len ={ tbCmd1.Text.Length,tbCmd2.Text.Length,tbCmd3.Text.Length,tbCmd4.Text.Length,tbCmd5.Text.Length}; int j = 0; int OldIdx=CmdIdx; for (int i = OldIdx; i<OldIdx 5; i ) { CmdIdx %= 5; j = i % 5; if (CmdIdx == j) { CmdIdx ; if (Len[j] > 0) { CmdClick(CmdIdx); return; } } } } catch (Exception Err) { MessageBox.Show("定时发送错误!" Err.Message, "串口调试助手"); cbTimeHex.Checked = false; } } private void TimeStr_Tick(object sender, EventArgs e) { try { btSend_Click(null, null); } catch (Exception Err) { MessageBox.Show("定时发送错误!" Err.Message, "串口调试助手"); cbTimeStr.Checked = false; } } private void tbDec_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == '\r') //回车键 IntToHex(); //转换为Hex。 } private void tbDec_Leave(object sender, EventArgs e) { IntToHex(); } private void tbHex_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == '\r') //回车键 { while (tbHex.Text.Length < 8) tbHex.Text = '0' tbHex.Text; HexToInt(); //转换为Dec。 } } private void tbHex_Leave(object sender, EventArgs e) { while (tbHex.Text.Length < 8) tbHex.Text = '0' tbHex.Text; HexToInt(); //转换为Dec。 } private void btClose_Click(object sender, EventArgs e) { StopAutoSend(); //停止自动发送。 ClosePort(); //安全关闭串口。 if (!sComm.IsOpen) { btOpen.Enabled = true; btClose.Enabled = false; lbComStat.Text = "已关闭"; } } private void btQuit_Click(object sender, EventArgs e) { btClose_Click(null, null); this.Close(); } //=================================================== } }
相关软件
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论