用C步步写串口通信精编版_第1页
用C步步写串口通信精编版_第2页
用C步步写串口通信精编版_第3页
用C步步写串口通信精编版_第4页
用C步步写串口通信精编版_第5页
免费预览已结束,剩余43页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、用c步步写串口通信f-空d、工»CnrIE 曲GE GROUP system office room GEIHUA16H-GEIHUA GEIHUA8Q8-我们来看具体的实现步骤。公司要求实现以下儿个功能:1):实现两台计算机之前的串口通信,以16进制形式和字符串两种形式传送和接收。2):根据需要设置串口通信的必要参数。3):定时发送数据。4):保存串口设置。看着好像挺复杂,其实都是纸老虎,一戳就破,前提是你敢去戳。我 尽量讲的详细一些,争取说到每个知识点。在编写程仔前,需要将你要测试的COM 口短接,就是收发信息都在本地计算机,短接的方式是将COM 口的2. 3号针接起來。COM

2、口各针的具体作用,度娘是这么说的:COM 口。记住2、3针连接一定要连接牢固,我就是因为接触不良,导致本身就不通,白白花掉了一大半天时间调试代码。下面给出主要的操作界面,如下:顺便,我将所有控件对应的代码洛字也附上了,相信对初学者来说,再看 下面的代码会轻松很多。控件名字命名的方法是“控件名+作用”的形 式,例如"打开串口"的开关按钮,其名字是btnSwitch (btn就是 button的简写了)。我认为这种命名控件的方式比较好,建议大家使用,如果你有好的命名方式,希望你能告诉我!下而我们将各个功能按照从主到次的顺序逐个实现。(我分块给出代码实 现,详细代码见链接:C#串

3、口通信工具)一.获取计算机的COM 口总个数,将它们列为控件cbSerial的候选项, 并将第一个设为cbSerial的默认选项。这部分是在窗体加载时完成的。请看代码:(很多信息代码的注释里讲的 很清楚,我就不赘述了。)csharpview plaincopyprint1. /检查是否含有串口2.3.stringstr=SerialPort. GetPortNames();4.if(str=null)5.MessageBox. Show("本机没有串口 ! ","Error");7.return;9./添加串口项目10.foreach (stringsi

4、nSystem. 10. Ports. SerialPort. GetPortNamesO)11/获取有多少个COM 口12cbSerial. Items. Add(s);13.14./串口设置默认选择项15cbSerial. SelectedIndex=O;/设置spanstyle="font-size: 18px; ><strong>cbSerial 的默认选项</strongX/span>“串口设置”这面我没代码编程,直接从窗体上按照串口信息设置 就行。我们仅设置它们的默认选项,但这里我用到了 ini文件,暂时不讲,我们先以下面形式设置默认。csh

5、arpview plaincopyprint1. cbBaudRate. Selectedlndex=5;2. cbDataBits. Selectedlndex=3;3. cbStop. SelectedIndex=0;4. cbParity. SelectedIndex=O;5. radiol. Checked=true;/发送数据的"16进制”单选按钮(这里我忘了改名,现在看着很不舒服!)6. rbRcvStr. Checked二true;三. 打开串口在发送信息之前,我们需要根据选中的选项设置串口信 息,并设置一些控件的属性,最后将串口打开。csharpview plainc

6、opyprintprivatevoidbtnSwitch_Click(objectsender, EventArgse)2.3.spanstyle="white-spacespan>/spl 是全局变量。SerialPortspl=newSerialPort();13.stringstrDateBits=cbDataBits. Text;4.if (!spl. IsOpen)5.try7.设置串口号9.10.stringserialName=cbSeriaL Selecteditem. ToString ();spl. PortName=serialName;IL/设置各“串口

7、设置”12.stringstrBaudRate=cbBaudRate. Text;14stringstrStopBits=cbStop. Text:15.Int32iBaudRate=Convert. Tolnt32(strBaudRate);1&Int32iDateBits=Convert. Tolnt32(strDateBits);17.spl. BaudRate=iBaudRate; /波特率18.spL DataBits=iDateBits; /数据位19.switch(cbStop, Text)/停止位20.-case 1 :22.spl.StopBits=StopBits.

