c上位机串口通信助手源代码详解.docx
- 文档编号:7390898
- 上传时间:2023-01-23
- 格式:DOCX
- 页数:24
- 大小:56.58KB
c上位机串口通信助手源代码详解.docx
《c上位机串口通信助手源代码详解.docx》由会员分享,可在线阅读,更多相关《c上位机串口通信助手源代码详解.docx(24页珍藏版)》请在冰豆网上搜索。
c上位机串口通信助手源代码详解
Forpersonaluseonlyinstudyandresearch;notforcommercialuse
c#上位机串口通信助手源代码实例详解
一、功能
1软件打开时,自动检测有效COM端口
2软件打开时,自动复原到上次关闭时的状态
3不必关闭串口,即可直接进行更改初始化设置内容(串口号、波特率、数据位、停止位、校验位),可按更改后的信息自动将串口重新打开
4可统计接收字节和发送字节的个数
5接收数据可按16进制数据和非16进制数据进行整体转换
6可将接收到数据进行保存
7可设置自动发送,发送时间可进行实时更改
8可按字符串、16进制字节、文件方式进行发送,字符串和16进制字节可分别进行存储,内容互不干扰
9按16进制发送时,可自动校验格式,不会输错
10可清空发送或接收区域的数据
二、使用工具
VisualStudio2015
三、程序详解
1界面创建
图1
用winform创建如图1所示界面,控件名字分别为:
端口号:
cbxCOMPort波特率:
cbxBaudRate
数据位:
cbxDataBits停止位:
cbxStopBits
校验位:
label5打开串口按钮:
btnOpenCom
发送(byte):
tbSendCount接收(byte):
tbReceivedCount
清空计数按钮:
btnClearCount按16进制显示:
cb16Display
接收区清空内容按钮:
btnClearReceived保存数据按钮:
btnSaveFile
接收数据框:
tbReceivedData发送数据框:
tbSendData
自动发送:
cbAutomaticSend间隔时间:
tbSpaceTime
按16进制发送:
cb16Send发送区清空内容按钮:
btnClearSend
读入文件按钮:
btnReadFile发送按钮:
btnSend
2创建一个方法类
按Ctrl+shift+A快捷键创建一个类,名字叫Methods,代码为:
usingSystem;
usingSystem.Collections;
usingSystem.Collections.Generic;
usingSystem.IO.Ports;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
namespace串口助手sdd
{
classMethods
{
//获取有效的COM口
publicstaticstring[]ActivePorts()
{
ArrayListactivePorts=newArrayList();
foreach(stringpnameinSerialPort.GetPortNames())
{
activePorts.Add(Convert.ToInt32(pname.Substring(3)));
}
activePorts.Sort();
string[]mystr=newstring[activePorts.Count];
inti=0;
foreach(intnuminactivePorts)
{
mystr[i++]="COM"+num.ToString();
}
returnmystr;
}
//16进制字符串转换为byte字符数组
publicstaticByte[]_16strToHex(stringstrValues)
{
string[]hexValuesSplit=strValues.Split('');
Byte[]hexValues=newByte[hexValuesSplit.Length];
Console.WriteLine(hexValuesSplit.Length);
for(inti=0;i { hexValues[i]=Convert.ToByte(hexValuesSplit[i],16); } returnhexValues; } //byte数组以16进制形式转字符串 publicstaticstringByteTo16Str(byte[]bytes) { stringrecData=null;//创建接收数据的字符串 foreach(byteoutByteinbytes)//将字节数组以16进制形式遍历到一个字符串内 { recData+=outByte.ToString("X2")+""; } returnrecData; } //16进制字符串转换字符串 publicstaticstring_16strToStr(string_16str) { stringoutStr=null; byte[]streamByte=_16strToHex(_16str); outStr=Encoding.Default.GetString(streamByte); returnoutStr; } } } 2Form1.cs的代码为: usingSystem; usingSystem.Collections.Generic; usingSystem.ComponentModel; usingSystem.Data; usingSystem.Drawing; usingSystem.IO.Ports; usingSystem.Linq; usingSystem.Text; usingSystem.Text.RegularExpressions; usingSystem.Threading.Tasks; usingSystem.Windows.Forms; usingSystem.IO; usingSystem.Collections; namespace串口助手sdd { publicpartialclassForm1: Form { //声明变量 SerialPortsp=newSerialPort(); boolisSetProperty=false;//串口属性设置标志位 privateenumPortState//声明接口显示状态,枚举型 { 打开, 关闭 } stringpath=AppDomain.CurrentDomain.BaseDirectory+"confing.ini";//声明配置文件路径 stringtbSendDataStr="";//发送窗口字符串存储 stringtbSendData16="";//发送窗口16进制存储 List //接收串口数据 privatevoidsp_DataReceived(objectsender,SerialDataReceivedEventArgse) { byte[]ReceivedData=newbyte[sp.BytesToRead];//创建接收字节数组 sp.Read(ReceivedData,0,ReceivedData.Length);//读取所接收到的数据 receivedDatas.AddRange(ReceivedData); tbReceivedCount.Text=(Convert.ToInt32(tbReceivedCount.Text)+ReceivedData.Length).ToString(); if(cb16Display.Checked) tbReceivedData.Text=Methods.ByteTo16Str(receivedDatas.ToArray()); else tbReceivedData.Text=Encoding.Default.GetString(receivedDatas.ToArray()); sp.DiscardInBuffer();//丢弃接收缓冲区数据 } //发送串口数据 privatevoidDataSend() { try { if(cb16Send.Checked) { byte[]hexBytes=Methods._16strToHex(tbSendData16); sp.Write(hexBytes,0,hexBytes.Length); tbSendCount.Text=(Convert.ToInt32(tbSendCount.Text)+hexBytes.Length).ToString(); } else { sp.WriteLine(tbSendDataStr); tbSendCount.Text=(Convert.ToInt32(tbSendCount.Text)+tbSendDataStr.Length).ToString(); } } catch(Exceptionex) { MessageBox.Show(ex.Message.ToString()); return; } } //设置串口属性 privatevoidSetPortProperty() { sp.PortName=cbxCOMPort.Text.Trim();//设置串口名 sp.BaudRate=Convert.ToInt32(cbxBaudRate.Text.Trim());//设置波特率 switch(cbxStopBits.Text.Trim())//设置停止位 { case"1": sp.StopBits=StopBits.One;break; case"1.5": sp.StopBits=StopBits.OnePointFive;break; case"2": sp.StopBits=StopBits.Two;break; default: sp.StopBits=StopBits.None;break; } sp.DataBits=Convert.ToInt32(cbxDataBits.Text.Trim());//设置数据位 switch(cbxParity.Text.Trim())//设置奇偶校验位 { case"无": sp.Parity=Parity.None;break; case"奇校验": sp.Parity=Parity.Odd;break; case"偶校验": sp.Parity=Parity.Even;break; default: sp.Parity=Parity.None;break; } sp.ReadTimeout=5000;//设置超时时间为5s Control.CheckForIllegalCrossThreadCalls=false;//这个类中我们不检查跨线程的调用是否合法(因为.net2.0以后加强了安全机制,,不允许在winform中直接跨线程访问控件的属性) //定义DataReceived事件的委托,当串口收到数据后出发事件 sp.DataReceived+=newSerialDataReceivedEventHandler(sp_DataReceived); } //设置端口显示状态 privatevoidDisplayPortState(PortStateportState) { toolStripStatusLabel1.Text=cbxCOMPort.Text+"端口处于"+portState+"状态"+cbxBaudRate.Text+""+cbxDataBits.Text+""+cbxStopBits.Text+""+cbxParity.Text; } //重新打开串口 privatevoidAgainOpenPort() { if(sp.IsOpen) { try { sp.Close(); SetPortProperty(); isSetProperty=true; sp.Open(); } catch(Exception) { isSetProperty=false; btnOpenCom.Text="打开串口"; DisplayPortState(PortState.关闭); MessageBox.Show("串口无效或已被占用! ","错误提示"); return; } DisplayPortState(PortState.打开); } else { DisplayPortState(PortState.关闭); } } publicForm1() { InitializeComponent(); } //软件启动时加载事件 privatevoidForm1_Load(objectsender,EventArgse) { #region加载配置文件 Hashtableht=newHashtable(); if(File.Exists(path)) { try { stringmyline=""; string[]str=newstring[2]; using(StreamReadersr=newStreamReader(path)) { myline=sr.ReadLine(); while(myline! =null) { str=myline.Split('='); ht.Add(str[0],str[1]); myline=sr.ReadLine(); } } } catch(Exceptionex) { MessageBox.Show(ex.Message.ToString()); } } #endregion #region设置窗口为固定大小且不可最大化 this.MaximumSize=this.Size; this.MinimumSize=this.Size; this.MaximizeBox=false; #endregion #region列出常用的波特率 cbxBaudRate.Items.Add("1200"); cbxBaudRate.Items.Add("2400"); cbxBaudRate.Items.Add("4800"); cbxBaudRate.Items.Add("9600"); cbxBaudRate.Items.Add("19200"); cbxBaudRate.Items.Add("38400"); cbxBaudRate.Items.Add("43000"); cbxBaudRate.Items.Add("56000"); cbxBaudRate.Items.Add("57600"); cbxBaudRate.Items.Add("115200"); if(ht.ContainsKey("cbxBaudRate")) cbxBaudRate.SelectedIndex=cbxBaudRate.Items.IndexOf(ht["cbxBaudRate"].ToString()); else cbxBaudRate.SelectedIndex=3; cbxBaudRate.DropDownStyle=ComboBoxStyle.DropDownList; #endregion #region列出停止位 cbxStopBits.Items.Add("1"); cbxStopBits.Items.Add("1.5"); cbxStopBits.Items.Add("2"); if(ht.ContainsKey("cbxStopBits")) cbxStopBits.SelectedIndex=cbxStopBits.Items.IndexOf(ht["cbxStopBits"].ToString()); else cbxStopBits.SelectedIndex=0; cbxStopBits.DropDownStyle=ComboBoxStyle.DropDownList; #endregion #region列出数据位 cbxDataBits.Items.Add("8"); cbxDataBits.Items.Add("7"); cbxDataBits.Items.Add("6"); cbxDataBits.Items.Add("5"); if(ht.ContainsKey("cbxDataBits")) cbxDataBits.SelectedIndex=cbxDataBits.Items.IndexOf(ht["cbxDataBits"].ToString()); else cbxDataBits.SelectedIndex=0; cbxDataBits.DropDownStyle=ComboBoxStyle.DropDownList; #endregion #region列出奇偶校验位 cbxParity.Items.Add("无"); cbxParity.Items.Add("奇校验"); cbxParity.Items.Add("偶校验"); if(ht.ContainsKey("cbxParity")) cbxParity.SelectedIndex=cbxParity.Items.IndexOf(ht["cbxParity"].ToString()); else cbxParity.SelectedIndex=0; cbxParity.DropDownStyle=ComboBoxStyle.DropDownList; #endregion #regionCOM口重新加载 cbxCOMPort.Items.Clear();//清除当前串口号中的所有串口名称 cbxCOMPort.Items.AddRange(Methods.ActivePorts()); if(ht.ContainsKey("cbxCOMPort")&&cbxCOMPort.Items.Contains(ht["cbxCOMPort"].ToString())) cbxCOMPort.SelectedIndex=cbxCOMPort.Items.IndexOf(ht["cbxCOMPort"].ToString()); else cbxCOMPort.SelectedIndex=0; cbxCOMPort.DropDownStyle=ComboBoxStyle.DropDownList; #endregion #region初始化计数器 tbSendCount.Text="0"; tbSendCount.ReadOnly=true; tbReceivedCount.Text="0"; tbReceivedCount.ReadOnly=true; #endregion #region初始化当前时间 toolStripStatusLabel3.Text=DateTime.Now.ToString(); #endregion #region初始化串口状态 toolStripStatusLabel1.ForeColor=Color.Blue; if(! isSetProperty)//串口未设置则设置串口属性 { SetPortProperty(); isSetProperty=true; } try { sp.Open(); btnOpenCom.Text="关闭串口"; DisplayPortState(PortState.打开); } catch(Exception) { //串口打开失败后,串口属性设置标志位设为false isSetProperty=false; MessageBox.Show("串口无效或已被占用! ","错误提示"); } #endregion #region初始化间隔时间 if(ht.ContainsKey("tbSpaceTime")) tbSpaceTime.Text=ht["tbSpaceTime"].ToString(); else tbSpaceTime.Text="1000"; #endregion #region初始化按16进制显示状态 if(ht.ContainsKey("cb16Display")&&ht["cb16Display"].ToString()=="True") cb16Display.Checked=true; else cb16Display.Checked=false; #endregion #region初始化按16进制发送状态 if(ht.ContainsKey("cb16Send")&&ht["cb16Send"].ToString()=="True") cb16Send.Checked=true; else cb16Send.Checked=false; #endregion #region初始化发送区文本 if(ht.ContainsKey("tbSendData16")&&ht.ContainsKey("tbSendDataStr")) { tbSendData16=ht["tbSendData16"].ToString(); tbSendDataStr=ht["tbSendDataStr"].ToString(); if(cb16Send.Checked) tbSendData.Text=ht["tbSendData16"].ToString(); else tbSendData.Text=ht["tbSendDataStr"]
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 上位 串口 通信 助手 源代码 详解
![提示](https://static.bdocx.com/images/bang_tan.gif)