串行通信协议范文

2024-08-13

串行通信协议范文(精选11篇)

串行通信协议 第1篇

关键词:PLC,通信协议,VB6.0,串行通讯

可编程逻辑控制器 (PLC) 以其高可靠性、模块化结构、编程简单等优点, 在工控领域得了广泛应用。在绝大多数中小型控制系统中, 上位机与PLC的数据交换必不可少, 比如上位机对PLC的监控等, 如何实现两者的快速稳定通讯是每个控制系统需要考虑的问题。本文在VB6.0平台下, 依据三菱PLC的通信协议, 使用MSComm串行端口控件, 仅以简单串口连接线作为硬件连接, 即实现了PC机与FX2N系列PLC的稳定、快速通讯, 且该上位机系统可实现即插即用, 使用非常方便。

1 FX2n系列PLC的通信协议

使用三菱FX系列PLC通信协议进行PC与PLC的串行通讯时, 采用RS-232C设计标准, 需将PC通讯串口的通讯参数设置为9600, e, 7, 1。

1.1 PLC通信命令代码

对PLC的串行通讯所用命令如 (表1) 所示, 其中X表示输入开关量;Y表示输出开关量;M表示辅助开关量;S表示状态开关;T和C分别是定时器和计数器;D表示数据存储单元。

1.2 PLC通信控制指令

PC与PLC串行通讯的通信命令代码表明了PC对PLC可操作的对象及其状态, 那么用什么指令去控制这些对象使其实现所需的状态, 如表2所示, 使用表中相应控制指令实现, 其中的字符代码需用其ASCII码的十六进制 (0X) 表示。在VB6.0平台下, 若想使用“ENQ”, “ACK”, “STX”, “NAK”来代替相应的Ascii码值, 需要在程序段中加入“ENQ$=Chr$ (5) ”等程序语句。单字符数据传送格式如 (图1) 所示, 每个ASCII字符都遵循此原则, 首位起始位, 紧接7个数据位 (前低位, 后高位) , 1位偶校验, 1位停止位, 其波特率应设置为9600bps[4]。

2 基于通信协议的通讯报文分析

PC与PLC的通讯采用的“请求发送-回复应答”的通讯方式, 在此过程中, PC首先发送通讯请求给PLC, 即发送ENQ字符, 等待PLC的回复应答, 如果PLC返回ACK字符, PC读到给字符后, 则认为回复正确, 然后发送报文信息, 待PLC收到报文命令后会回复PC相应回复报文, 通讯就是以这个过程逐次发送报文的。如果PLC回复给PC的是NAK, 说明应答错误, 这种情况下, PC会再重新发送请求。下面通过实例对PC-PLC串行通讯的报文进行分析。

3 VB平台下通讯编程

VB6.0平台下, 有个串口专用控件, 名称为MSComm, 通过对该控件进行指令控制, 即可实现对表1中所有软元件的读和写操作, 也可置位或复位软开关。此过程不受PLC是否处于RUN状态影响[5]。

使用VB中的控件MSComm进行串行通讯设计, 其具体步骤如下: (1) 对通讯对象及所使用端口号进行属性设置; (2) 通讯协议设定及通讯报文准备; (3) 开通讯、传数据; (4) 通讯应答信号反馈; (5) 关通讯。

4 结语

系统所设计的通信设备的硬件连接方式和通信程序已成功应用于以FX2N系列PLC为主控器的剪切系统中, 通过实践证明, 系统有以下几个突出优点: (1) 系统不需外加三菱的任何专用通信板, 即可实现PC机-触摸屏-PLC的完美通信; (2) 应用三菱PLC通信协议进行通信, 不需对D8120进行设置, 不但简化了PLC程序, 而且通讯稳定可靠。 (3) 在有触摸屏进行现场控制的同时, VB开发的PC机监控程序可同时实现远程监控, 更独特的是PC机监控系统是即插即用模式, 可随时与系统分离, 这样对实验数据可方便地进行离线处理。 (4) 基于vb6.0平台的监控软件, 功能强大、经济实用界面友好、针对性强。

参考文献

[1]三菱公司.FX2N系列微型可编程控制器使用手册[M].上海:2008.

[2]三菱公司.MITSUBSHI FX通讯手册 (RS-232C, RS485) [M].上海:2007.

串行通信 第2篇

串行通信这里所说的通信是指计算机与计算机之间或计算机与外部设备之间的数据通信,基本的通信方式有两种:并行通信和串行通信。并行通信是多位数据同时传送,传送速度快,但需要较多的传输线,通信成本高,只适用于近距离的传送。串行通信是数据逐位顺序传送,从单纯传送数据的角度来说只需2~3根线,因而可以大大节省传输线。距离越长,这个优点越突出。显然串行通信的速度比并行通信慢,但是成本是系统构成的一个重要指标,因此长距离的数据传输都采用串行通信方式,

本章首先简要介绍数据通信的有关基础知识,接着要重点讨论属于外部总线的RS-232C串行通信总线以及PC系列机的串行通信,然后从应用角度介绍RS-422总线和RS-485总线,最后简要介绍一下通信协议。对于曾在PC/XT机中以单独芯片出现,并作为串行通信接口电路的核心在高档机中的逻辑或类似逻辑被集成到SuperI/0芯片中的Intel8250,这里仅从编程角度出发,介绍它的内部可编程寄存器以及初始化步骤。对于PC系列机串行通信的编程,这里考虑了汇编语言、DOS平台上的Turbo_c以及windows平台上的VisualC++和VisualBasic,给出了部分程序示例或程序片段

串行通信与重叠I/O 第3篇

关键词:串行通信;RS232;重叠;I/O;Win API

中图分类号:TN914文献标识码:A文章编号:1007-9599 (2010) 06-0000-02

Serial Communication and Overlapping I/O

Yu Lu,Li Qing

(PLA 91550 Troop,Dalian116023,China)

Abstract:The serial communication to facilitate easy,widely used in both military and civilian.In combination with the hardware described in detail in the Windows environment,use the Win API for asynchronous serial communication method.

Keywords:Serial communication;RS232;Overlap;I/O;Win API

一、前言

串行通讯在通讯领域被广泛应用,标准的RS232接口已成为计算机、计算机外设、交换机和许多通讯设备的标准接口。微机与微机、微机与外设、微机与程控交换机等都可以通过RS232接口进行方便的连接,以实现控制外设和传输数据等目的。

在Windows应用程序的开发中,我们常常需要面临与外围数据源设备通信的问题。笔者在实际工作中积累了一些经验,现结合硬件、软件,及需要注意的要点作一番探讨。希望对各位需要编写串口通信程序的朋友有一些帮助。

二、RS232串口标准

EIA-RS-232是美国电子工业协会正式公布的串行总线标准,也是目前最常用的串行接口标准。该标准规定:直接连接的最大物理距离为15m,通讯速率低于20kbps。

由于RS232并未定义连接器的物理特性,因此,出现了DB-25、DB-15和DB-9各种类型的连接器,其引脚的定义也各不相同。表1介绍了其中两种连接器(DB-25,DB-9)。

RS232标准接口有25条线,4条数据线、11条控制线、3条定时线、7条备用和未定义线,但常用的只有9根。

目前较为常用9针串口和25针串口,当通信距离较近时,可以用电缆线直接连接,若距离较远,须附加Modem。最为简单且常用的是三线制接法,即地、接收数据和发送数据三脚相连。表2列举了RS232串口通信接线方法。

EIA-RS-232对电气特性、逻辑电平和各种信号线功能都作了规定。

在TxD和RxD上:

逻辑1(MARK)=-3V~-15V。

逻辑0(SPACE)=+3V~+15V。

在RTS、CTS、DSR、DTR和DCD等控制线上:

信号有效:(接通,ON状态,正电压)=+3V~+15V。

信号无效:(断开,OFF状态,负电压)=-3V~-15V。

三、Win32串口应用程序

(一)打开串口

Win32系统把文件的概念进行了扩展。无论是文件、通信设备、命名管道、邮件槽、磁盘、还是控制台,都是用API函数CreateFile来打开或创建的。该函数的声明为:HANDLE CreateFile(LPCTSTR lpFileName,//文件名DWORD dwDesiredAccess,//访问模式DWORD dwShareMode,//共享模式LPSECURITY_ATTRIBUTES lpSecurityAttributes,//通常为NULL

DWORD dwCreationDistribution,//创建方式

DWORD dwFlagsAndAttributes,//文件属性和标志

HANDLE hTemplateFile // 临时文件的句柄,通常为NULL

);

如果调用成功,那么该函数返回文件的句柄,如果调用失败,则函数返回INVALID_HANDLE_VALUE。

(二)串口配置和串口属性

在打开通信设备句柄后,常常需要对串口进行一些初始化工作。这需要通过一个DCB结构来进行。DCB结构包含了诸如波特率、每个字符的数据位数、奇偶校验和停止位数等信息。在查询或配置串口的属性时,都要用DCB结构来作为缓冲区。

调用GetCommState函数可以获得串口的配置,该函数把当前配置填充到一个DCB结构中。一般在用CreateFile打开串口后,可以调用GetCommState函数来获取串口的初始配置。要修改串口的配置,应该先修改DCB结构,然后再调用SetCommState函数用指定的DCB结构来设置串口。

除了在DCB中的设置外,程序一般还需要设置I/O缓冲区的大小和超时。Windows用I/O缓冲区来暂存串口输入和输出的数据,如果通信的速率较高,则应该设置较大的缓冲区。调用SetupComm函数可以设置串口的输入和输出缓冲区的大小。

(三)串口读写

在用ReadFile和WriteFile读写串口时,既可以同步执行,也可以重叠(异步)执行。在同步执行时,函数直到操作完成后才返回。这意味着在同步执行时线程会被阻塞,从而导致效率下降。在重叠执行时,即使操作还未完成,调用的函数也会立即返回。费时的I/O操作在后台进行,这样线程就可以干别的事情。例如,线程可以在不同的句柄上同时执行I/O操作,甚至可以在同一句柄上同时进行读写操作。“重叠”一词的含义就在于此。

ReadFile函数只要在串口输入缓冲区中读入指定数量的字符,就算完成操作。而WriteFile函数不但要把指定数量的字符拷入到输出缓冲中,而且要等这些字符从串口送出去后才算完成操作。

ReadFile和WriteFile函数是否为执行重叠操作是由CreateFile函数决定的。如果在调用CreateFile创建句柄时指定了FILE_FLAG_OVERLAPPED标志,那么调用ReadFile和WriteFile对该句柄进行的读写操作就是重叠的,如果未指定重叠标志,则读写操作是同步的。

