实例介绍
【实例简介】
串口 调试助手,实现了 接收、发送串口消息 功能
【实例截图】
【核心代码】
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小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论