串口调试小助手大体设计文档分析.docx
《串口调试小助手大体设计文档分析.docx》由会员分享,可在线阅读,更多相关《串口调试小助手大体设计文档分析.docx(22页珍藏版)》请在冰豆网上搜索。
串口调试小助手大体设计文档分析
C#编写串口调试小助手设计文档
/*********************************************************************/
/*文档名称:
C#编写串口调试小助手设计文档*/
/*操作系统:
win7X64*/
/*编译软件:
VirtualStudio2010*/
/*编译环境:
.NetFrameWork4.0*/
/*时间:
2014/7/24*/
/*Author:
软星包子*/
1.定义程序的的命名空间静态主函数(staticmain)
namespaceVCCom
{
staticclassProgram
///
///应用程序的主入口点。
[STAThread]
staticvoidMain()
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(newFormCOM());//定义程序启动默认加载的窗体
//可以通过修改FormCOM()来启动需要默认打开的窗体。
}
2.定义程序会用到的类包及全局变量
usingSystem.IO;
usingSystem.IO.Ports;
usingSystem.Threading;
//定义SerialPort对象
SerialPortSerialPortcom;
Thread_readThread;//用Thread线程类定义线程对象_readThread
bool_keepReading;
3.初始化窗体,初始化窗体控件属性与事件
publicFormCOM()
InitializeComponent();//该方法中包含窗体中所用空间的属性和事件
4.点击打开串口/关闭串口对应的Click事件处理
privatevoidbutton_OpenCOM_Click(objectsender,EventArgse)
//button_OpenCOM.Text=button_OpenCOM.Text=="打开串口"?
"关闭串口":
"打开串口";
if(button_OpenCOM.Text=="打开串口")//条件判断,如果按钮当前的文本为:
“打开串口”,则将它的文本改为“关闭串口”,同时将pictureBox1.Image属性更换为D:
\02.ico,但要保证图片的路径正确,否则会报异常。
button_OpenCOM.Text="关闭串口";
button_OpenCOM.BackColor=Color.HotPink;
Imageimg=Image.FromFile(@"D:
\02.ico");//路径要确保正确(位图文件放在“串口调试小助手目录下,需把文件放在D盘,或修改以上路径。
”)
//this.pictureBox1.Image.每次点击按钮pictureBox1都对更换图片
this.pictureBox1.Image=img;
Stringstr_PortName=boBox_ComName.Text.Trim();
SerialPortcom=newSerialPort();
SerialPortcom.BaudRate=Convert.ToInt32(boBox_Baudrate.Text.Trim());//波特率:
9600;//115200
SerialPortcom.PortName=boBox_ComName.Text.Trim();
try
SerialPortcom.Open();//打开串口}
catch(UnauthorizedAccessExceptionIOe)
//MessageBox.Show(IOe.Message);
//textBox_COMStatus.Text=IOe.Message;
this.listBox_TiShi.Items.Add(IOe.Message);
MessageBox.Show(boBox_ComName.Text.Trim()+"串口被占用");//以消息盒的形式弹出警告
return;
catch(IOExceptionIOe)
this.listBox_TiShi.Items.Add(str_PortName+"成功打开串口");
_keepReading=true;
_readThread=newThread(ReadPort);
//将读到的串口数据作为参数送给Thread线程,创建_readThread线程对象,来循环读取串口数据
_readThread.Start();
else
button_OpenCOM.BackColor=Color.DarkGray;
\01.ico");
_keepReading=false;
Thread.Sleep(100);
ClosePort(SerialPortcom);
a.打开端口/关闭串口事件处理所需要的函数
privatevoidshowCOMName()
string[]portList=System.IO.Ports.SerialPort.GetPortNames();//获取串口的名称
comboBox_ComName.Items.Clear();
for(inti=0;i{stringname=portList[i];boBox_ComName.Items.Add(name);}}//关闭串口的方法publicvoidClosePort(SerialPortport){if(port==null){this.listBox_TiShi.Items.Add("串口不存在");MessageBox.Show("串口不存在,请重新选择!");}try{port.Close();if(!port.IsOpen){//Console.WriteLine("串口已经被关闭!");this.listBox_TiShi.Items.Add(port.PortName+"成功关闭");}}catch(NullReferenceException){}}b.读取串口的事件处理,委托与线程privatevoidReadPort(){while(_keepReading){if(SerialPortcom.IsOpen){try{StringBuildercurrentline=newStringBuilder();//循环接收数据while(SerialPortcom.BytesToRead>0){charch=(char)SerialPortcom.ReadByte();currentline.Append(ch);}//StringSerialIn=System.Text.Encoding.ASCII.GetString(readBuffer,0,count);//在这里对接收到的数据进行处理//------------委托-------------------------this.textBox_Read.Invoke(//在拥有此控件的基础窗口句柄的线程上执行委托Invoke(Delegate)//即在textBox_ReceiveDate控件的父窗口form中执行委托.newMethodInvoker(/*表示一个委托,该委托可执行托管代码中声明为void且不接受任何参数的任何方法。在对控件的Invoke方法进行调用时或需要一个简单委托又不想自己定义时可以使用该委托。*/delegate{/*匿名方法,C#2.0的新功能,这是一种允许程序员将一段完整代码区块当成参数传递的程序代码编写技术,通过此种方法可以直接使用委托来设计事件响应程序以下就是你要在主线程上实现的功能但是有一点要注意,这里不适宜处理过多的方法,因为C#消息机制是消息流水线响应机制,如果这里在主线程上处理语句的时间过长会导致主UI线程阻塞,停止响应或响应不顺畅,这时你的主form界面会延迟或卡死*/if(currentline.ToString().Length>0){//this.textBox_Read.Text=currentline.ToString()+",";//this.richTextBox_Read.AppendText(currentline.ToString());if(checkBox_Show16_1.Checked){this.textBox_Read.Text=ClassFunctions.StrToHexStr(currentline.ToString());this.richTextBox_Read.AppendText(ClassFunctions.StrToHexStr(currentline.ToString()));}else{this.textBox_Read.Text=currentline.ToString();this.richTextBox_Read.AppendText(currentline.ToString());}}}));//----------委托end-------------------//this.textBox_Read.Text=currentline.ToString();currentline=newStringBuilder();}catch(Exceptionex){Console.WriteLine(ex.Message.ToString());}}else{TimeSpanwaitTime=newTimeSpan(0,0,0,0,500);//TimeSpan:(系统方法)将新的System.TimeSpan初始化为指定的天数、小时数、分钟数、秒数和毫秒数。Thread.Sleep(waitTime);//主线程休眠500ms等待子线程结束}}try{this.listBox_TiShi.Items.Add("线程退出");}catch(Exception){}} 5.初始化SerialPort对象,检测当前系统下可用端口,检测当前用户相关配置信息//初始化SerialPort对象方法.PortName为COM口名称,例如"COM1","COM2"等,注意是string类型publicvoidInitCOM(stringPortName){SerialPortcom=newSerialPort(PortName);SerialPortcom.BaudRate=Convert.ToInt32(boBox_Baudrate.Text.Trim());//波特率4800,9600,115200,256000SerialPortcom.Parity=Parity.None;//无奇偶校验位SerialPortcom.StopBits=StopBits.Two;//两个止位SerialPortcom.Handshake=Handshake.RequestToSend;//控制协议SerialPortcom.ReceivedBytesThreshold=4;//设置DataReceived事件发生前内部输入缓冲区中的字节数SerialPortcom.DataReceived+=newSerialDataReceivedEventHandler(port1_DataReceived);//DataReceived事件委托}6.DataReceived事件委托方法//DataReceived事件委托方法privatevoidOnDataReceived(objectsender,SerialDataReceivedEventArgse){try{StringBuildercurrentline=newStringBuilder();//循环接收数据while(SerialPortcom.BytesToRead>0){charch=(char)SerialPortcom.ReadByte();currentline.Append(ch);//文本追加}//在这里对接收到的数据进行处理this.textBox_Read.Invoke(//在拥有此控件的基础窗口句柄的线程上执行委托Invoke(Delegate)//即在textBox_ReceiveDate控件的父窗口form中执行委托.newMethodInvoker(/*表示一个委托,该委托可执行托管代码中声明为void且不接受任何参数的任何方法。在对控件的Invoke方法进行调用时或需要一个简单委托又不想自己定义时可以使用该委托。*/delegate{/*匿名方法,C#2.0的新功能,这是一种允许程序员将一段完整代码区块当成参数传递的程序代码编写技术,通过此种方法可以直接使用委托来设计事件响应程序以下就是你要在主线程上实现的功能但是有一点要注意,这里不适宜处理过多的方法,因为C#消息机制是消息流水线响应机制,如果这里在主线程上处理语句的时间过长会导致主UI线程阻塞,停止响应或响应不顺畅,这时你的主form界面会延迟或卡死*/this.textBox_Read.Text=currentline.ToString();//输出到主窗口文本控件this.richTextBox_Read.AppendText(currentline.ToString());//输出到主窗口文本控件+"\n"//this.textBox_Read.Text+="";}));//this.textBox_Read.Text=currentline.ToString();currentline=newStringBuilder();}catch(Exceptionex){Console.WriteLine(ex.Message.ToString());}}//DataReceived事件委托方法privatevoidport1_DataReceived(objectsender,SerialDataReceivedEventArgse){try{StringBuildercurrentline=newStringBuilder();//循环接收数据charch='0';while(SerialPortcom.BytesToRead>0){ch=(char)SerialPortcom.ReadByte();//currentline.Append(ch);}//在这里对接收到的数据进行处理////-------------------------------------//this.textBox_Read.Invoke(////在拥有此控件的基础窗口句柄的线程上执行委托Invoke(Delegate)////即在textBox_ReceiveDate控件的父窗口form中执行委托.//newMethodInvoker(///*表示一个委托,该委托可执行托管代码中声明为void且不接受任何参数的任何方法。在对控件的Invoke方法进行调用时或需要一个简单委托又不想自己定义时可以使用该委托。*///delegate//{///*匿名方法,C#2.0的新功能,这是一种允许程序员将一段完整代码区块当成参数传递的程序代码编写技术,通过此种方法可以直接使用委托来设计事件响应程序以下就是你要在主线程上实现的功能但是有一点要注意,这里不适宜处理过多的方法,因为C#消息机制是消息流水线响应机制,如果这里在主线程上处理语句的时间过长会导致主UI线程阻塞,停止响应或响应不顺畅,这时你的主form界面会延迟或卡死*/this.textBox_Read.AppendText(ch.ToString());//输出到主窗口文本控件this.textBox_Read.Text+="kk";currentline=newStringBuilder();}catch(Exceptionex){Console.WriteLine(ex.Message.ToString());}}7.数据发送事件处理privatevoidbutton_Send_Click(objectsender,EventArgse){Stringstr_Send=this.richTextBox_Send.Text;if(str_Send.Length>0){//this.WriteCom(SerialPortcom,str_Send,3);SendCommand(str_Send,SerialPortcom);}} //向串口发送数据publicvoidSendCommand(stringCommandString,SerialPortport){byte[]WriteBuffer=Encoding.ASCII.GetBytes(CommandString);//字符编码,继承自接口ICloneabletry{port.Write(WriteBuffer,0,WriteBuffer.Length);//port.Write(CommandString);}catch(Exceptione){MessageBox.Show("Exception:串口关闭或被占用\n"+e);//如果串口被关闭或被占用,以消息窗的形式提示“串口被关闭或被占用”,并打印异常。}}8.写数据操作,利用线程循环发送数据//////WriteCom(SerialPortCOMport,StringCommandString,intnum)写串口///参数:SerialPortCOMport:已打开的串口///StringCommandString:需要发送的数据,///intnum:循环发送次数,如果发送成功则忽略该参数///返回值:写成功则返回"0",//////publicStringWriteCom(SerialPortCOMport,StringCommandString,intnum){Stringstr_Return="-1";if((COMport==null)||(!COMport.IsOpen)){return"Com_Closed";}//try//{COMport.DiscardInBuffer();//serialPort.DiscardInBuffer();//清空接收缓冲区COMport.DiscardOutBuffer();{}CommandString=CommandString.Trim();if(CommandString.Length<1){str_Return="-1";}else{byte[]WriteBuffer=HexStringToByteArray(CommandString);for(inti=0;i{try{//COMport.Write(CommandString);//写指令,该指令返回00000068000000530000AC6716for(intk=0;k=null;k++){byte[]WriteBuffer_2=newbyte[1];WriteBuffer_2[0]=WriteBuffer[k];COMport.Write(WriteBuffer_2,0,WriteBuffer_2.Length);//写指令,该指令返回00000068000000530000AC6716//COMport.Write((WriteBuffe
stringname=portList[i];
boBox_ComName.Items.Add(name);
//关闭串口的方法
publicvoidClosePort(SerialPortport)
if(port==null)
this.listBox_TiShi.Items.Add("串口不存在");
MessageBox.Show("串口不存在,请重新选择!
");
port.Close();
if(!
port.IsOpen)
//Console.WriteLine("串口已经被关闭!
this.listBox_TiShi.Items.Add(port.PortName+"成功关闭");
catch(NullReferenceException)
b.读取串口的事件处理,委托与线程
privatevoidReadPort()
while(_keepReading)
if(SerialPortcom.IsOpen)
StringBuildercurrentline=newStringBuilder();
//循环接收数据
while(SerialPortcom.BytesToRead>0)
charch=(char)SerialPortcom.ReadByte();
currentline.Append(ch);
//StringSerialIn=System.Text.Encoding.ASCII.GetString(readBuffer,0,count);
//在这里对接收到的数据进行处理
//------------委托-------------------------
this.textBox_Read.Invoke(
//在拥有此控件的基础窗口句柄的线程上执行委托Invoke(Delegate)
//即在textBox_ReceiveDate控件的父窗口form中执行委托.
newMethodInvoker(
/*表示一个委托,该委托可执行托管代码中声明为void且不接受任何参数的任何方法。
在对控件的Invoke方法进行调用时或需要一个简单委托又不想自己定义时可以使用该委托。
*/
delegate
/*匿名方法,C#2.0的新功能,这是一种允许程序员将一段完整代码区块当成参数传递的程序代码编写技术,通过此种方法可以直接使用委托来设计事件响应程序以下就是你要在主线程上实现的功能但是有一点要注意,这里不适宜处理过多的方法,因为C#消息机制是消息流水线响应机制,如果这里在主线程上处理语句的时间过长会导致主UI线程阻塞,停止响应或响应不顺畅,这时你的主form界面会延迟或卡死*/
if(currentline.ToString().Length>0)
//this.textBox_Read.Text=currentline.ToString()+",";
//this.richTextBox_Read.AppendText(currentline.ToString());
if(checkBox_Show16_1.Checked)
this.textBox_Read.Text=ClassFunctions.StrToHexStr(currentline.ToString());
this.richTextBox_Read.AppendText(ClassFunctions.StrToHexStr(currentline.ToString()));
this.textBox_Read.Text=currentline.ToString();
this.richTextBox_Read.AppendText(currentline.ToString());
)
);
//----------委托end-------------------
//this.textBox_Read.Text=currentline.ToString();
currentline=newStringBuilder();
catch(Exceptionex)
Console.WriteLine(ex.Message.ToString());
TimeSpanwaitTime=newTimeSpan(0,0,0,0,500);
//TimeSpan:
(系统方法)将新的System.TimeSpan初始化为指定的天数、小时数、分钟数、秒数和毫秒数。
Thread.Sleep(waitTime);
//主线程休眠500ms等待子线程结束
this.listBox_TiShi.Items.Add("线程退出");
catch(Exception)
5.初始化SerialPort对象,检测当前系统下可用端口,检测当前用户相关配置信息
//初始化SerialPort对象方法.PortName为COM口名称,例如"COM1","COM2"等,注意是string类型
publicvoidInitCOM(stringPortName)
SerialPortcom=newSerialPort(PortName);
SerialPortcom.BaudRate=Convert.ToInt32(boBox_Baudrate.Text.Trim());
//波特率4800,9600,115200,256000
SerialPortcom.Parity=Parity.None;//无奇偶校验位
SerialPortcom.StopBits=StopBits.Two;//两个止位
SerialPortcom.Handshake=Handshake.RequestToSend;//控制协议
SerialPortcom.ReceivedBytesThreshold=4;//设置DataReceived事件发生前内部输入缓冲区中的字节数
SerialPortcom.DataReceived+=newSerialDataReceivedEventHandler(port1_DataReceived);//DataReceived事件委托
6.DataReceived事件委托方法
//DataReceived事件委托方法
privatevoidOnDataReceived(objectsender,SerialDataReceivedEventArgse)
currentline.Append(ch);//文本追加
this.textBox_Read.Text=currentline.ToString();//输出到主窗口文本控件
this.richTextBox_Read.AppendText(currentline.ToString());//输出到主窗口文本控件+"\n"
//this.textBox_Read.Text+="";
privatevoidport1_DataReceived(objectsender,SerialDataReceivedEventArgse)
charch='0';
ch=(char)SerialPortcom.ReadByte();//
//
//-------------------------------------
//this.textBox_Read.Invoke(
////在拥有此控件的基础窗口句柄的线程上执行委托Invoke(Delegate)
////即在textBox_ReceiveDate控件的父窗口form中执行委托.
//newMethodInvoker(
///*表示一个委托,该委托可执行托管代码中声明为void且不接受任何参数的任何方法。
//delegate
//{
///*匿名方法,C#2.0的新功能,这是一种允许程序员将一段完整代码区块当成参数传递的程序代码编写技术,通过此种方法可以直接使用委托来设计事件响应程序以下就是你要在主线程上实现的功能但是有一点要注意,这里不适宜处理过多的方法,因为C#消息机制是消息流水线响应机制,如果这里在主线程上处理语句的时间过长会导致主UI线程阻塞,停止响应或响应不顺畅,这时你的主form界面会延迟或卡死*/
this.textBox_Read.AppendText(ch.ToString());//输出到主窗口文本控件
this.textBox_Read.Text+="kk";
7.数据发送事件处理
privatevoidbutton_Send_Click(objectsender,EventArgse)
Stringstr_Send=this.richTextBox_Send.Text;
if(str_Send.Length>0)
//this.WriteCom(SerialPortcom,str_Send,3);
SendCommand(str_Send,SerialPortcom);
//向串口发送数据
publicvoidSendCommand(stringCommandString,SerialPortport)
byte[]WriteBuffer=Encoding.ASCII.GetBytes(CommandString);//字符编码,继承自接口ICloneable
port.Write(WriteBuffer,0,WriteBuffer.Length);
//port.Write(CommandString);
catch(Exceptione)
MessageBox.Show("Exception:
串口关闭或被占用\n"+e);
//如果串口被关闭或被占用,以消息窗的形式提示“串口被关闭或被占用”,并打印异常。
8.写数据操作,利用线程循环发送数据
///WriteCom(SerialPortCOMport,StringCommandString,intnum)写串口
///参数:
SerialPortCOMport:
已打开的串口
///StringCommandString:
需要发送的数据,
///intnum:
循环发送次数,如果发送成功则忽略该参数
///返回值:
写成功则返回"0",
publicStringWriteCom(SerialPortCOMport,StringCommandString,intnum)
Stringstr_Return="-1";
if((COMport==null)||(!
COMport.IsOpen))
return"Com_Closed";
//try
COMport.DiscardInBuffer();//serialPort.DiscardInBuffer();
//清空接收缓冲区
COMport.DiscardOutBuffer();
CommandString=CommandString.Trim();
if(CommandString.Length<1)
str_Return="-1";
byte[]WriteBuffer=HexStringToByteArray(CommandString);
for(inti=0;i{try{//COMport.Write(CommandString);//写指令,该指令返回00000068000000530000AC6716for(intk=0;k=null;k++){byte[]WriteBuffer_2=newbyte[1];WriteBuffer_2[0]=WriteBuffer[k];COMport.Write(WriteBuffer_2,0,WriteBuffer_2.Length);//写指令,该指令返回00000068000000530000AC6716//COMport.Write((WriteBuffe
//COMport.Write(CommandString);
//写指令,该指令返回00000068000000530000AC6716
for(intk=0;k=null;k++){byte[]WriteBuffer_2=newbyte[1];WriteBuffer_2[0]=WriteBuffer[k];COMport.Write(WriteBuffer_2,0,WriteBuffer_2.Length);//写指令,该指令返回00000068000000530000AC6716//COMport.Write((WriteBuffe
=null;k++)
byte[]WriteBuffer_2=newbyte[1];
WriteBuffer_2[0]=WriteBuffer[k];
COMport.Write(WriteBuffer_2,0,WriteBuffer_2.Length);
//COMport.Write((WriteBuffe
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1