函数ReadFile和WriteFile的参数和返回值很相似。这里仅列出ReadFile函数的声明:

BOOL ReadFile(

HANDLE hFile,//文件句柄

LPVOID lpBuffer,//读缓冲区

DWORD nNumberOfBytesToRead,//要求读入的字节数

LPDWORD lpNumberOfBytesRead,//实际读入的字节数

LPOVERLAPPED lpOverlapped//指向一个OVERLAPPED结构

);//若返回TRUE则表明操作成功

需要注意的是如果该函数因为超时而返回,那么返回值是TRUE。参数lpOverlapped在重叠操作时应该指向一个OVERLAPPED结构,如果该参数为NULL,那么函数将进行同步操作,而不管句柄是否是由FILE_FLAG_OVERLAPPED标志建立的。

当ReadFile和WriteFile返回FALSE时,不一定就是操作失败,线程应该调用GetLastError函数分析返回的结果。例如,在重叠操作时如果操作还未完成函数就返回,那么函数就返回FALSE,而且GetLastError函数返回ERROR_IO_PENDING。

在使用重叠I/O时,线程需要创建OVERLAPPED结构以供读写函数使用。OVERLAPPED结构最重要的成员是hEvent,hEvent是一个事件对象句柄,线程应该用CreateEvent函数为hEvent成员创建一个手工重置事件,hEvent成员将作为线程的同步对象使用。如果读写函数未完成操作就返回,就那么把hEvent成员设置成无信号的。操作完成后(包括超时),hEvent会变成有信号的。

如果GetLastError函数返回ERROR_IO_PENDING,则说明重叠操作还为完成,线程可以等待操作完成。有两种等待办法:一种办法是用象WaitForSingleObject这样的等待函数来等待OVERLAPPED结构的hEvent成员,可以规定等待的时间,在等待函数返回后,调用GetOverlappedResult。另一种办法是调用GetOverlappedResult函数等待,如果指定该函数的bWait参数为TRUE,那么该函数将等待OVERLAPPED结构的hEvent事件。GetOverlappedResult可以返回一个OVERLAPPED结构来报告包括实际传输字节在内的重叠操作结果。

如果规定了读/写操作的超时,那么当超过规定时间后,hEvent成员会变成有信号的。因此,在超时发生后,WaitForSingleObject和GetOverlappedResult都会结束等待。WaitForSingleObject的dwMilliseconds参数会规定一个等待超时,该函数实际等待的时间是两个超时的最小值。注意GetOverlappedResult不能设置等待的时限,因此如果hEvent成员无信号,则该函数将一直等待下去。

在调用ReadFile和WriteFile之前,线程应该调用ClearCommError函数清除错误标志。该函数负责报告指定的错误和设备的当前状态。

调用PurgeComm函数可以终止正在进行的读写操作,该函数还会清除输入或输出缓冲区中的内容。

(四)超时设置

在用ReadFile和WriteFile读写串口时,需要考虑超时问题。如果在指定的时间内没有读出或写入指定数量的字符,那么ReadFile或WriteFile的操作就会结束。要查询当前的超时设置应调用GetCommTimeouts函数,该函数会填充一个COMMTIMEOUTS结构。调用SetCommTimeouts可以用某一个COMMTIMEOUTS结构的内容来设置超时。

有两种超时:间隔超时和总超时。间隔超时是指在接收时两个字符之间的最大时延,总超时是指读写操作总共花费的最大时间。写操作只支持总超时,而读操作两种超时均支持。用COMMTIMEOUTS结构可以规定读/写操作的超时,该结构的定义为:

typedef struct_COMMTIMEOUTS {

DWORD ReadIntervalTimeout;//读间隔超时

DWORD ReadTotalTimeoutMultiplier;//读时间系数

DWORD ReadTotalTimeoutConstant;//读时间常量

DWORD WriteTotalTimeoutMultiplier;//写时间系数

DWORD WriteTotalTimeoutConstant;//写时间常量

} COMMTIMEOUTS,*LPCOMMTIMEOUTS;

COMMTIMEOUTS结构的成员都以毫秒为单位。总超时的计算公式是:总超时=时间系数×要求读/写的字符数+时间常量

例如,如果要读入10个字符,那么读操作的总超时的计算公式为:读总超时=ReadTotalTimeoutMultiplier×10+ReadTotalTimeoutConstant

可以看出,间隔超时和总超时的设置是不相关的,这可以方便通信程序灵活地设置各种超时。

如果所有写超时参数均为0,那么就不使用写超时。如果ReadIntervalTimeout为0,那么就不使用读间隔超时,如果ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant都为0,则不使用读总超时。如果读间隔超时被设置成MAXDWORD并且两个读总超时为0,那么在读一次输入缓冲区中的内容后读操作就立即完成,而不管是否读入了要求的字符。

在用重叠方式读写串口时,虽然ReadFile和WriteFile在完成操作以前就可能返回,但超时仍然是起作用的。在这种情况下,超时规定的是操作的完成时间,而不是ReadFile和WriteFile的返回时间。

四、结束语

以上给出了用Win32 API设计串行通信的基本思路,这个重叠(异步)I/O操作的串行通信程序,曾多次应用于大型任务,表现出良好的性能。在实际应用中,可以以此为模型稍加改造,设计出满足需要的各种串行通信程序。

参考文献:

[1]李现勇.Visual C++串口通信技术与工程实践[M].人民邮电出版社,2004,7

串行通信协议 第4篇

在工业控制领域中,PLC作为一种稳定可靠的控制器得到了广泛的应用。但它也有一些自身的缺点:数据的计算处理和管理能力较弱,不能给用户提供良好的界面等。而计算机恰好能弥补PLC的不足,它不但有很强的数据处理和管理能力,而且能给用户提供非常美观而又易于操作的界面。

将PLC与计算机结合,可使系统既能及时地采集、存储数据,又可处理和使用好数据,这是PLC发展和应用的一个热点问题。计算机与PLC结合的关键是它们之间通信功能的实现,本文主要介绍如何利用Visual Basic的MSComm控件和Modbus协议来轻松地实现计算机与PLC之间的串行通信。

1 S7-200系列PLC的通信协议[1]

西门子S7-200系列PLC是一种小型整体结构形式的PLC,内部集成的PPI接口为用户提供了强大的通信功能,根据不同的协议,通过此接口与不同的设备进行通信或组成网络。

S7-200PLC支持多种通信协议,比如点到点(point-to-point)接口协议(PPI)、多点(Multi-Point)接口协议(MPI)、Profibus协议、用户定义的协议(自由端口模式)。而大多数用户选用的是对用户完全开放的自由端口模式。在自由端口模式,计算机与S7-200之间可以用以下的方法来通信:①使用Modbus从站协议;②使用用户自定义的协议(自由端口模式)。

自由端口模式为计算机或其它有串行通信接口的设备与S7-200PLC之间的通信提供了一种廉价和灵活的方法。计算机与PLC通信时,为了避免通信中各方争用通信线,一般采用主从方式,即计算机为主机,PLC为从机,只有主机才有权主动发送请求报文(Request message,或称为请求帧),从机收到后返回响应报文。

2 Modbus协议简介[2,3]

Modbus自1979年被MODICON公司开发以来,作为一种网络通信协议,它在工业自动化领域被广为应用。Modbus协议可以使用RS-232C兼容串行接口作为物理接口,方便实现基于数/模控制的仪表等终端设备的控制。

Modbus协议详细定义了校验码、数据序列等,这些都是特定数据交换的必要内容。Modbus协议在一根通信线上使用主从应答式连接(半双工),这意味着在一根单独的通信线上信号沿着相反的两个方向传输。首先,主计算机的指令信号寻址到一台惟一的终端设备(从机),然后,终端设备发出的应答信号以相反的方向传输给主机。另外,Modbus 协议只允许在主机(PC,PLC等)和终端设备之间通信,而不允许独立的终端设备之间的数据交换, 这样各终端设备不会在它们初始化时占据通信线路,而仅限于响应到达本机的查询信号。

Modbus协议有ASCII和RTU两种传输模式。其中,RTU模式信息帧中的8位数据包括两个4位十六进制字符,相对ASCII模式,RTU模式表达相同的信息需要较少的位数,在相同通信速率下具有更大的数据流量,因此通常情况下都是采用RTU模式的Modbus协议。RTU通信帧的基本结构见图1。

遵循Modbus RTU协议的主机—终端控制系统在运行过程中,相互之间经常需要进行数据传输,为了保证数据在传送过程中正确无误,必须引入某种差错检查机制对数据信息进行检验,以检测是否有数据传送错误。通常是使用检验码的方法来检测数据是否出错,而CRC就是常用的一种检验码。Modbus中生成CRC的步骤为:①预置一个16位寄存器为十六进制数FFFF(全为1),该寄存器称为CRC寄存器;②把第一个8位数据与16位CRC寄存器的低8位相异或,将结果放于CRC寄存器中;③把寄存器的内容右移一位(向最低位LSB方向),用0填补最高位MSB,并检查最低位;④如果最低位LSB为0,重复步骤③(再次移位),如果最低位LSB为1,CRC寄存器与多项式码A001Hex(1010000000000001)进行异或;⑤重复步骤③和④,直到右移8次,这样整个8位数据全部进行了处理;⑥重复步骤②到⑤,进行下一个8位数据的处理,直到所有的字节被处理;⑦最后得到的CRC寄存器内容即为CRC码。

必须注意,当CRC寄存器值被置入消息时,它的高位字节和低位字节必须交换。当16位CRC(两个8位字节)在消息中被传送,低位字节将先被传送,随后传送高位字节。

3 上位机通信程序设计

VB中的MSComm控件实用性强、功能完善,为应用程序提供了通过串行接口收发数据的简便方法。

MSComm控件提供两种处理通信的方式:一种是事件驱动方式,另一种是查询方式。事件驱动方式是处理串行端口交互作用的一种非常有效的方法,许多情况下在事件发生时需要得到通知。例如,在有字符到达或发生变化时,不管是发生通信事件或错误,程序都可以利用MSComm控件检测并处理。事件驱动方式的优点是程序响应及时、可靠性高;缺点是每个MSComm控件对应着一个串行端口,如果应用程序需要访问多个串行端口,必须使用多个MSComm控件。另一种是查询方式,这种方式实质上还是事件驱动,在程序的每个关键功能之后可以通过检查CommmEvent属性的值来查询事件和错误,如果应用程序较小且是自保持的,这种方法可能更为可取。

