通信网络程序设计(王晓东西电版)第3章串口网络编程

上传人:xiao****017 文档编号:16357184 上传时间:2020-09-28 格式:PPT 页数:90 大小:339KB
返回 下载 相关 举报
通信网络程序设计(王晓东西电版)第3章串口网络编程_第1页
第1页 / 共90页
通信网络程序设计(王晓东西电版)第3章串口网络编程_第2页
第2页 / 共90页
通信网络程序设计(王晓东西电版)第3章串口网络编程_第3页
第3页 / 共90页
点击查看更多>>
资源描述
,第3章 串口网络编程,3.1 串行通信概述 3.2 串口通信程序设计 3.3 串口通信程序设计 小结,串口通信是一种通信条件要求最低却十分重要的网络通信模式,网络设备调试、极端条件下的网络通信都可以通过串口来实现,特别是对一些便携式、小型设备,串口通信可能是它们的唯一通信手段。串口通信处于OSI模型的数据链路层,通信协议简单、编程接口函数数量较少,适合作为进行网络编程技术的入门学习内容。本章由串口通信的基本原理、接口入手,介绍串口通信的API函数;并以主机与单片机、主机间的通信为实例,介绍串口网络编程的方法。,串行总线是一种目前经常使用的通信方式,单片机、PLC、测试仪器、PC、打印机、交换机、路由器、防火墙、工业控制设备都带有串口总线。串行接口包括RS-232/422/485,其技术简单成熟,性能可靠,所要求的软硬件环境和条件都很低,是一种最简单的建立网络连接的方式。,3.1 串行通信概述,3.1.1 串行通信的模式通过单线传输信息是串行数据通信的基础,数据通常是在两个站(点对点)之间进行传输的。按照数据流的方向,串行通信可分成三种传输模式:单工、半双工、全双工。1单工模式单工模式的数据传输是单向的。通信双方中,一方固定为发送端,另一方则固定为接收端。信息只能沿一个方向传输,使用一根传输线。单工模式一般用在只向一个方向传输数据的场合。例如计算机与打印机之间的通信是单工模式,因为只有计算机向打印机传输数据,而没有相反方向的数据传输。在某些通信信道中,存在单工无线发送等单工模式。,2半双工模式半双工通信中使用同一根传输线,既可发送数据又可接收数据,但不能同时进行发送和接收。在任何时刻,只能由其中的一方发送数据,另一方接收数据。因此半双工模式既可以使用一条数据线,也可以使用两条数据线。在半双工通信中,每一端需装有一个收发切换电子开关,通过切换来决定数据向哪个方向传输。因为有切换,所以会产生时间延迟,信息传输效率也较低。,3全双工模式全双工数据通信分别由两根可以在两个不同的站点同时发送和接收的传输线进行传输,通信双方都能在同一时刻进行发送和接收操作。在全双工模式中,每一端都有发送器和接收器,有两条传输线,可在交互式应用和远程监控系统中使用,信息传输效率较高。,3.1.2 串口的基本参数与标准目前,常用的串口标准有RS-232C、RS-422、RS-485标准。1RS-232CRS-232C是美国电子工业协会(Electronic Industry Association,EIA)于1962年公布并于1969年修订的串行接口标准,它已经成为了国际上通用的标准。1987年1月,RS-232C经修改后,正式改名为EIA-232D。由于标准修改内容并不多,因此现在很多厂商仍使用旧的。RS-232C标准(协议)的全称是EIA-RS-232C标准,,其中RS(Recommended Standard)代表推荐标准,232是标识号,C代表RS-232的最新一次修改,它适合于数据传输速度在020kb/s范围内的通信。这个标准对串行通信接口的有关问题,如信号电平、信号线功能、电气特性、机械特性等都作了明确的规定。目前RS-232C已成为数据终端设备(DTE,如计算机)和数据通信设备(DCE,如Modem)的接口标准。RS-232C是PC与通信工业中应用最广泛的一种串行接口,PC上的COM1和COM2大多是RS-232C接口。利用RS-232C串行通信接口可实现两台个人计算机之间点对点的通信;通过RS-232C接口可与其他外设(如打印机、逻辑分析仪、智能调节仪、PLC等)近距离串行连接,通过RS-232C接口连接调制解调器(Modem)可远距离地与其他计算机通信;将RS-232C接口转换为RS-422或RS-485接口,可实现一台个人计算机与多台现场设备之间的通信。 RS-232的每一引脚都有它的作用,也有其信号流动的方向,各引脚的信号功能描述见表3-1。原来的RS-232是用来连接调制解调器作为传输用的,因此它的引脚位意义通常也和调制解调器传输有关。从功能来看,全部信号线分为三类,即数据线(TXD、RXD)、地线(GND)和联络控制线(DSR、DTR、RI、DCD、RTS、CTS)。,表3-1 RS-232各引脚的信号功能,只有当DSR和DTR都处于有效(ON)状态时,才能在DTE和DCE之间进行传输操作。若DTE要发送数据,则预先将DTR线置成有效(ON)状态,等CTS线上收到有效(ON)状态的回答后,才能在TXD线上发送串行数据。这种顺序的规定对半双工的通信线路特别有用,因为半双工的通信确定DCE已由接收端向改为发送端向,这时线路才能开始发送。从计算机的角度来看这些引脚的通信状况,流进计算机端的,可以看做数字输入;而流出计算机端的,则可以看做数字输出。从工业应用的角度来看,所谓的输入就是用来“监测”的,而输出就是用来“控制”的。,2RS-422RS-422由RS-232发展而来,是为了弥补RS-232的不足而提出的。为了改进RS-232抗干扰能力差、通信距离短、传输速度低等缺点,RS-422定义了一种平衡通信接口,将传输速度提高到10Mb/s,速率低于100kb/s时的传输距离延长到4000英尺(1英尺=0.3048m),并允许在一条平衡总线上连接最多10个接收器。RS-422是一种单机发送、多机接收的单向、平衡传输规范。,3RS-485为扩展应用范围,EIA又于1983年在RS-422基础上制定了RS-485标准,增加了多点、双向通信能力,即允许多个发送器连接到同一条总线上,同时增加了发送器的驱动能力和冲突保护特性,扩展了总线共模范围。RS-485协议可以看做是RS-232协议的替代标准,与传统的RS-232协议相比,其在通信速率、传输距离、多机连接等方面均有了非常大的提高。由于RS-485总线是RS-232总线的改良标准,因此在软件设计上它与RS-232总线基本上一致。,当两台RS-232串口设备通信距离较近时(小于15m),可以用电缆线直接将两台设备的RS-232端口连接;若通信距离较远时(大于15m),则需要附加Modem。当PC与串口设备的通信距离较远或PC与多台具有RS-232接口的设备通信时,也可以采用RS-485总线。,3.1.3 串行通信握手协议串行通信需要使用握手协议保持数据收发双方的同步,握手协议靠握手信号实现。握手信号实际上就是控制信号,用来控制数据的传输。通过握手信号,发送端可以得知接收端是否有数据要发送。接收端通过握手信号通知发送端它是否已经准备好了接收信号。握手信号遵循某种协议。当发送端和接收端处理数据的速度不一样时,可能会造成数据丢失。在数据传输中,如果发送端的发送速度大于接收端的接收速度,同时接收端处理数据的速度不够快,那么接收端的缓冲区必定在一定时间后溢出,从而造成以后发送过来的数据不能进入缓冲区而丢失。,发送端何时可以继续发送数据,何时必须暂停发送,从而让接收端有时间处理数据,则必须靠握手信号来解决这个问题。例如,打印机和计算机进行通信时,一些打印机的打印速度可能跟不上计算机发送数据的速度,就必须通过握手信号通知计算机暂停发送数据。通常,串行通信握手的协议可以是硬件握手、软件握手或二者的结合,具体如下所述。,1硬件握手在硬件握手中,发送端通过将某一条导线拉到高电平或者低电平,以表示发送端可以发送数据。接收端已经准备好接收数据之后,也把某一个导线拉到高电平或者是低电平,以通知发送端,发送端一直在检测这个信号。接收端可以在任何时候把这个信号变为无效,甚至是在接收一个数据块的过程中。当发送端检测到这个信号变为无效之后,就必须停止本次发送,直到这个信号变为有效为止。,2软件握手在软件握手中,以数据线上特定的数据信号来代替实际的硬件电路电平变化。这种方法用在直接连接或者通过调制解调器连接的两台计算机之间进行双向通信的场合。对于软件握手,现在已经建立了一些标准协议,其中最常用的是通信协议。通信协议是指通信双方的一种约定,包括对数据格式、同步方式、传输速度、传输步骤、检/纠错方式以及控制字符定义等问题进行统一规定,通信双方必须共同遵守,也叫做通信控制规程或传输控制规程,它属于OSI七层参考模型中的数据链路层。,3软硬结合握手在使用个人计算机或终端设备通过调制解调器和主计算机进行通信时(例如:对路由器进行基于串口的远程配置的情况),一般会采用软硬结合的握手。这种握手同时采用了硬件握手和软件握手:一方面,个人计算机与调制解调器、主计算机与调制解调器之间,使用硬件握手方法进行联系;另一方面,主计算机和个人计算机之间将使用软件握手方法进行联系。因此,个人计算机向主计算机传输数据时,同时要考虑硬件和软件握手。,例如:在个人计算机通过调制解调器向主计算机发送数据时,只有在调制解调器DSR(有时可能使用CD)线电位变高,且没有收到来自主计算机的“停止传输”软件信号时,才送出数据。 一些计算机会自动监测硬件握手信号,所以应用程序只需要处理软件握手信号即可。但这种情况并不等于硬件握手不存在,依然是软硬结合的握手。,现在的产品若要自动化,一定要提供一个能与计算机进行通信的通道。最简单的方式就是在产品内部烧上一颗单芯片,利用单芯片上的串行通信功能进行自动化的工作,由于计算机中的串口是必备的通道,且从价格及技术上来说是最能被厂商所接受的,因此,市面上很多自动化产品也就加上了串行通信的功能,从而扩大了产品的使用领域,使产品自动化的实现技术变得简单化。,3.2 串口通信程序设计,3.2.1 串行通信软件工具除了用户自己动手编写串口通信软件之外,目前也有一些现成的串口通信软件工具。1超级终端程序超级终端程序是Windows操作系统自带的串口通信软件,用户可以选择“开始/程序/附件/通信/超级终端”命令来调用它。使用超级终端程序需要对其进行设置,设置步骤如下:(1) 首先按照“开始/程序/附件/通信”顺序,执行“超级终端”操作(对应系统目录“C:Program FilesWindows NT”下的hypertrm.exe应用程序),,会出现一个本次联机的名称设置窗口(第一次使用该应用程序时,可能还会被要求设置国家、区号等属性参数),在其中输入名称并选择一个代表图标。此名称通常应使用易记的名称来命名,以后再进行联机操作时,只要加载该名称,一切其它的设置就会恢复。(2) 然后在出现的界面中选择所要连接的设备。可以根据需要连接相应的设备,可选得选项包括:COM、TCP/IP等,在这里选择COM。(3) 在弹出的窗口中设置相关的参数,如图3-1所示。,图3-1 超级终端参数设置,(4) 单击“确定”按钮后,就会出现一个工作窗口,这说明已经连接到需要连接的设备上。设置完成后,会出现连接提示,包括连接时间、终端类型、连接参数等。如果串口不存在,或已被其他设备使用,超级终端就无法打开该端口,会显示错误提示。用超级终端和其他的设备进行连接时,双方互传的数据以文字数据为主,在正式用程序将计算机和设备联机之前,最好使用类似超级终端之类的程序先行做一些基本的测试,以确定使用字符串的通信没有问题,然后再进行控制。,2窗口精灵软件窗口精灵软件是一个极好的串口监视与调试程序,适用于 Win9X/NT 平台,能提高开发效率。它可以在线设置各种通信速度、奇偶校验、通信口而无需重新启动程序;可以设置定时发送的数据以及时间间隔;可以自动显示接收到的数据,并能在字符串、十进制和十六进制之间自由切换;还能自动保存设置参数。窗口精灵软件是工程技术人员监视、调试串口程序的必备工具。,3串口调试助手串口调试助手是在实际工程应用中,根据实际的、普遍的需求而开发的串口调试工具,其界面精致美观、实用性强,支持各种串口设置,如波特率、校验位、数据位和停止位等。支持ASCII/Hex发送,发送和接收的数据可以在十六进制和ASCII码之间任意转换。可以自动在发送的数据末尾增加校验位,支持多种校验格式。支持间隔发送、循环发送和批处理发送,输入的数据可以从外部文件导入,并且能够自动将接收到的数据保存到磁盘文件。,4串口监控器串口监控器是一个免费的多功能串口通信监控软件,它能够以多种方式显示、接收、分析通信数据;能够以多种灵活方式发送数据;具有方便的数据编辑功能。串口监控器的特点是功能强大,操作简单,在串口通信监控、设备通信测试中,能够很好地提高工作效率。它的主要功能如下:(1) 接收数据;(2) 以十六进制方式显示接收到的数据;(3) 以字符方式显示接收到的数据;(4) 数据帧自动识别,分行显示。,5串口文件自动发送/接收系统当要求隔离的两个网络之间需要经常性地传输一些文件时,若使用优盘拷贝则费时、费力,使用网闸则动辄花费数万至数十万元,而此时使用“串口文件自动发送/接收系统”不失为一种很好的解决方案。串口文件自动发送/接收系统使用的是Zmodem文件传输协议,虽然速度不快,但不使用任何网络协议。串口文件自动发送/接收系统由发送端和接收端两部分组成:发送端可设置需要传输的文件夹和文件类型,支持定时检测,当发现新增文件或当文件长度、创建时间发生变化时,都会自动地通过串口发送到接收端;,接收端处在自动接收状态,当收到文件后会自动将其保存到指定的文件夹中。上述软件在基于串口通信的工程实践中发挥了巨大效益,使用范围非常广泛。下面我们将从串口操作函数入手,讲解如何设计实现自己的串口通信程序。,3.2.2 串口操作API函数在32位的Windows系统中,串口和其他通信设备都是作为文件进行处理的。串口的打开、关闭、读取和写入所用的函数与操作文件的函数完全一样。1打开串口在通信过程中,程序是通过CreateFile()函数打开串口来进行读、写或读/写访问的。CreateFile()调用成功后返回一个句柄,这个句柄将会在后续操作中使用,可以打开已经存在的文件、创建新文件和打开系统设备(例如:串口设备、并口设备和调制解调器等。注意:这些设备需正确安装驱动,获得系统合法I/O资源),它的原型如下:,HANDLE CreateFile( LPCTSTR lpFileName, /指向文件名的指针 DWORD dwDesiredAccess, /访问模式(写/读) DWORD dwShareMode, /共享模式 LPSECURITY_ATTRIBUTES lpSecurityAttributes, /指向安全属性的指针 DWORD dwCreationDisposition, /如何创建 DWORD dwFlagsAndAttributes, /文件属性 HANDLE hTemplateFile); /用于复制文件句柄,函数调用成功后,返回一个HANDLE句柄,可以在串口后续操作中对其进行调用,该句柄指向所开辟串口。,2关闭串口调用CloseHandle()函数即可关闭由CreateFile()函数返回的句柄。使用串口后一般要关闭串口,如果忘记关闭串口,串口就会始终处于打开状态,其他应用程序就不能打开并使用串口了,其原型如下:BOOL CloseHandle( HANDLE hObject ); /指向需关闭的文件句柄,3读串口操作程序可以使用Win32 API的ReadFile()函数或者ReadFileEx()函数从串口中读取数据。Readfile()函数对同步或异步操作都支持,而ReadFileEx()函数只支持异步操作。这两个函数不受函数是否异步操作、超时操作等有关参数的影响和限制。利用Win32 API读/写串口时,既可同步执行,也可以异步执行。同步执行时,函数直到操作完成后才返回,这意味着在同步执行时线程会被阻塞,从而导致效率变低。异步执行时,即使操作还未完成,调用的函数也会立即返回并交出控制权,把费时的I/O操作安排在后台进行,这样就可以提高工作效率。ReadFile()的原型如下(ReadFilEx()与之非常类似):,BOOL ReadFile(HANDLE hFile, /文件的句柄 LPVOID lpBuffer, /用于保存读入数据的一个缓冲区DWORD nNumberOfBytesToRead, /要读入的字符数LPDWORD lpNumberOfBytesRead, /指向实际读取字节数的指针LPOVERLAPPED lpOverlapped ); /异步读取操作数据结构体指针Windows 9X/NT/2000中读/写串口时引入了超时结构。超时结构直接影响读/写操作行为。当事先设定的超时间隔消失时,,ReadFile()、ReadFileEx()、WriteFile()和WriteFileEx()函数操作仍未结束,那么超时设置将无条件结束读/写操作,而不管是否已读出或已写入指定数量的字符。在读/写操作期间发生的超时将不按错误处理,即读/写操作返回指定成功的值。对于同步读/写操作,实际传输的字节数由ReadFile()和WriteFile()函数报告。对于异步操作,则由OVERLAPPED结构来获取。该结构定义如下:typedef struct _OVERLAPPED DWORD Internal; /操作系统保留,指出系统相关状态 DWORD InternalHigh; /指出发送或接收的数据长度,DWORD Offset; /文件传送的开始位置DWORD OffsetHigh; /文件传送的字节偏移量的高位字HANDLE hEvent /指定一个I/O操作完成后触发的事件 OVERLAPPED可以使用下面函数获得超时设定时间:BOOL GetCommTimeouts( HANDLE hFile, /通信驱动句柄 LPCOMMTIMEOUTS lpCommTimeouts );,/超时结构体指针可以使用下面函数设置超时:BOOL SetCommTimeouts( HANDLE hFile, /通信驱动句柄 LPCOMMTIMEOUTS lpCommTimeouts ); /超时结构体指针,4写串口操作可以使用Win32 API的函数WriteFile()或者WriteFileEx()向串口中写数据。WriteFile()函数对同步或异步操作都支持,而WriteFileEx()函数只支持异步操作。这两个函数都受函数是否异步操作、超时操作等有关参数的影响和限制。WriteFile()函数原型如下:BOOL WriteFile(HANDLE hFile, /文件句柄LPCVOID lpBuffer, /数据缓存区指针DWORD nNumberOfBytesToWrite, /需写入的字节数,LPDWORD lpNumberOfBytesWritten, /实际写入字节数的存储区域指针LPOVERLAPPED lpOverlapped ); /OVERLAPPED结构体指针,5通信状态操作获取串口状态使用GetCommState()函数,该函数原型如下:BOOL GetCommState( HANDLE hFile, /通信驱动句柄 LPDCB lpDCB ); /驱动控制块结构指针串口的状态在成功调用上述函数后,将被放入一个类型名为DCB的结构体,结构体成员定义如下:typedef struct _DCB DWORD DCBlength;,/DCB长度 DWORD BaudRate; /指定当前的波特率DWORD fBinary: 1; /指定是否允许二进制模式DWORD fParity: 1; /指定奇偶校验是否允许DWORD fOutxCtsFlow:1; /指定Cts是否用于检测发送控制DWORD fOutxDsrFlow:1; /指定Dsr是否用于检测发送控制DWORD fDtrControl:2; / Dtr流控制类型 DWORD fDsrSensitivity:1; / Dsr sensitivity,DWORD fTXContinueOnXoff:1; / XOFF信号时发送是否停止DWORD fOutX: 1; / Xon/Xoff流出DWORD fInX: 1; / Xon/Xoff流入控制 DWORD fErrorChar: 1; /是否用ErrorChar成员代替错误字符DWORD fNull: 1; /接收时是否去掉空(0值)字节DWORD fRtsControl:2; /Rts流控制,DWORD fAbortOnError:1; /有错误发生时是否终止读和写操作DWORD fDummy2:17; /保留未用WORD wReserved; /未使用,必须为0 WORD XonLim; /传输Xon字符发送之前的接收缓冲区/中可允许的最小字节数WORD XoffLim; /传输Xoff字符发送之前的接收缓冲区/中可允许的最小字节数BYTE ByteSize; /指定端口当前使用的数据位,BYTE Parity; /指定端口当前使用的奇偶校验方法BYTE StopBits; /指定端口当前使用的停止位数char XonChar; /指定用于发送和接收字符的Xon值char XoffChar; /指定用于发送和接收字符的Xoff值char ErrorChar; /代替奇偶校验发生错误时的字符值char EofChar; /输入字符结束char EvtChar; /当接收到此字符时产生一个事件WORD wReserved1; /保留未用, DCB;也可人工填写好DCB结构,通过调用下面函数设置串口状态:BOOL SetCommState( HANDLE hFile, /通信驱动句柄 LPDCB lpDCB ); /驱动控制块结构指针函数调用成功,返回TRUE;否则返回FALSE。,6串口数据清除串口数据清除函数用于清除串口的错误信息。如果在串口通信中发生错误,如终端、奇偶错误等,I/O操作将会终止。如果程序要进一步执行I/O操作,则必须调用ClearCommError()函数,它有两个作用:清除错误条件和确定串口通信状态。ClearCommError()函数原型如下:BOOL ClearCommError( HANDLE hFile, /通信驱动句柄 LPDWORD lpErrors, /接收错误码变量指针,LPCOMSTAT lpStat ); /通信状态存储区指针清除串口缓冲区可通过下面函数来实现:BOOL PurgeComm( HANDLE hFile, /通信资源句柄 DWORD dwFlags ); /执行动作函数调用成功后,返回TRUE,代表接收缓存区被成功清空;否则返回FALSE。,7串口事件操作串口事件操作函数为某一个驱动器设置事件,当事件发生时,触发并通知主程序。可选的事件有EV_BREAK、EV_CTS等(见表3-2)。监控的事件可以是“|”联结或多个事件的组合,如EV_RXCHAR|EV_TXEMPTY。函数结构如下:BOOL SetCommMask( HANDLE hFile, /通信驱动句柄 DWORD dwEvtMask); /串口事件掩码可使用下面函数对某事件进行查找:BOOL GetCommMask( HANDLE hFile, /通信驱动句柄,LPDWORD lpEvtMask ); /接收事件变量指针事件设置完毕后,可以调用下面函数等待驱动器上设置的事件的发生:BOOL WaitCommEvent( HANDLE hFile, /通信驱动句柄 LPDWORD lpEvtMask, /接收事件变量指针 LPOVERLAPPED lpOverlapped, ); /重叠结构体指针SetCommMask的调用会导致正在监听的WaitCommEvent()立即返回。,表3-2 串口可选的事件,通常,串口通信可以分为以下几个步骤,按这些步骤操作就可以创建自己的串口通信传输软件了。(1) 设置串口号码,使用CreateFile()函数打开串口;(2) 设置传输速度等参数;(3) 设置超时参数;,3.3 串口通信程序设计,(4) 设置事件掩码来监视指定通信端口上的事件;(5) 监控事件并写出或读入字符串,可以使用WriteFile()及ReadFile()函数;(6) 使用完毕后用CloseHandle()函数将串口关闭。由于使用Windows API中的函数作为串行通信的基础,使用CreateFile()函数打开串口后的返回值是一个数值(称为Handle),在往后的函数中,只要是和该串口有关的操作与设置,一定要使用到这个Handle。这个Handle就是在串口成功打开后,由操作系统配置的一个代码,程序所要求的操作也必须通过出示这个代码才得以进行。,换句话说,就是把这个分配到的Handle视为该串口的代表,当对该Handle进行操作时,操作系统会代为转向到实际的硬件对象(也就是COM1或COM2)上去。,3.3.1 枚举本地机串口串口的使用具有随机性,也就是用户在进行串口编程的时候并不知道哪一个串口处于连接状态,因此有必要对本地所有串口进行枚举。枚举的方法主要是查询注册表中HKEY_LOCAL_MACHINEHARDWAREDEVICEMAPSERIALCOMM下的键值。下面程序实现了对该键值的查询和屏幕打印,使用了RegOpenKeyEx()、RegEnumValue()、RegCloseKey()等三个注册表操作函数。除了实现枚举COM口的功能外,对于网络程序设计中其他相关的注册表操作也有借鉴作用。,#include stdafx.h#include windows.h /不要使用winreg.h,因其版本太旧容易引起错误int main(int argc, char* argv)char strSerialList25625; /临时定义256个字符串组,因为系统最多也就256个 ERROR_SUCCESS HKEY hKey;LPCTSTR,data_Set=HARDWAREDEVICEMAPSERIALCOMM;long ret0 = RegOpenKeyEx(HKEY_LOCAL_MACHINE, data_Set, 0, KEY_READ, /获取HKEY_LOCAL_MACHINEHARDWAREDEVICEMAPSERIALCOMM,键值下项数目RegQueryInfoKey(hKey,NULL,NULL,NULL, NULL,NULL,NULL,DWORD dwSizeofPortName;DWORD Type;dwName = sizeof(Name);dwSizeofPortName = sizeof(szPortName);for(DWORD i=0;icValues;i+) dwName = sizeof(Name);/一定要在每一次调用RegEnumValue时都要初始化! dwSizeofPortName = sizeof(szPortName); ZeroMemory(Name,256);,ZeroMemory(szPortName,256); Status = RegEnumValue(hKey, i, Name, ,/ COM调用return 0;程序执行后,COM将会填入strSerialList数组,以便后续调用。有时管理员会因安全原因关闭所有COM口,那么上述程序则无法查询到任何端口。,3.3.2 主机与单片机间的通信下面程序实现了主机与单片机之间的单工通信,有很多应用都是采用这种方式工作的,如主机从传感器中接收采集信息。假设连接于PC的COM4端口,该程序监听一个基于单片机无线接收器接收到的信号,接收数据由read_com()函数实现(假设最多接收256个字节)。#include stdafx.h#include DWORD read_com(HANDLE hCom,char * Buffer),COMSTAT ComStat;DWORD dwErrorFlags;BOOL bResult; DWORD nBytesToRead=256;DWORD nBytesRead;ClearCommError(hCom,int main(int argc, char* argv)HANDLE hCom;char com10=.COM4; / 1. 以同步读/写方式打开串口COM4, 这里的.COM4是COM的全名,最好写成这样hCom = CreateFile(com, /打开串口COM4,GENERIC_READ|GENERIC_WRITE, /允许进行读/写操作0, /独占方式NULL, OPEN_EXISTING, /打开一个存在的串口0, NULL);,/ 2. 将串口设置为:波特率为9600,数据位数为7位,停止位为2 位,偶校验,接收/缓冲区和发送缓冲区的大小均为1024个字节,最后用PurgeComm函数终止所有的后台/读/写操作并清空接收缓冲区和发送缓冲区DCB dcb;GetCommState(hCom,/必须调用一下GetCommState才能使SetCommState的,/返回值不为0!dcb.BaudRate = 9600; /波特率为9600dcb.ByteSize =7; /数据位数为7位dcb.Parity = EVENPARITY; /偶校验dcb.StopBits = 2; /两个停止位dcb.fBinary = TRUE;dcb.fParity = TRUE;if(SetCommState(hCom, ,return 0;SetupComm(hCom, 1024, 1024);/设置串口缓冲区的大小为1024位PurgeComm(hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);/清空串口缓冲区/ 3. 程序将串口读操作的超时设定为10 毫秒COMMTIMEOUTS to;,memset(,char rcvbuff256;ZeroMemory(,/ 5. 等待串口上出现了利用SetCommMask()函数设置的事件WaitCommEvent(hCom,read_num=read_com(hCom,rcvbuff);if(read_num=0)continue;/.接收数据处理ZeroMemory(rcvbuff, 256);while(1);/ 6. 关闭串口CloseHandle(hCom);return 0;,注意:在接收数据前,必须根据监控设备的有关通信参数约定双方的通信方式,包括各种参数的设置,如程序中的步骤2。,3.3.3 主机间的通信以下程序可以实现两台主机之间的串口数据传输,可用于计算机与路由器或交换机进行交互。在无网络可用的时候应急用。与3.3.1节中的程序功能不完全相同,最大的区别就是该程序是双工的。连接线采用TXD与RXD交叉相连、GND共线的方法。程序代码如下(下面主要列出了与3.3.1节中不同的代码):DWORD write_com(HANDLE hCom,char * Buffer),OVERLAPPED m_ov;BOOL bResult;DWORD nBytesToSend=strlen(Buffer);DWORD nBytesSend;char buff10;m_ov.Offset = 0;m_ov.OffsetHigh = 0;PurgeComm(hCom,PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_RXABORT|,PURGE_TXABORT);bResult = WriteFile(hCom,buff,nBytesToSend,/ 1. 以同步读/写方式打开串口COM4, 这里的.COM4是COM的全名,最好写成这样hCom = CreateFile(com, /打开串口COM4GENERIC_READ|GENERIC_WRITE, /允许进行读/写操作0, /独占方式NULL,OPEN_EXISTING, /打开一个存在的串口,FILE_FLAG_OVERLAPPED, /设置为异步串口NULL); /与3.3.2节的程序相同/ 4. 设置事件掩码来监视指定通信端口上的事件SetCommMask(hCom,EV_RXCHAR|EV_TXEMPTY|EV_BREAK);OVERLAPPED ov;,DWORD lpEvtMask;char buff256;ZeroMemory(,ov.hEvent = CreateEvent(0, true, 0, 0);PurgeComm(hCom, URGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);m_hEventArray0 =ov.hEvent;m_hEventArray1 =WriteEvent;m_hEventArray2 =ExitEvent;/ 5. 等待串口上出现读、写和关闭串口等三类事件do,if(WaitCommEvent(hCom, /等候1秒钟,switch (Event) /解析当前的Event事件 case 0: /若发生了读事件 GetCommMask(hCom, ,read_com(hCom,buff); /从COM中读数据 PurgeComm(hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); break; case 1: /若发生写事件, write_com(hCom,buff); /向COM中写数据 break; case 2: /若发生推出事件 CloseHandle(hCom); /关闭COM并退出,return 0; default: PurgeComm(hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); / end switch rintf(please input command:n); /询问用户手动发出指令printf(1.input S to send datan); /输入S或s字符以发送数据,printf(2.input E to exitn); /输入E或e字符以退出程序printf(3.input any other key to listen sequentiallyn);/输入其他键以继续监听int input=getchar();if(input=83|input=115) /判断输入的是否为S或s字符SetEvent(WriteEvent); /WriteEvent置位,strcpy(buff,data testn);else if(input=69|input=101) /判断输入的是否为E或e字符SetEvent(ExitEvent); /ExitEvent置位while(1);return 0;,该程序增加了一个写串口子函数write_com()。在CreateFile()函数中使用关键字FILE_FLAG_OVERLAPPED将该串口设置为异步模式(WaitCommEvent()不会阻塞)。此外,该函数与3.3.2节所讲的函数最主要的区别在于第5步。由于这步需要同时等候读、写和关闭串口这三类事件,因此又使用了一个WaitCommEvent()函数。程序每过1秒,就会等待用户手动发出指令。依照本节介绍的程序设计方法,读者还可以设计多种串口通信的应用,如PC与智能仪器、PC与GSM短息模块、PC与读卡器、PC与调制解调器等设备的通信。,串口是最简单的通信方式,这在OSI模型中的协议上层几乎没有涉及到,因此对串口编程的学习,是读者建立通信模型、由硬件通信向软件通信过渡的最佳起点,非常适合于初学者。此外,由于建立通信基本条件的门槛低、结构简单,因此串口也是目前网络设备必备的通信接口,应用极其广泛。本章重点介绍了串口通信的基本概念和主要工具,最后由简入繁,依次介绍了单工和双工两种串口通信的程序设计方法。,小 结,
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!