8、 One:23.break;24. q L case 1. b :25.spl. StopBits=StopBits. OnePointFive;26.break:27.case z :42.case"偶校验:43.spL Parity=Parity. Even;44.break:default:46.MessageBox. Show(Error:参数不正确! ","Error");47.break:48.49.50.spl. CloseO ;52.53.状态栏设置辻(spl. IsOpen=true)/如果打开状态,则先关闭一下54.tsSpNum.

9、Text二"串 口号;"+spl PortName+ | "55.tsBaudRate. Text="波特率:"+spl BaudRate+ | "56.tsDataBits. Text=数据位:+spl DataBits+" | "57.tsStopBits. Text=停止位:+spl StopBits+" | "58.tsParity. Text二"校验位j "+spl Parity+" | "59./设置必要控件不可用60.cbSerial. En

10、abled=false;6162.63.cbStop. Enabled=false;64.cbParity. Enabled=false;65.spl. Open0 ;/打开串口66.btnSwitch. Text二"关闭串口"67.68catch (System. Exceptionex)69.cbBaudRate. Enabled=false: cbDataBits. Enabled=false;70.MessageBox. Show ("Error : "+ex Message, "Error");return;72.74.el

11、se状态栏设置77,tsSpNum. Text="串 口号;未指定78.tsBaudRate. Text="波特率:未指定 I"79.tsDataBits. Text="数据位:未指定 I"80.tsStopBits. Text="停止位j 未指定;"8LtsParity. Text二"校验位 j 未指定 I"82./恢复控件功能83./设置必要控件不可用84.cbSerial.Enabled=true:85.cbBaudRate. Enabled=true;86.cbDataBits. Enabled=

12、true;87.cbStop. Enabled=true;88.cbParity. Enabled=true;89.spl. CloseO ;/关闭串口90.btnSwitch. Text二"打开串口"9192四. 发送信息 因为这里涉及到字符的转换,难点在于,在发送16进制数据时,如何将 文本框中的字符数据在内存中以同样的形式表现出來,例如我们输入16 进制的90显示到内存中,也就是如下形式:Address:0xai35b65c10 2f 12 790200000030mO135B65Cleb 30|00 0000,y0kO135B66900000068311279020

13、000006500hl, y,e0xO135B676620000000000102£1279020000b/,y,0kO135B68300&56200000000000068311279,胡hl,0x01356690020000003900300000000000109, 00x013586912f127902000000393000000000h y.30XO135B6U0000202d12T9Os 000000f48f Ofy0xO135B6B7793c0333010000000000000000y< 30=c0135BSC400000000000000000000

14、0000000xO135B&Dl000000000000000000000000000xO135B6DE000000000000f48f Of 79000000,0xO135B6EE0000000000e416Of T9 00000000Y.0kO135B6FS0000000060£6Se640000000060 , , ,AyVettory 1byteBuf fersp1.Write(byteBuffer, 8, strArray.Length)lesorF X05 0000 JJD00 0000 00 112 34|00002000 00 00 00 £T 35

15、000001或输入我们想要的任何字节,如上面的“12 34 56 78 90” 内存中的数据时16进制显示的,而我们输入的数据时字符串,我们需要将字符串转换为对应的16进制数据,然后将这个16进制数据转换为字节数据,用到的主要方法是:Convert. Tolnt32 (String, Int32);Convert. ToByte (Int32);这是我想到的,如果你有好的方法,希望你能告诉我。下面看代码:csharpview plaincopyprint1. privatevoidbtnSend_Click(objectsender, EventArgse)2.113.辻(! spl. IsO

16、pen)/如果没打开4.5.MessageBox. ShowC请先打开串口 ! ","Error");return;7.StringstrSend=txtSend. Text;9.if (radio!. Checked=true) / " 16 进制发送"10.按钮12.处理数字转换,目的是将输入的字符按空格、% ”等分组,以便发送数据时的方便(此处转的比较麻烦,有高见者,请指点!)13.stringsendBuf=strSend;14stringsendnoNull=sendBuf. TrimO ;15.stringsendNOConinia