下面是用VB编制的串口及通信参数初始化程序:

上位机通信窗口界面见图2,PC机发送数据和接收数据的程序框图分别见图3和图4。

4 PLC通信程序设计

PLC通信程序遵循Modbus协议,采用模块化的子程序结构,即整体功能由多个功能相对独立的子功能组合实现,每个子功能由若干个任务单一的子程序构成。PLC通信程序框图见图5。

在S7-200的程序中使用Modbus从站协议指令的编程步骤如下:①在用户程序中调用Modbus从站指令;②为Modbus从站协议指令分配库内存;③处理Modbus协议与PPI协议的切换。

图6是Modbus从站协议指令的梯形图。在该梯形图中,Mode(模式)输入值用来选择通信协议:数值1将端口0指定给Modbus协议,并启用协议;Addr设置站地址的值;Baud(波特率)可以设为1 200、2 400、4 800、9 600、19 200、38 400、57 600或115 200;Parity(奇偶校验)与Modbus主设备的奇偶校验方式相同;Delay(延迟)参数以ms为单位,在有线网络上该参数的典型值应为0;MaxIQ指定Modbus主设备可以使用的I/Q的点数;MaxAI指定Modbus主设备可以使用的模拟量输入字的个数;MaxHold指定主设备可以访问的保持寄存器的最大个数;HoldStart用来设置保持寄存器的起始地址。

5 结束语

Modbus通信协议是工业自动化控制系统中一种重要的通信协议,其应用将越来越广泛。本文给出的基于Modbus通信协议的串行通信设计已得到了较好的应用。实际运行情况表明,通过采用Modbus通信协议的串行通信,保证了通信数据的安全、可靠和稳定。

参考文献

[1]廖常初.PLC编程及应用[M].北京:机械工业出版社,2005.

[2]冯向科,邓莹.基于MODBUS RTU通信协议下的CRC算法实现[J].电脑知识与技术,2006(8):43.

[3]孟开元.Modbus通信协议中CRC校验的快速C语言算法[J].福建电脑,2004(11):63-64.

[4]丁莉君,吴晓君.VB6.0下S7-200PLC与PC机的串行通信[J].制造业自动化,2007(1):84-86.

[5]李喜东,刘波涛,刘刚.Modbus RTU串行通讯协议在工业现场的应用[J].自动化技术与应用,2005(7):37-40.

C语言实现串行通信接口程序 第5篇

摘 要 本文说明了异步串行通信(RS-232)的工作方式,探讨了查询和中断两种软件接口利弊,并给出两种方式的C语言源程序。

的I/O通道之一,以最简单方式组成的串行双工线路只需两条信号线和一条公共地线,因此串行通信既有线路简单的优点同时也有它的缺点,即通信速率无法同并行通信相比,实际上EIA RS-232C在标准条件下的最大通信速率仅为20Kb/S。

尽管如此,大多数外设都提供了串行口接口,尤其在工业现场RS-232C的应用更为常见。IBM PC及兼容机系列都有RS-232的适配器,操作系统也提供了编程接口,系统接口分为DOS功能调用和BIOS功能调用两种:DOS INT 21H的03h和04h号功能调用为异步串行通信的接收和发送功能;而BIOS INT 14H有4组功能调用为串行通信服务,但DOS和BIOS功能调用都需握手信号,需数根信号线连接或彼此间互相短接,最为不便的是两者均为查询方式,不提供中断功能,难以实现高效率的通信程序,为此本文采用直接访问串行口硬件端口地址的方式,用C语言编写了串行通信查询和中断两种方式的接口程序。

1.串行口工作原理

微机串行通信采用EIA RS-232C标准,为单向不平衡传输方式,信号电平标准±12V,负逻辑,即逻辑1(MARKING)表示为信号电平-12V,逻辑0(SPACING)表示为信号电平+12V,最大传送距离15米,最大传送速率19.6K波特,其传送序列如图1,平时线路保持为1,传送数据开始时,先送起始位(0),然后传8(或7,6,5)个数据位(0,1),接着可传1位奇偶校验位,最后为1~2个停止位(1),由此可见,传送一个ASCII字符(7位),加上同步信号最少需9位数据位。

@@T8S12300.GIF;图1@@

串行通信的工作相当复杂,一般采用专用芯片来协调处理串行数据的发送接收,称为通用异步发送/接收器(UART),以节省CPU的时间,提高程序运行效率,IBM PC系列采用8250 UART来处理串行通信。

在BIOS数据区中的头8个字节为4个UART的端口首地址,但DOS只支持2个串行口:COM1(基地址0040:0000H)和COM2(基地址0040:0002H)。8250 UART共有10个可编程的单字节寄存器,占用7个端口地址,复用地址通过读/写操作和线路控制寄存器的第7位来区分。这10个寄存器的具体功能如下:

COM1(COM2) 寄存器

端口地址 功能 DLAB状态

3F8H(2F8H) 发送寄存器(写) 0

3F8H(2F8H) 接收寄存器(读) 0

3F8H(2F8H) 波特率因子低字节 1

3F9H(2F9H) 波特率因子高字节 1

3F9H(2F9H) 中断允许寄存器 0

3FAH(2FAH) 中断标志寄存器

3FBH(2FBH) 线路控制寄存器

3FCH(2FCH) MODEM控制寄存器

3FDH(2FDH) 线路状态寄存器

3FEH(2FEH) MODEM状态寄存器

注:DLAB为线路控制寄存器第七位在编写串行通信程序时,若采用低级方式,只需访问UART的.这10个寄存器即可,相对于直接控制通信的各个参量是方便可靠多了。其中MODEM控制/状态寄存器用于调制解调器的通信控制,一般情况下不太常用;中断状态/标志寄存器用于中断方式时的通信控制,需配合硬件中断控制器8259的编程;波特率因子高/低字节寄存器用于初始化串行口时通信速率的设定;线路控制/状态寄存器用于设置通信参数,反映当前状态;发送/接收寄存器通过读写操作来区分,不言而喻用于数据的发送和接收。

UART可向CPU发出一个硬件中断申请,此中断信号接到中断控制器8259,其中COM1接IRQ4(中断OCH),COM2接IRQ3(中断OBH)。用软件访问8259的中断允许寄存器(地址21H)来设置或屏蔽串行口的中断,需特别指出的是,设置中断方式串行通信时,MODEM控制寄存器的第三位必须置1,此时CPU才能响应UART中断允许寄存器许可的任何通信中断。

2.编程原理

程序1为查询通信方式接口程序,为一典型的数据采集例程。其中bioscom函数初始化COM1(此函数实际调用BIOS INT 14H中断0号功能)。这样在程序中就避免了具体设置波特率因子等繁琐工作,只需直接访问发送/接收寄存器(3F8H)和线路状态寄存器(3FDH)来控制UART的工作。线路状态寄存器的标志内容如下:

第0位 1=收到一字节数据

第1位 1=所收数据溢出

第2位 1=奇偶校验错

第3位 1=接收数据结构出错

第4位 1=断路检测

第5位 1=发送保存寄存器空

第6位 1=发送移位寄存器空

第7位 1=超时

当第0位为1时,标志UART已收到一完整字节,此时应及时将之读出,以免后续字符重叠,发生溢出错误,UART有发送保持寄存器和发送移位寄存器。发送数据时,程序将数据送入保持寄存器(当此寄存器为空时),UART自动等移位寄存器为空时将之写入,然后把数据转换成串行形式发送出去。

本程序先发送命令,然后循环检测,等待接收数据,当超过一定时间后视为数据串接收完毕。若接收到数据后返回0,否则返回1。

若以传送一个ASCII字符为例,用波特率9600 b/s,7个数据位,一个起始位,一个停止位来初始化UART,则计算机1秒可发送/接收的最大数据量仅为9600/9=1074字节,同计算机所具有的高速度是无法相比的,CPU的绝大部分时间耗费在循环检测标志位上。在一个有大量数据串行输入/输出的应用程序中,这种消耗是无法容忍的,也不是一种高效率通信方式,而且可以看到,在接收一个长度未知的数据串时,有可能发生遗漏。

程序2是一组中断方式通信接口程序。微机有两条用于串行通信的硬件中断通道IRQ3(COM2)和IRQ4(COM1),对应中断向量为OBH和OCH,可通过设置中断屏蔽寄存器(地址21H)来开放中断。置1时屏蔽该中断,否则开放中断。硬件中断例程必须在程序末尾往中断命令寄存器(地址20H)写入20H,即

MOV AL, 20H

OUT 20H, AL用以将当前中断服务寄存器清零,避免中断重复响应。

每路UART有4组中断,程序可通过中断允许寄存器(3F9H)来设置开放那路中断。这4组中断的位标志如下:

第0位 1=接收到数据

第1位 1=发送保持寄存器为空

第2位 1=接收数据出错

第3位 1=MODEM状态寄存器改变

第4~7位为0

在中断例程中检查UART的中断标志寄存器(3FAH),确定是哪一组事件申请中断。该寄存器第0位为0时表示有中断申请,响应该中断并采取相应措施后,UART自动复位中断标志;第2,1位标志中断类型,其位组合格式如下:代码 中断类型 复位措施11接收出错读线路状态寄存器10接收到数据读接收寄存器01发送寄存器空输出字符至发送寄存器00MODEM状态改变读MODEM状态寄存器这4组中断

的优先级为0号最低,3号最高。

在本组程序中,函数setinterrupt()和clearinterrupt()设置和恢复串行通信中断向量;cominit()初始化指定串行口并开放相应中断;sendcomdata()和getcomeomdata()用于发送和接收数据串;com1()和com2()为中断例程,二者均调用fax2()函数,fax2()函数为实际处理数据接收和发送的例程。明确了串行口的工作原理,就不难理解其具体程序。

3.结论

上述程序采用C语言编写,在BORLAND C++2.0集成环境中调试通过,为简单起见,只考虑了使用发送/接收两条信号线的情况,并未考虑使用握手信号线。

在实际应用中这两组程序尚有一些可修改之处。比如,中断接收程序中的缓冲区可改为循环表,以防数据溢出,尽可能保留最新数据。由于笔者水平所限,文中不足疏漏之处尚希行家指正。

程序1:

static int receive_delay=10000;

int may(unsigned par,char *comm,char *ss)

{int cs=0,j=0;

char *p;

bioscom(0,par,0); //com1

loop:p=comm;

inportb(0x3f8); //reset

do{ while((inportb(0x3f8+5)&0x20)==0); outportb(0x3f8,*p++);

}while(*p); //send command

os=0;j=0;

do{ if((inportb(0x3fd)&0x01)==0)

if(os〉receive_delay) break;

else { cs++;

continue; } ss[j++]=inportb(0x3f8); cs=0;

}while(l);

ss[j]=';

if(j) return 0;

else return 1;

程序2:

#include

#include

#include

#include

#inolude

#define maxsize 4096

#define SEND 2

#define RECEIVE 1

#define COM1 0

#define COM2 1

static unsigned char Hardinterrupt=0;

struct ComInterrupt

{int portadd;

int intbit;

char buf[maxsize],*comm;

int bufh,recount,sendcount;

}com[2]={{0x3f8,0x0c,”“,”“,0,0,0},

{0x2f8,0x0b,”“,”“,0,0,0} };

void static interrupt (*old_com[2])(void);

vold interrupt coml(vold);

void interrupt com2(void);

void fax2(int comnum);

void setinterrupt(int comnum);

void clearinterrupt(int comnum);

void cominit(int comnum, int para, int interruptmark);

void sendcomdata (int comnum,char *command);

int getcomdata (int comnum, char *buf);

void interrupt com1(void)

{fax2(0);}

void interrupt com2(void)

{fax2(1);}

// set cominterrupt, comnum 0=com1, 1=com2

void setinterrupt (int comnum)

{

old_com[comnum]=getvect(com[comnum].intbit);

if (!oomnum)

setvect(com[comnum].intbit,coml); //com1

else

setvect(com[comnum].intbit,com2); //com2

//set hard int

Hardinterrupt = inportb(0x21);

if(comnum)

outportb(0x21,Hardinterrupt&0xf7); //com2 ,0

else

outportb(0x21,Hardinterrupt&0xef); //com1 0,

}

void clear interrupt(int comnum)

{

if(comnum)

outportb(0x21,Hardinterrupt | 0x08); //COM2

else

outportb(0x21,Hardinterrupt|0x10); //COM1

setvect(com[comnum].intbit,old_com[comnum]);

for( i=0;i

com[comnum].sendcount=com[comnum].recount=com[comnum].bufh=0;

outportb(com[comnum].portadd+1,0);

outportb(com[comnum].por tadd+4,0x0);

}

void fax2(int i)//i=o,com1; i=1, com2

{ unsigned char mark;

mark=inport(com[i].portadd+2);

do

{

if(mark&0x4)// receive data

{ if (com[i].bufh==maxsize)

com[i].bufh=0; com[i].buf[com[i].bufh++]=inportb(com[i].portadd); com[

i].recount++;}

else if(mark&0x2)// send command

{ if(*com[i].comm)

outportb(com[i].p

ortadd,*com[

i].comm++);

com[i],sendcount++;}

else

outportb(com[i].portadd+1,1);

}

}while ((mark=inport([1]. portadd+2))!=1);

outportb(ox20,0x20); //hard int return

}

// interruptmark 1= reoeive, 2=send, 3=rec&send

void comint(int com, char para, int interruptmark)

{

bioscom(0, par, com);

//open com interrupt

outportbv (com[comnum]. portadd+4,0x8;

outportb (com[comnum].portadd+1,interruptmark);

}

void sendcomdata(int comnum,char * command)

{ unsigned char interruptmark;

com[comnum],comm=command;

com[comnum],sendcount=0;

//set send interrupt

interruptmark=inportb (com[comnum].portadd_1);

outportb (com[comnum].portadd+1.(interruptmark|2));

}

//get com_receivedate and clear com_receivebuf,

int getcomdata (int comnum, char * buf)

{ int result=com[comnum]. recount,i:

if(buf)

strncpy(buf,com[comnum].buf,com

[comnum].bufh);

buf[com[comnum].bufh]=" ;

com[comnum].recount=com [comnum].bufh=0;

retun(result);

串行通信协议 第6篇

【关键词】上位机;PLC;串行通信

1.引言

PLC是当前在工业现场数据信息采集活动中应用较为广泛的一种新兴工业控制器,由于在实际活动中所体现出的性能优越、数据精准等优势特点,备受国内外中众多相关厂家的亲睐。

以S市某化肥厂为例,在该化肥厂的集散控制系统中,传统的专业组态软件在连接上位机与PLC的过程中,出现了成本较高、控制难度较大等问题,针对这一问题,该化肥厂尝试重新进行系统结构与功能的调整,并重新设计现骨干软件,以满足了化肥厂现场生产工况的要求,实现了对现场数据准确的实时采集目标。

2.系统的结构与功能

2.1 硬件组成

S市某化肥厂的集散控制系统由两种通讯协议组成,即RS232和RS485,也有两种通讯协议存在一定的差异,这就需要相关工程技术人员需要利用ADAM4520来实现两种不同协议之间的转换过程。COM06这一单元模块有A、B个PORT口,A口符合RS232协议,B口符合RS422/RS485协议。在本系统中,集散控制系统共连接了4台PLC,而为了最大限度的确保程序在运行过程中的稳定性,技术人员采用双机冗余系统,这样可以确保一旦主机发生意外故障而无法正确运行时,备份机能够及时接班继续执行任务[1]。

2.2 符合通讯协议的电缆连接

为了确保通讯协议之间的转换能够顺利的进行,这就要求工程技术人员应当建立起符合两种通讯协议的电缆连接来。科学正确的电缆连接离不开对两种接口协议的正确认识。当前最为常见的串行接口标准、将计算机与计算机有机地进行数据通讯的协议是RS232,而相比较之下,RS232串行接口总线主要于以下情况,即设备器材之间的距离>15m,传输速率维持在最大20kB/s左右[2]。基于这一认识,本集散控制系统中计算机与ADAM4520l的接线就是符合RS232协议的串行电缆。

2.3 软件系统组成

在设计相关的软件系统时,设计人员首先应当明确自己的基本设计原则与设计理念。由于软件系统是为了正常的通讯功能而服务的,这就要求软件需要实现VB与PLC之间的成功通讯。一般情况下,我们往往采用两种上位机链接通信方式,即上位机向PLC发送通信请求命令与PLC向上位机发送通信请求命令。根据这两种方式,软件技术开发人员可以依据相关的工业管理来制定一定的通讯规约,如规定好上位机向PLC所发的命令帧格式及其命令帧的格式,规定 PLc向上位机返回的应答呵格式及其应答帧的格式。

由于在软件系统的运行过程中,上位机的命令帧是通过VB中MSComm通讯控件所产生的通信事件来实现命令发送的,因而,结合该化肥厂的实际工作情况,研究人员应当尽量控制PLC固定储存器区域中的数据[3]。PLC所返回的命令帧同样需要经过相关的软件数据进行通信接收,这就说明,研究人员采集在所需要的数据后,通过利用MSChart控件来显示实时数据的方式,能够顺利地完成了生产现场实时数据的准确采集。

3.软件的设计

3.1 MSComm通讯控件的设计

在VB当中,MSComm控件实现成功通讯的重要控件,而在设计过程中,设计人员应当着重注意以下几点。首先要做好初始化工作,这就要求设计人员在设置端口号时,应当以当前所使用的串行口作为基本参考对象。在设置好端口号之后,设计人员设置好Settings工作,对停止位、奇偶校验、波特率、数据位等基本参数进行标准设置。在设置过程中设计人员要注意设置读取数据的类型与其读取的字符数。当设置InputLen为0时,设计人员需要利用MSComm控件来读取缓冲区中的全部内容;当设置Rthreshold为1时,设计人员则需要将接收到的每一个字符都经过MSComm控件进而产生OnComm事件[4]。

3.2 软件的握手

实现软件握手,设计人员需要注意以下几个问题:

第一,要确保VB程序与PLC实现成功通信,确保程序所发送的命令帧正确无误。这就要求设计人员要仔细鉴定分析应答帧的结束码,判断其是否出错,如若出现错误,则应当依据错误的具体类型进行针对性处理;

第二,在通讯程序的OnComm事件中,设计人员应当判断CommEvent是否产生接收事件,如若产生,则应当接收,否则不接收;

第三,在处理程序中错误语句的活动中,设计人员应当不断提高系统自身的应對能力和防御能力,以及时有效地辨认用户的错误语句,避免不必要的麻烦[5]。

3.3 程序基本轮廓设计思想

设计人员在设计程序的基本轮廓时,应当首要利用VB的事件驱动特性,充分发挥出用户的自主选择权,让用户能够依据自身需求来选择是利用全部四台PLC进行运作还是只使用当中的一台。如果选择全部运作,那么设计人员应当设计好所有的通信接电的相应命令帧,并实时进行检测与观察;如果选择运行单个的PLC,那么设计人员需要输入与PLC从站单元相对应的所想要显示采集数据的节点号,并与用户的确认步骤进行同步操作,从而实现通过通讯端口定时从现场PLC中接收数据的目的[6]。需要指出的是,本程序的运行环境是windowsxp与VB6.0,在实际操作过程中,用户可以通过个人的喜好与实际的需求从PLC单元对现场数据进行实时采集分析处理,一旦出现突发事件,依据已采集的数据与当前具体情况技术人员能够对其进行相应处理。

4.结束语

当前在工业控制活动中,上位机与可PLC之间的串行通信已经成为其中的重要组成部分。面临日益严峻的市场竞争压力与发展形势,企业需要从集散控制系统的构造与软件程序的开发应用两方面着手来推行通讯的成功实现。

通过有效利用高级语言VB,将其与C200HE进行有机地连接,进而利用串行通信来实现对化肥厂现场数据信息采集的目的,具有稳定性、灵活性、高校性等一系列优势特点。当前基于上位机与PLC之间的串行通信数据系统已经在S市的某化肥厂正式投入使用,并取得了预期的效果。这说明,随着相关厂家其生产活动的自动化程度不断提高,串行通信数据系统的应用将不断拓展到更深更广泛的领域。

参考文献

[1]何默为,刘永贤.上位机与PLC远程通信实现动态数据采集研究[J].机械与电子,2011,2(04):69-70.

[2]刘玉国,李居峰.基于PLC的现场数据采集和自动化控制[J].现代机械,2012,2(03):116-117.

[3]白冰,潘真,靳继红,等.基于PLC现场数据采集与分析[J].科技情报开发与经济,2010,10(21):55-56.

[4]陆嘉,李常辉,刘银锁,等.基于VB的PLC与上位机通信软件的设计[J].自动化技术与应用,2010,5(09):106-107.

[5]蔡倩,经亚枝.Windows环境下PLC与上位机的串行通信[J].电脑开发与应用,2013,2(03):90-91.

[6]周雪辉,朱永兴,吴燕翔.PLC与上位机的串行通信实现[J].上海水产大学学报,2014,1(02):84-85.

双机串行通信设计 第7篇

单片机技术作为计算机技术的一个重要分支, 由于单片机体积小, 系统运行可靠, 数据采集方便灵活, 成本低廉等优点, 在通信中发挥着越来越重要的作用。但能在一些相对复杂的单片机应用系统中, 仅仅一个单片机资源是不够的, 往往需要两个或多个单片机系统协同工作。这就对单片机通信功能的要求不断增加。因此, 单片机通信功能是否满足设计要求是设计中的一个关键问题。

单片机之间的通信可以分为两大类:并行通信和串行通信。串行通信传输线少, 长距离传输时成本低, 且可以利用电话网等现成的设备, 所以本系统采用串行通信来实现单片机之间可靠的, 有效的数据交换。

一、概述

1、系统概述

MCS-51单片机系列是Intel公司推出的功能强、速度快的8位高档单片微型计算机系列产品, 是当前工业测试系统中较理想的一种, 内部有一个可编程的全双工的串行通信口, 即串行通信和发送缓冲器 (SBUF) , 这两个在物理上是独立的接收发送器, 既可以发送数据, 也可以接收数据。全双工的串行通信只需要一根输出线 (发送数据TXD) 和一根输入线 (接收数据RXD) 。串行通信中主要有两种技术问题, 一个是数据传送, 另一个是数据转换。具体说, 在发送端, 要把并行数据转换为串行数据;而在接收端, 则要把接收到的串行数据转换为并行数据。

串行数据传送是将构成字符的每个二进制数据按一定的顺序进行传送的方式,

串行通信协议规定字符数据的传送格式如图1所示, 每个串行数据由起始位、数据位、奇偶校检位和停止位组成。本系统就是利用单片机的串行口, 以串行通信方式, 实现两单片机之间的数据交换, 信息共享。

2、方案设计

本系统利用单片机的串行口, 由软件和硬件两部分协调实现两单片机的串行数据传输。硬件电路以AT89C51单片机为核心, 外围电路包括键盘电路 (数据的输入) , 显示电路 (数据的输出) 。工作在硬件电路基础上的软件主要完成数据的输入, 存储, 显示, 发送和接收。由于两单片机相距很近, 可以直接将其串行口相连。系统整体电路图如图2所示。

3、研究方向和技术关键

本系统主要研究两单片机之间的串行数据传输, 实现两单片机之间的信息共享。将P1口连接2个键盘, 作为输入数据控制端。利用单片机的定时/计数器T1来设定P2口的数据显示, 并通过传输线把数据发送给另外一个单片机。本系统的技术关键在于准确的, 高效率的传输信息。主要技术指标: (1) 比特吞吐特性 (2) 有效性 (3) 数据的安全性

二、设计原理

此设计以AT89C51单片机为核心, 利用其内部的串行口, 通过硬件与软件相结合的方式, 实现双机的全双工的串行通信。硬件电路包括键盘电路, 显示电路, 单片机主控电路, 串行通信线和电源电路。软件包括键盘扫描程序, 显示程序, 发送程序和接受程序。发送和接收都采用

中断方式。硬件电路的组成如图3所示。

由于两个单片机应用系统相距很近, 近程通信时 (通信距离小于15米) , 可以

不使用调制解调器, 将它们的串行口直接相连就可以实现全双工的串行通信。

1、硬件设计

(1) 系统组成

下面就以1号机为例, 介绍硬件。硬件电路包括AT89C51单片机, 共阳性LED数码管以及传输线。

AT89C51是一个低电压, 低功耗, 高性能CMOS 8位单片机, 40个引脚, 32个外部双向输入/输出 (I/O) 端口, 同时内含2个外设中断口, 2个16位可编程定时计数器, 2个全双工串行通信口。AT89C51可以按照常规的方法进行编程, 也可以在线编程。片内含4k bytes的可反复擦写的Flash只读程序存储器和128 bytes的随机存取数据存储器 (RAM) , 器件采用ATMEL公司的高密度、非易失性存储技术生产, 兼容标准MCS-51指令系统。

共阳极七段LED数码管见图4所示。

(2) 单片机主控电路

AT89C51是片内有ROM/EPROM的单片机, 用其构成最小应用系统时, 只要将单片机接上时钟电路和复位电路即可。

(1) 晶振电路

AT89C51单片机的时钟信号通常有两种形式:一种是内部时钟方式, 另外一种是外部时钟方式。内部时钟方式是在单片机的XTAL1和XTAL2引脚外接石英晶体, 就构成了自激震荡并在单片机内部产生时钟脉冲信号。本设计采用内部时钟方式, 可以不受设备条件的影响。

(2) 复位电路

当在AT89C51单片机的RST引脚引入高电平并保持两个机器周期时, 单片机内部就执行复位操作。在实际应用中, 复位操作有两个基本形式:一种是上电复位, 另一种是上电与按键均有效的复位。本系统采用上电与按键均有效的复位。

开机瞬间RST引脚获得高电平, 随着电容C的充电, RST引脚的高电平将获得下降。RST引脚的高电平只能保持足够的时间 (2个机器周期) , 单片机就可以进行复位操作。另外在单片机运行期间, 还可以利用按键完成复位操作。

(3) 键盘电路

按键实际上就是简单的开关, 当按键按下时, 相当于开关闭合;当按键松开时, 相当于开关断开。操作员通过键盘输入数据或命令, 实现简单的人机对话。

按键有独立式按键和行列式按键。独立式按键的各个按键相互独立, 每一个按键独立地与一根数据输入线相连。独立式按键配置灵活, 软件结构简单, 但每个按键必须占用一根口线, 在按键数量多时, 口线占用多。所以, 独立式按键常用于按键数量不多的场合。由于此系统所用的按键较少, 故选用独立式按键。

(4) 显示电路

显示器是单片机应用系统常用的设备, 主要包括LED和LCD。LED显示器由若干个发光二极管组成。当发光二极管导通时, 相应的一个笔画或一个点就发光, 控制相应的二极管导通, 就能显示出对应字符。七段LED通常构成字型“8”, 还有一个发光二极管用来显示小数点。由于LED显示器成本低廉, 配置灵活, 并且与单片机接口方便, 所以本系统选用七段LED显示器 (共阳极) 。

(5) 总体硬件电路图

本设计总体硬件电路图如图5所示。

2、系统软件设计

(1) 总体方案

此系统欲实现双机的全双工的串行通信。甲乙两机的内部软件是完全相同的, 1号机和2号机都能发送和接收数据信息, 能同时进行数据交换。

假设1号机为发送方, 2号机为接收方。当按下发送按键时, 1号机开始发送数据, 存储在R7中并通过显示器显示。按下2号机的接收按键, 2号机开始接收数据, 每接收一个数值就直接送到显示器显示。本设计通过键盘输入数据。利用软件控制键盘进行加1或者减1操作, 可以使其输入0~F之间的任意一个数。

(2) 模块说明

(1) 串行口工作方式

单片机的串行通信口是可编程的, 在工作之前应该初始化, 对它初始化编程只需将两个控制字分别写入特殊功能寄存器SCON[98H]和电源控制寄存器PCON[97H]即可。

串行控制寄存器SCON是一个特殊功能寄存器, 用以设定串行口的工作方式、发送/接收控制以及设置控制状态标志。字节地址为98H, 可进行位寻址, SM0和SM1 (SCON.7和SCON.6) :串行口工作方式选择位, 可选择4种工作方式 (见表1)

本系统采用串行口方式1 (SM0置0, SM1置1) 进行通信, 一帧信息为10位, 其中有1个起始位, 8个数据位和1个停止位。

(2) 中断口设定

AT89C51单片机有5个中断源, 在应用之前应该初始化。

本系统用到外部中断, 外部中断, 作为发送中断, 入口地址是0003H。当此键按下, 转到中断服务程序 (执行发送程序) 。作为接收中断, 入口地址是0013H。当此键按下, 转到中断服务程序 (执行接收程序) 。

中断控制寄存器TCON中IT0位, IT1位应置0, 采用电平触发方式。中断允许控制寄存器IE中EX0、EX1、ES位应置1, 允许中断。

(3) 键盘工作设定

本系统采用独立式按键结构。对于是否有按键按下的信息输入方式有中断方式和查询方式, 本系统采用查询方式。

本系统的键盘控制程序分为以下几个部分:

(1) 判断有无键按下;

(2) 用软件编程的方式控制键盘的输入数值;

(3) 可靠的逻辑处理方法。

(4) 显示工作设定

显示程序用查表法显示, 七段数码管 (共阳性) 显示段选码如表2所示。

三、调试

本设计采用软件和硬件结合的方式进行串行数据传送。在电路板检查完好的前提下, 重在软件的调试。程序写好后, 用Keil C编译软件进行编译检查, 没有语法错误。再用Keil C调试软件对程序进行单步运行, 通过各窗口观察程序每一步的执行结果, 程序工作正常, 程序调试结束。

四、结论

串行口通信技术应用探究 第8篇

计算机与外部设备的连接,不是通过并行口就是通过串行口。并行口编程很简单,相对而言,串行口的编程就要复杂得多了。为了进行可靠的串行通信,标准串行口必须具有握手信号和状态信息。但由于串行口通信是为相距一定距离的两台或两台以上设备提供彼此连接的最方便的办法,尽管编程较复杂,但应用得还是相当广泛。下面针对串口通信进行探究。

1 数据异步串行的发送和接收

数据异步串行的发送和接收具有异步和串行两个特点。所谓“串行”是指一次一个数据位,而并行是一次一个字节。所谓“异步”,是指相邻两个字节之间的停顿时间是长短不一的,尽管同一个字节内各位的定时和顺序是非常严格的。很容易想到有异步串行就会有同步串行,但是为了简单起见,这里把异步串行口就简称为“串行口”。在串行口中收发的每一个字节数据是由以下4个部分按顺序组成的:1个起始位,8个数据位(在某些情况下是7个),奇偶校验位(可有可无,可奇可偶),1个或2个停止位。在每两个字节之间,可以停顿任意长时间。

数据收发线的空状态是高电平。起始位标志着一个新字节传送的开始,与一个数据位占用同样的时间宽度,低电平。起始位之后是奇偶校验位,在奇偶校验位之后就是停止位,它可以占一位或两位数据位的时间宽度。停止位是低电平,它表示一个字节传送的结束。在停止位之后,可以接着又是下一个字节的起始位,也可以在停顿任意长时间之后,才是下一个字节的起始位。

2 RS-232标准

2.1 RS-232标准信号

大部分串行口的结构都是在发送和接收双方都装有一个25针插座,都不很严格地遵循RS-232标准。制造厂家最经常提供的RS-232信号是:针号为3的TXD(发送数据);针号为2的RXD(接收数据);针号为5的GRD(地)。这些信号中许多是为支持Modem而定义,在计算机和Modem之间建立硬件规约,以便在Modem可以接收数据之前计算机不会向它发送数据,在Modem准备好数据之前计算机不会从它那儿接收数据。

如果控制通信双方串行口的内部时钟彼此不一样,则可能引起所谓的“帧错”(framing error)。容易想到,接收方的串行口一旦检测一个起始位,它就会周期性地去对传输线进行取样,得到每一位的信号。这个周期的长短是由波特率计算出来的。然而,每次取样的实际时刻却是由系统内部的主时钟决定的,在传输线上并没有这样一个取样时钟信号。因此,如果双方的波特率不一致,或者系统内部的主时钟发生了偏差,都可能造成发送和接收双方不协调一致,从而发生“帧错”。

2.2 硬件握手

通过串行口发送数据的正确做法是不断地监视接收口上的CTS信号。只有当CTS信号表明可以安全发送数据时才去发送数据。因此,当使用了硬件握手信号时,伪C码描述的发送程序如下所示:

如果通信双方都支持RS-232标准,并且彼此之间的电缆连接也是正确的,那么显然应该使用握手信号。但是,实际情况两者大都不能同时满足。

3 通信问题

如果通信是在计算机之间进行,则也可以只使用GND,TXD和RXD三个信号线就能解决问题。如果两台同样类型的计算机彼此进行通信,当一台准备好发送数据时,在理论上另一台一定准备好接收这个数据,这样可以省略掉RTS、CTS这些信号了。但是省略掉这些信号之后,却可能招来很多其他麻烦,其中最糟糕的就是“过冲”(Overrun)错。

当连接两个串行口的电缆线只有三根(GND,RXD,TXD)时,发送方根本无法知道接收方什么时候可以接收数据,所以只好造一个假信号去愚弄发送对方,使它误以为接收方任何时候都准备好了接收数据。具体做法是把25针插座中的针6(DSR),针8(CD)和针20(DTR)直接连接在一起。但这样一来却很容易引起“过冲”错。例如,假设计算机A比计算机B速度快,由于没有任何硬件握手信号,计算机A误以为计算机总是可以接收数据的,结果在计算机B可以来得及读取计算机A发送来的第一个字节之前,计算机A又发送来了第二个字节,这就引起了“过冲”错。即使计算机B的速度比计算机A快,但计算机B的软件速度太慢也可能引起这类“过冲”错。

4 通过BIOS调用存取PC的串口

4.1 串行口的初始化

在使用串行口之前,需要首先对它进行初始化,以便设置与缺省设置不一样的串行口参数。第一个串行口的缺省设置是1200波特率,偶校验,7个数据位,1个停止位。中断14H的子功能号0就是用来初始化串行口的,其入口参数是:寄存器AH等于0,AL为初始化参数,DX为串行口号。一个字节的初始化参数分为4个部分:位7至位5说明波特率的大小,位4和位3说明有无校验位和什么样的校验,位2说明停止位的位数,位1和位0说明数据位的位数,其格式如图1所示。

比如某个串行口的波特率为9600,偶校验,1个停止位,8个数据位,则AL寄存器中的值是11111011,即十进制251。

在一台标准的PC机上,最多可以有7个串行口。在一些较新的计算机上,串行口的数目还要多。在使用BIOS调用时,需要在DX寄存器内说明初始化哪一个串行口。串行口的编号是从0开始。下面的int_port函数就是对串行口进行初始化的。

4.2 发送一个字节

中断14H中的子功能号1是用来通过串行口发送一个字节的,其入口参数是:AH寄存器含有状态信息。如果返回时AH寄存器的位7是1,则表明发送有错。错误的具体原因和性质还必须通过读串行口的状态才能断定。下面就是通过指定串行口发送一个字节的函数sport。

4.3 检查串行口的状态

中断14H中的子功能号3是用来检查串行口的状态的,其入口参数是:寄存器AH等于3,DX是串行口号。返回时,AH和AL寄存器含有串行口的状态信息,当某一位置1时,其相应的含义如下:

从上面的表可以看出,这些状态大部分是针对Modem的。如果使用串行口的目的是为了把计算机和非调制解调器设备相连接,则可以忽略其中大部分状态信息。然而有一个状态信息在此种情况下却是至关重要的,这就是AH寄存器位0的“数据准备好”信息。借助于这个信息就可以知道串行口是否接到一个字节可以被CPU读取。下面就是通过串行口读取一个字节的函数rport。

应该注意,如果串行口当前无数据可读,中断14H的子功能号2是一直等待的,直到接收到一个字节才返回。但采用这个办法后,当遇到某些串行口错误时,例如,忘记插电缆,就可能使计算机“死机”。为了避免这个问题的发生,函数rport首先读取指定串行口的状态,检查“数据准备好”这一位。如果没有准备好,则还调用kbhit函数去检查用户是否打入了一个键。如果没有击键,则继续循环检查“数据准备好”位。如果击了一键,则去读取这个键值并退出。

5 在计算机之间传送文件

当多个型号不同计算机要共享数据或程序,若硬件上已经提供了硬件握手信号,则应尽量利用。但实际环境常常不提供这些信号或提供的不准确,这时为避免文件传送过程中发生“过冲”错的唯一办法就是实现软件握手,即发送方发送一个字节后,就一直等待着从接收方收到一个“认可”字节,只有在收到这个“认可”字节以后,发送方才发送第二个字节,并接着等待接收方收到第二个“认可”字节,这个过程一直持续到整个文件发送完毕。如果使用伪C码来表示,可以把发送和接收程序过程描述如下:

尽管软件握手的办法会降低文件传送速度,但却提供了传输的可靠性办法。

6 结束语

采用软件握手以后,不管两台计算机的速度相差多远,发送方永远也不会超前于接收方。传送文件的每一个字节,在传送线上要来回传送两次,因此降低了速度,却实现了可靠性。

参考文献

[1]李牧,何明星,汤波,胡训强.微机系统与接口[M].北京:冶金工业出版社,2007.

[2]王效华,张咏梅.单片机原理与应用[M].北京:北京交通大学出版社,2007.

[3]串口通信协议[EB/OL].http://baike.baidu.com/view/2459734.htm

串行通信与重叠I/O 第9篇

串行通信在通信领域被广泛应用,标准的RS232接口已成为计算机、计算机外设、交换机和许多通信设备的标准接口。微机与微机、微机与外设、微机与程控交换机等都可以通过RS232接口进行方便的连接,以实现控制外设和传输数据等目的。

在Windows应用程序的开发中,我们常常需要面临与外围数据源设备通信的问题。笔者在实际工作中积累了一些经验,现结合硬件、软件,及需要注意的要点作一番探讨。希望对各位需要编写串口通信程序的朋友有一些帮助。

2 RS232串口标准

EIA-RS-232是美国电子工业协会正式公布的串行总线标准,也是目前最常用的串行接口标准。该标准规定:直接连接的最大物理距离为15m,通信速率低于20kbps。

由于RS232并未定义连接器的物理特性,因此,出现了DB-25、DB-15和DB-9各种类型的连接器,其引脚的定义也各不相同。表1介绍了其中两种连接器(DB-25, DB-9)。

RS232标准接口有25条线,4条数据线、11条控制线、3条定时线、7条备用和未定义线,但常用的只有9根。

目前较为常用9针串口和25针串口,当通信距离较近时,可以用电缆线直接连接,若距离较远,须附加Modem。最为简单且常用的是三线制接法,即地、接收数据和发送数据三脚相连。表2列举了RS232串口通信接线方法。

EIA-RS-232对电气特性、逻辑电平和各种信号线功能都作了规定。

在TxD和RxD上:

(1) 逻辑1 (MARK) =-3V~-15V。

(2) 逻辑0 (SPACE) =+3V~+15V。

在RTS、CTS、DSR、DTR和DCD等控制线上:

(1) 信号有效: (接通, ON状态, 正电压) =+3V~+15V。

(2) 信号无效: (断开, OFF状态, 负电压) =-3V~-15V。

3 Win32串口应用程序

3.1 打开串口

Win32系统把文件的概念进行了扩展。无论是文件、通信设备、命名管道、邮件槽、磁盘、还是控制台,都是用API函数CreateFile来打开或创建的。该函数的声明为:

如果调用成功,那么该函数返回文件的句柄,如果调用失败,则函数返回INVALID_HANDLE_VALUE。

3.2 串口配置和串口属性

在打开通信设备句柄后,常常需要对串口进行一些初始化工作。这需要通过一个DCB结构来进行。DCB结构包含了诸如波特率、每个字符的数据位数、奇偶校验和停止位数等信息。在查询或配置串口的属性时,都要用DCB结构来作为缓冲区。

调用GetCommState函数可以获得串口的配置,该函数把当前配置填充到一个DCB结构中。一般在用CreateFile打开串口后,可以调用GetCommState函数来获取串口的初始配置。要修改串口的配置,应该先修改DCB结构,然后再调用SetCommState函数用指定的DCB结构来设置串口。

除了在DCB中的设置外,程序一般还需要设置I/O缓冲区的大小和超时。Windows用I/O缓冲区来暂存串口输入和输出的数据,如果通信的速率较高,则应该设置较大的缓冲区。调用SetupComm函数可以设置串口的输入和输出缓冲区的大小。

3.3 串口读写

在用ReadFile和WriteFile读写串口时,既可以同步执行,也可以重叠(异步)执行。在同步执行时,函数直到操作完成后才返回。这意味着在同步执行时线程会被阻塞,从而导致效率下降。在重叠执行时,即使操作还未完成,调用的函数也会立即返回。费时的I/O操作在后台进行,这样线程就可以干别的事情。例如,线程可以在不同的句柄上同时执行I/O操作,甚至可以在同一句柄上同时进行读写操作。“重叠”一词的含义就在于此。

ReadFile函数只要在串口输入缓冲区中读入指定数量的字符,就算完成操作。而WriteFile函数不但要把指定数量的字符拷入到输出缓冲中,而且要等这些字符从串口送出去后才算完成操作。

ReadFile和WriteFile函数是否为执行重叠操作是由CreateFile函数决定的。如果在调用CreateFile创建句柄时指定了FILE_FLAG_OVERLAPPED标志,那么调用ReadFile和WriteFile对该句柄进行的读写操作就是重叠的,如果未指定重叠标志,则读写操作是同步的。

函数ReadFile和WriteFile的参数和返回值很相似。这里仅列出ReadFile函数的声明:

需要注意的是如果该函数因为超时而返回,那么返回值是TRUE。参数lpOverlapped在重叠操作时应该指向一个OVERLAPPED结构,如果该参数为NULL,那么函数将进行同步操作,而不管句柄是否是由FILE_FLAG_OVERLAPPED标志建立的。

当ReadFile和WriteFile返回FALSE时,不一定就是操作失败,线程应该调用GetLastError函数分析返回的结果。例如,在重叠操作时如果操作还未完成函数就返回,那么函数就返回FALSE,而且GetLastError函数返回ERROR_IO_PENDING。

在使用重叠I/O时,线程需要创建OVERLAPPED结构以供读写函数使用。OVERLAPPED结构最重要的成员是hEvent, hEvent是一个事件对象句柄,线程应该用CreateEvent函数为hEvent成员创建一个手工重置事件,hEvent成员将作为线程的同步对象使用。如果读写函数未完成操作就返回,就那么把hEvent成员设置成无信号的。操作完成后(包括超时),hEvent会变成有信号的。

如果GetLastError函数返回ERROR_IO_PENDING,则说明重叠操作还未完成,线程可以等待操作完成。有两种等待办法:一种办法是用象WaitForSingleObject这样的等待函数来等待OVERLAPPED结构的hEvent成员,可以规定等待的时间,在等待函数返回后,调用GetOverlappedResult。另一种办法是调用GetOverlappedResult函数等待,如果指定该函数的bWait参数为TRUE,那么该函数将等待OVERLAPPED结构的hEvent事件。GetOverlappedResult可以返回一个OVERLAPPED结构来报告包括实际传输字节在内的重叠操作结果。

如果规定了读/写操作的超时,那么当超过规定时间后,hEvent成员会变成有信号的。因此,在超时发生后,WaitForS-ingleObject和GetOverlappedResult都会结束等待。WaitForSingleObject的dwMilliseconds参数会规定一个等待超时,该函数实际等待的时间是两个超时的最小值。注意GetOverlappedResult不能设置等待的时限,因此如果hEvent成员无信号,则该函数将一直等待下去。

在调用ReadFile和WriteFile之前,线程应该调用ClearCommError函数清除错误标志。该函数负责报告指定的错误和设备的当前状态。

调用PurgeComm函数可以终止正在进行的读写操作,该函数还会清除输入或输出缓冲区中的内容。

3.4 超时设置

在用ReadFile和WriteFile读写串口时,需要考虑超时问题。如果在指定的时间内没有读出或写入指定数量的字符,那么ReadFile或WriteFile的操作就会结束。要查询当前的超时设置应调用GetCommTimeouts函数,该函数会填充一个COMMTIMEOUTS结构。调用SetCommTimeouts可以用某一个COMMTIMEOUTS结构的内容来设置超时。

有两种超时:间隔超时和总超时。间隔超时是指在接收时两个字符之间的最大时延,总超时是指读写操作总共花费的最大时间。写操作只支持总超时,而读操作两种超时均支持。用COMMTIMEOUTS结构可以规定读/写操作的超时,该结构的定义为:

COMMTIMEOUTS结构的成员都以毫秒为单位。总超时的计算公式是:总超时=时间系数×要求读/写的字符数+时间常量

例如, 如果要读入10个字符, 那么读操作的总超时的计算公式为:读总超时=ReadTotalTimeoutMultiplier×10+ReadTotalTimeoutConstant

可以看出,间隔超时和总超时的设置是不相关的,这可以方便通信程序灵活地设置各种超时。

如果所有写超时参数均为0,那么就不使用写超时。如果ReadIntervalTimeout为0,那么就不使用读间隔超时,如果ReadTotalTimeoutMultiplier和ReadTotalTimeoutConstant都为0, 则不使用读总超时。如果读间隔超时被设置成MAXDWORD并且两个读总超时为0,那么在读一次输入缓冲区中的内容后读操作就立即完成,而不管是否读入了要求的字符。

在用重叠方式读写串口时,虽然ReadFile和WriteFile在完成操作以前就可能返回,但超时仍然是起作用的。在这种情况下,超时规定的是操作的完成时间,而不是ReadFile和WriteFile的返回时间。

4 结语

以上给出了用Win32 API设计串行通信的基本思路,这个重叠(异步)I/O操作的串行通信程序,应用于大型任务,表现出良好的性能。在实际应用中,稍加改造,即可设计出满足需要的各种串行通信程序。

摘要:串行通信方便易行, 应用广泛。结合硬件详细介绍在Windows环境下使用Windows API实现异步串行通信的方法。

关键词:串行通信,RS232,重叠,I/O,Win API

参考文献

[1]李现勇.Visual C++串口通信技术与工程实践.人民邮电出版社, 2004.

计算机串行通信接口及其应用 第10篇

关键词:总线,串行通信,通信接口,电平转换

0 引 言

随着多微机系统的广泛应用和计算机网络技术的普及,计算机的通信功能显得愈来愈重要。在多微机系统及现代测控系统中,信息的交换多采用串行通信方式。对于串行通信、数据信息、控制信息要按位在一条线上依次传送,为了对数据和控制信息进行区分,收发双方要事先约定共同遵守的通信协议。通信协议约定的内容包括数据格式、同步方式、传输速率和校验方式等。依发送与接收设备的时钟控制方式,串行通信可分为同步通信和异步通信两类[1]。异步通信不要求收发双方时钟的严格一致,实现容易,设备开销较小。下面介绍RS 232接口,RS 422A/RS 485接口和20 mA电流环三类异步串行通信中的串行接口。

1 RS 232C接口

RS 232C是使用最早、应用最多的一种异步串行通信总线标准。RS 232是美国电子工业协会(EIA)于1962年制定的标准。RS表示EIA的“推荐标准”,232为该标准的标识号。1969年修订为RS 232C,1987年修订为EIA-232D,1991年修订为EIA-232E,1997年又修订为EIA-232F。由于修改的不多,所以人们习惯于早期的名字“RS 232C”[2]。

RS 232C主要用来定义计算机系统的一些数据终端设备(DTE)和数据电路终接设备(DCE)之间的物理接口标准。例如CRT、打印机与CPU的通信大都采用RS 232C接口,80C51单片机与PC机的通信也是采用该种类型的接口。由于80C51系列单片机本身具有一个全双工的串行接口,因此该系列单片机采用RS 232C串行接口总线非常方便。

RS 232C串行接口总线适用于设备之间的通信距离不大于15 m,传输速率最大为20 Kb/s。

1.1 RS 232C信息格式

RS 232C采用串行格式,如图1所示。该标准规定,信息的开始为起始位,信息的结束为停止位;信息本身可以是5~8位再加1位奇偶校验位。如果两个信息之间无信息,则写“1”,表示空。

1.2 RS 232C电平转换电路

RS 232C规定了自己的电气标准,由于它是在TTL电路之前研制的,所以它的电平不是+5 V和地,而是采用负逻辑。规定DC(+3~+15 V)为逻辑0,DC(-3~-15 V)为逻辑1。-3~+3 V过渡区,不作定义。因此,RS 232C不能和TTL电平直接相连,使用时必须进行电平转换,否则将使TTL电路烧坏,实际应用时必须注意[3]。常用的电平转换器有MC1488,MC1489和MAX232等芯片。

MC1488内部有3个与非门和1个反相器,供电电压为±12 V,输入为TTL电平,输出为RS 232C电平;MC1489内有4个反相器,供电电压为+5 V,输入为RS 232C电平,输出为TTL电平。MC1488和MC1489与RS 232C电平转换电路如图2所示。

近年来,人们愈来愈多地采用自升压电平转换电路。各厂商生产的此类芯片虽然不同,但原理类似,并可代换。它的主要功能是在单+5 V电源下,有TTL电平输入到RS 232C电平输出的功能,也有RS 232C电平输入到TTL电平输出的功能。如图3为RS 232C双工发送器/接收器接口电路MAX232引脚图,该芯片与TTL/CMOS电平兼容,片内有2个发送器和2个接收器,内置电子泵电压转换器将+5 V转换成±10 V,使用时,此芯片只需要单一的+5 V电源就可以了,它能满足RS 232C的电气规范要求[4]。引脚T1IN或T2IN可直接接TTL/CMOS电平的单片机串行发送端TXD;R1OUT或R2OUT可直接接TTL/CMOS电平的单片机串行接收端RXD;T1OUT或T2OUT可直接接PC机的RS 232串行接口的接收端RXD;R1IN或R2IN可直接接PC机的RS 232串行接口的接收端TXD。

1.3 RS 232C总线规定

RS 232C标准总线为25根,采用标准的D型25芯连接器,连接器的尺寸及每个插针的排列位置都有明确的定义。在一般的应用中并不一定使用RS 232C标准的全部信号线,所以在实际应用中常使用9芯连接器替代25芯连接器。连接器引脚排列如图4所示,图中所示为阳头定义,通常用于计算机侧,对应的阴头用于连接线侧。

RS 232C接口的主要信号线的功能定义如表1所示。

注:引脚序号栏中( )内为9芯非标准连接器的引脚号。

在最简单的全双工系统中,仅用发送数据、接收数据和信号地3根线即可。对于80C51单片机,利用其RXD(串行数据接收端)线、TXD(串行数据发送端)线和1根地线,就可以构成符合RS 232C接口标准的全双工通信口。

2 RS 422A/RS 485接口

RS 232C是广泛应用的串口通信标准,但因其推出较早,在现代网络通信中已暴露出数据传输速度慢、传输距离短、接口处各信号间容易产生干扰等明显的缺点。鉴于RS 232C的这些缺点,EIA于1977年制定了新标准RS 499,RS 422A是RS-499的子集,RS 485则是RS 422A的变型。

2.1 RS 422A接口

RS 422A文本给出了RS 449中对通信电缆、驱动器和接收器的要求,规定双端电气接口型式,其标准是双端线传送信号。它是通过传输线驱动器将逻辑电平变换成电位差,实现发送端的信息传递;通过传输线接收器把电位差变换成逻辑电平,完成接收端的信息接收。

RS 422A比RS 232C传输距离长、速度快,传输速率最大可达10 Mb/s。在此速率下,电缆的允许长度为12 m,如果采用低速率传输,最大距离可达1 200 m[5]。

RS 422A和TTL进行电平转换最常用的芯片是传输线驱动器SN75174和传输线接收器SN75175,这两种芯片的设计都符合EIA的RS 422A标准。RS 422A的接口电路如图5所示,发送器SN75174将TTL电平转换为标准的RS 422A电平;接收器SN75175将RS 422A接口信号转换为TTL电平。

2.2 RS 485接口

RS 485是RS 422A的变型:RS 422A用于全双工,而RS 485则用于半双工[6]。RS 485是一种多发送器的电路标准,它扩展了RS 422A的性能,在通信线路上最多可以使用32对差分驱动器/接收器。RS 485接口电平转换电路如图6所示。

RS 485接口是一种基于平衡发送和差分接收的串行总线,具有很强的抗共模干扰能力,又因为它的阻抗低,无接地问题,在适当的波特率下传输距离远;同时易于进行网络扩展,被广泛的应用在很多工业现场。

RS 485是一点对多点的通信接口,一般采用双绞线的结构。普通的PC机一般不带RS 485接口,因此要使用RS 232/RS 485转换器。对于PC机与单片机组成的通信系统可以通过芯片MAX485来完成TTL/RS 485的电平转换。

3 20 mA电流环路串行接口

20 mA电流环是目前串行通信中广泛使用的一种接口电路,但未形成正式标准。电流环串行通信接口的最大优点是低阻传输线对电气噪声不敏感,而且易实现光电隔离,因此在长距离通信时要比RS 232C优越得多。图7是一个实用的20 mA电流环接口电路,它是一个加上光电隔离的电流环传送和接收电路[7]。在发送端,将TTL电平转换为环路电流信号,在接收端又转换成TTL电平。

4 基于MAX232的PC机与单片机串行通信接口

PC机与单片机之间可以由RS 232C,RS 422A或RS 485等接口相连。单片机和PC机之间的通信与单片机和单片机之间的通信从软件上讲完全一样,其差别主要在硬件方面[8] 。计算机的串行口使用的是RS 232电平,而单片机串行口的电平为TTL电平,两者的电气规范不同,所以,当需要单片机和PC机之间进行通信时,需要在两者之间加上电平转换电路。采用MAX232芯片的PC机和单片机串行通信接口电路如图8所示[9]。

5 结 语

计算机与单片机的串行通信在实际的工业过程中的应用十分广泛,且在工业现场易于调试,具有很大实用价值[10]。在选择通信接口标准时必须注意:通信速度与通信距离的关系以及系统的抗干扰能力。

标准串行接口通常都有满足可靠传输时的最大通信速度和传送距离指标,但这两个指标具有相关性,适当降低传输速度,可以提高通信距离,反之亦然。如采用RS 232C标准进行单向数据传输时,最大的传输速度为20 Kb/s,最大的传输距离为15 m。而采用RS 422A标准时,最大的传输速度可达10 Mb/s,最大的传输距离为300 m,适当降低传输速度,传输距离可达1 200 m。通常,选择的标准接口,在保证不超过其使用范围时都有一定的抗干扰能力,以保证可靠的信号传输。但在一些工业测控系统中,通信环境十分恶劣,因此在通信介质选择、接口标准选择时,要充分考虑抗干扰能力,并采取必要的抗干扰措施。例如在长距离传输时,使用RS 422A和RS 485标准,采用差动方式传输能有效地抑制共模信号干扰;使用20 mA电流环技术,能大大降低对噪声的敏感程度。在高噪声污染的环境中,通过使用光纤介质可减少噪声的干扰,通过光电隔离可以提高通信系统的安全性。

VC++中串行通信程序设计 第11篇

在很多情况下,远程监控和自动化领域系统常见的通信编程多为串口通信编程。计算机串口编程在通信软件中有着十分广泛的应用。在Visual C++、Delphi、Visual Basis、TC、BC等开发工具之间,Visual C++由于功能强大和应用灵活,同时也得到Miscrosoft系统的最好支持,因此涉及硬件操作的通信编程,一般采用Visual C++。

在VC++中有两种方法可以进行串口通讯。一种是直接用VC++访问串口。另一种是利用Microsoft公司提供的ActiveX控件Microsoft Communications Control。本文将主要介绍第二种方法。

1 利用ActiveX控件 Microsoft Communications Control访问串口

ActiveX是Windows下进行应用程序开发的崭新技术,它的核心内容是组件对象模型COM(Component Object Model)。ActiveX控件包括一系列的属性、方法和事件,使用ActiveX控件的应用程序和ActiveX控件之间的工作方式是客户/服务器方式,即应用程序通过ActiveX控件提供的接口来访问ActiveX控件的功能。

Microsoft Communications Control(以下简称MSComm)是Microsoft公司提供的简化Windows下串行通信编程的ActiveX控件,它为应用程序提供了通过串行接口收发数据的简便方法。具体的来说,它提供了两种处理通信问题的方法:一是事件驱动(Event-driven)方法,一是查询方法。

a) 事件驱动法

事件驱动通信是处理串行端口交互作用的一种非常有效的方法。在使用事件驱动法设计程序时,每当有新字符到达,或端口状态改变,或发生错误时,MSComm控件的OnComm事件捕获并处理这些通信事件。而应用程序在捕获该事件后,通过检查MSComm控件的CommEvent属性可以获知所发生的事件或错误,从而采取相应的操作。

b) 查询法

这种方法适合于较小的应用程序。在这种情况下,每当应用程序执行完某一串行口操作后,将不断检查MSComm控件的CommEvent属性以检查执行结果或者检查某一事件是否发生。如果应用程序较小,并且是自成一体,这种方法可能是更可取的。

MSComm控件有许多重要的属性,其中首要的几个如表1所示。

2 编程实现

打开Visual C++6.0集成开发环境,创建一个基于对话框的MFC应用程序项目,命名为MyCOM,记住在设置项目选项时必须选上ActiveX Controls,其他的按照缺省设置。完成这一步后,选择菜单项Project/Add to Project/Components and Controls……,将弹出一个对话框以选择系统中已有的组件(Components)和控件(Controls)。选择Registered ActiveX Controls文件夹下的Microsoft Communications Control项并按下Insert按钮,将MSComm控件支持加入到本项目中。这时将生成一个名为CMSComm的C++类,并且在对话框编辑器里的工具栏将出现MSComm控件图标。CMSComm类是由MSComm控件导出的一系列接口函数构成的,利用它将可以访问MSComm控件的属性(Property)和方法(Method)。

我们假设先利用计算机COM1口上,那么打开资源编辑器,在程序主对话框(资源ID为IDD-MYCOM-DIALOG)上面放置一个MSComm控件,并用Class Wizard为该对话框类添加对应该控件的成员变量m-wnd COM1。我们假设外接口与计算机进行串行通信时采用7个数据位、1个停止位、偶校验方式,并且波特率为2400/4800/9600可选,这里采用9600波特率,在对话框编辑器中设置MSComm控件的属性如表2所示:

其他选项按照缺省设置或者根据具体设备的要求进行设置。如果需要通过多个串行口与多台设备通信,那么每一个串行口对应于一个单独的MSComm控件。串行口的设置参数既可以在对话框编辑器里设定,也可以在程序代码中通过调用CMSComm类的成员函数设定。例如,我们可以在MyCOMDlg类的OnInitDialog成员函数中初始化MSComm控件的参数,代码如下:

BOOL CMyCOMDlg::OnInitDialog()

{

CDialog:OnInitDialog();

//……

//TODO:Add extra initialization here

m-wndCOM1.SetCommPort(1);

m-wndCOM1.SetSettings(“9600,e,7,1”);

m-wndCOM1.SetRThreshold(1);

m-wndCOM1.SetSThreshold(0);

m-wndCOM1.SetInputLen(1);

m-wndCOM1.SetPortOpen(TRUE);//打开通信口

return TRUE;

//return TRUE unless you set the focus to a control

}

接下来为程序主对话框建立响应MSComm事件的处理函数,每当MSComm控件触发事件时该函数将被调用。在对话框编辑器中用鼠标左键双击MSComm控件图标,在弹出的对话框中输入函数名OnCommCOM1,该事件处理函数的原型定义和消息映射入口将自动被添加到CMyCOMDlg类中,我们所要做的只是在OnCommCOM1函数中给出具体的数据处理程序段,代码示例如下:

void CMyCOMDlg::OnCommCom1()

{

//TODO:Add your control notification handler code here

CString sInput;

switch(m-wndCOM1.GetCommEvent())

{

case 1: //comEvSend事件

/*如有数据要发送,可采用以下代码:

VARIANT varOut;

VariantInit(&varOut);

varOut.vt=VT-BSTR;

USES-CONVERSION;

varOut.bstrVal=SysAllocString(T2OLE)(“My data”));

if(varOut.bstrVal)

{

m-wndCOM1.SetOutput(varOut);

SysFreeString(varOut.bstrVal);

}

*/

break;

case 2://comEvReceiv事件,有数据到达

sInput=m-wndCOM1.GetInput().bstrVal;

//对接收到的数据做必要处理

break;

case 1009://comEventRxParity事件,奇偶校验错误

//错误处理代码

break;

default:

break;

}

在这里必须注意的一点是在发送字符数据时,必须向MSComm控件提供Unicode格式的字符串,在以上代码中用到了USES_CONVERSION和T2OLE宏进行ANSI字符串到Unicode字符串的转换,具体内容可参考Visual C++6.0所带的MSDN文档,在此不加赘述。

3 小结

本文对Windows下在Visual C++6.0程序中的串行通信,着重讨论了使用MSComm串行通信ActiveX控件编程的方法做了探讨,显示了ActiveX技术的强大功能、充分的灵活性和易用性,具有一定的实践意义。

参考文献

[1]李现勇.Visual C++串口通信技术与工程实践[M].北京:人民邮电出版社,2002.

[2]张曜,郭立山,吴天.C函数实用手册[M].北京:冶金工业出版社,2003.

[3](美)Kate Gregory.Visual C++5开发使用手册[M].康博创作室,译.北京:机械工业出版社,1998.

上一篇:标准化自愿性论文下一篇:经济发展格局