17、=sendnoNulL Replace(*;/去掉英文逗号16.stringsendNOComnial=senclNOConima. Replace C » ','');/去掉中文逗号17.stringstrSendNoComma2=sendNOCommaL Replace ("Ox",")/去掉Ox18.strSendNoConima2. Replace ("OX",;/去掉 OX19.stringE strArray=strSenclNoComina2. Split ;20.<spanstyle=wh

18、ite-space :pre></span>/str Ar ray 数组中会出现“”空字符的情况,影响下面的赋值操作,故将<spanstyle="background-color :rgb (255, 255, 255) ; ">byteBufferLength 相应减小</span>intbyteBufferLength=strArray. Length;22.for (inti=0;ispanstyle="background-color:rgb (255, 255, 255);"strArray Lengt

19、h</span><spanstyle=background-color: rgb (255, 255, 255) ; "> i+) </span>23.24.if(strArray1="")25.26.byteBufferLength;9.bytebyteBuffer=newbytebyteBufferLength;30.intii=0; <spanstyle=%hite-space:pre"></span>/用于给spanstyle二"background-col

20、or:rgb(255, 255, 255);">byteBuffer赋值 </span>for (inti=0; KstrArray. Length; i+)/对获取的字符做相加运算940i);intdecNum二0;if (strArray1="")continue;elseBytebytesOfStr=Encoding. Default, GetBytes(strArray41.42.decNum=Convert. Tolnt32(strArrayi, 16);/atrArrayi=12 时,temp=1

21、843.try/防止输错,使其只能输入一个字节的字符,即只能在txtSend里输入“eb9(r 等字符串,不能输入“1232345”等超出 字节范围的数字5.byteBuffer ii =Convert. ToByte (decNuin);46.47.catch (System. Exceptionex)48.49.MessageBox. Show("字节越界,请逐个字节输入!,Error 丿;50.return;52.ii+;53.54.spl. Write(byteBuffer, 0, byteBuffer. Length);56.else/以字符串形式发送时

22、59.spl. WriteLine (txtSend. Text) ;/写入数据5960.五. 数据的接收 亮点来了,看到这里,如果你还没吐(可能是我的代码比较拙劣!),那 么下而的知识点对你也不成问题。这里需要用到委托的知识,我是搞C/C+出身,刚碰到这个知识点还真 有点不适应。为了不偏离主题,关于委托,我仅给出两条比较好的链接, 需要的网友可以去加深学习:C#委托、订阅委托事件。在窗体加载时就订阅上委托是比较好的,所以在Forml_Load中添加以 下代码:csharpview plaincopyprint1. Control. CheckForIllegalCrossThreadCall

23、s=false:/意图见解释2. spl. DataReceived+=newSerialDataReceivedEventHandler(spl_DataReceived) ;/iJ 阅委托注意,因为net 2. 0以后加强了安全机制,不允许在winform中直接跨线程(事件触发需要产生一个线程处理)访问控件的属性,第一条 代码的意图是说在这个类中我们强制不检查跨线程的调用是否合法。处理 这种问题的解决方案有很多,具体可参阅以下内容:解决方案。好了,订阅委托之后,我们就可以处理接收数据的事件了。csharpview plaincopyprint1. voidspl_DataReceived(

24、objectsender, SerialDataReceivedEventArgse)2.3.辻(spLIsOpen)/此处可能没有必要判断是否打开串口,但为了严谨性,我还是加上了4.5.bytebyteRead=newbytespl. BytesToRead;/BytesToRead:spl接收的字符个数 辻(rdSendStr. Checked) IT发送字符串'单选按钮 txtReceive. Text+=spl. ReadLine()+"rn"/注意:回车换行必7.须这样写,单独使用和n都不会有效果9. spl. DiscardInBuffer () ;/清

25、空 SerialPort 控件的 Buffer10.ILelse/'发送16进制按钮'12.13.try1415.Byte receivedData=newByte spl. BytesToRead ; /创建接收字节数组1&spL Read(receivedData> 0, receivedData. Length) ;/读取数据17.spl. DiscardInBuffer () ;/清空 SerialPort 控件的 Buffer18.stringstrRcv=null:20.19.for (inti=0; i<receivedData. Length

26、; i+)/窗体显不22.23.txtReceive. Text+=strRcv+"rn"24.25.catch (System. Exceptionex)26.27.MessageBox. Show (ex. Message,"出错提不");28.txtSend. Text二""29.30.strRcv+=receivedDatai. ToString("X2") ;/16 进制显不33.32.34.elseMessageBox. ShowC请打开某个串口/错课提示");35.36.为了友好和美观,我将

27、当前时间也显示出來,乂将显示字体的颜色做7修改:csharpview plaincopyprint1.spanstyle二"white-space:pre">/span>/输出当前时间2. DateTimedt=DateTime. Now;3.txtReceive. Text+=dt. GetDateTimeFormats C f')0 ToString() +4.txtReceive. SelectAll();5.txtReceive. SelectionColor=Color. Blue;/改变字体的颜色做到这里,大部分功能就己实现了,剩下的工作就是

28、些简单的操作设置 了,有保存设置、定时发送信息、控制文本框输入内容等。六. 保存设置这部分相对简单,但当时我没接触过,也花了点时间,现 在想想,也不过如此。保存用户设置用ini文件是个不错的选择,虽然大 ini部分都用注册表实现,但ini文件保存还是有比较广泛的使用。.ini文 件是Initialization F订e的缩写,也就是初始化文件。为了不偏离正题,也不过多说明,可参考相关内容(网上资源都不错,因人而异,就不 加链接了)。使用Inifile读写ini文件,这里我用到了两个主要方法:csharpview plaincopyprintL /读出ini文件2.3. a:=in辻ile. R

29、eadstring( 节点','关键字'、缺省值):/string 类4. b:=in辻订e. Readinteger节点关键字',缺省值):/integer类型5. c:=in辻订e. Readbool C节点','关键字',缺省值);/boolean类型6.其中缺省值为该INI文件不存在该关键字时返回的缺省值。7. /写入INI文件:8. ill辻ile. writestringC节点','关键字',变量或字符串值);9. in辻ile. writeinteger C节点','关键字',

30、变量或整型值);10.in辻订e. writebool C节点','关键字',变量或True或False);请看代码:csharpview plaincopyprint1. /using 省写了2.namespacelNIFILE3.4.5.classProfile7.publicstaticvoidLoadProfile 08. 9. stringstrPath=AppDomain. CurrentDomain. BaseDirectory;10._file=newIniFile(strPath+Cfg. ini"ILG_BAUDRATE=_file. Re

31、adString ("CONFIG", "BaudRate", "4800);/读数据,下同12.G_DATABITS=_f 订& ReadString ("CONFIG", "DataBits", 8)13.G_STOP=_f 订6 Readstring ("CONFIG "StopBits", ”1)14.G_PARITY=_file ReadString ("CONFIG", "Parity", "NONE&qu

32、ot;);1516.publicstaticvoidSaveProf ile ()17.18.stringstrPath=AppDomain. CurrentDomain. BaseDirectory;19._file=newIniFile(strPath+Cfg. ini"20.WriteString("CONFIG", "BaudRate", G_BAUDRATE) ;/22.23.写数据,下同WriteString("CONFIG", "DataBits: G_DATABITS);WriteString(&q

33、uot;CONFIG", "StopBits", G_STOP);24.25.privatestat icIniFile_f lie; / 内置了一个对象26.publicstaticstringG_BAUDRATE="1200"/给 ini 文件赋新并且影响界面下拉框的显示27.publicstaticstringG_DATABITS=8;28.publicstaticstriiigG_STOP二"1"29.publicstaticstringG_PARITY="NONE":30file. WriteS

34、tring("CONFIG", "GPARITY: G_PARITY);_file声明成了内置对象,可以方便各函数的调用。下面是“保存设置”的部分代码:csharpview plaincopyprintprivatevoidbtnSave_Click(ob jectsender> EventArgse)2.11switch(cbStop. Text)/停止位3./设置各“串口设置”4.stringstrBaudRate=cbBaudRate. Text;5.stringstrDateBits=cbDataBits. Text;stringstrStopBit

35、s=cbStop.Text:7.Int32iBaudRate=Convert. Tolnt32(strBaudRate);Int32iDateBits=Convert. Tolnt32(strDateBits);9.Profile. G_BAUDRATE=iBaudRate+"/波特率10.Prof 订 eG_DATABITS=iDateBits+"/ 数据位12.13.-case 1 :14Profile. G_STOP="1":15.break;16./ 1 L case 1. b :17.Prof 订 eG_ST0P=l5;18.break:19./防止过多刷屏,下面省写了20.22.switch(cbParity. Text)/校验位23.25.Profile. G_PARITY二"NONE"24.case"无":26.break:27.28.29.Profile. SaveProfile() ;/保存设置30读取ini文件主要在加载窗体时执行:INIFIL

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论