手机  
密码      忘记密码?
  注册
 
标题摘要内容
串口基本信息:纽荷尔拍照显微镜
来源: | 作者:纽荷尔显微镜 | 发布时间 :2024-04-16 | 128 次浏览: | 🔊 点击朗读正文 ❚❚ | 分享到:

用一台电脑实验串口自发自收,实验前要将串口(以9针为例)的发送引脚(2脚)和接受引脚(3脚)短接。


三线连接:适用于计算机之间尤其是PC机和单片机之间的数据通信。其连接信号对为(TxD,RxD)、(RxD,TxD)、(SG,SG)。即发送数据TxD端和接受数据RxD端交叉连接,信号地SG对应连接。纽荷尔拍照显微镜给观测研究提供成像解决方案。


七线交叉连接:适用于同型号的计算机之间的连接,如PC机间的数据通信。其连接信号对为:(TxD,RxD)、(RxD,TxD)、(SG,SG)、(RTS,CTS)、(CTS,RTS)、(DSR.DTR)、(DTR,DSR)。其中,TxD、RxD、SG与前面信号的含义相同,RTS为请求发送,CTS为准许发送,DSR为数据装置准备好,DTR为数据终端准备好。在本地连接的微机系统中,RTS、CTS、DTR、DSR用作硬件联络控制信号。


目前使用的串口连接线有DB9和DB25两种连接器,用户可以国家使用的具体机器选择相应的连接器。



PC机的RS-232接口的电平标准是-12V标示“1”,和+12V表示“0”,有些单片机的信号电平时TTL型,即大于2.4v表示“1”,小于0.5v表示“0”,因此采用RS-232总线进行异步通信是,发送端和接受端要有一个电平转换接口。


串口通讯方法的三种实现


串口是计算机上一种非常通用的设备通信协议。大多数计算机包含两个基于RS232的串口。串口同时也是仪器仪表设备通用的通信协议;很多GPIB兼容的设备也带有RS一232口。同时,串口通信协议也可以用于获取远程采集设备的数据。


串口通信(Serial Communication),是指外设和计算机间,通过数据信号线、地线、控制线等,按位进行传输数据的一种通讯方式。串口通信方便易行,应用广泛。在Windows应用程序的开发中,我们常常需要面临与外围数据源设备通信的问题。计算机和单片机(如MSC—51)都具有串行通信口,可以设计相应的串El通信程序,完成二者之间的数据通信任务。


1串口通讯原理


串口通信的原理非常简单,串口按位(bit)发送和接收字节。纽荷尔拍照显微镜给观测研究提供成像解决方案。尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。它很简单并且能够实现远距离通信。比如IEEE488定义并行通行状态时,规定设备线总常不得超过20米,并且任意两个设备间的长度不得超过2米;而对于串口而言,长度可达1200米。


典型地,串口用于ASCII码字符的传输。通信使用3根线完成:(1)地线,(2)发送,(3)接收。由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。其它线用于握手,但是不是必须的。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。对于两个进行通信的端口,这些参数必须匹配。


2串口通讯实现


在.net平台下使用C#语言实现串口通信的方法主要有三种:第一种方法是采用VB6.0中提供的MSComm控件,这种方法编程简单.但MSComm控件在使用前需要在系统中注册;第二种方法是采用微软在.net2.0及其以后版本提供的内置的串口操作类--System.IO.SerialPort,使用简单,但欠灵活;第三种方法是Windows的API函数,虽然编程难度高,但这种方法可以清楚地掌握串口通信的机制,并且高效、自由、灵活。


无论那种采用方式实现串口通讯,都需要通过以下四个步骤来完成:


1)打开串口


MSComm控件是通过设置PortOpen属性值来打开和关闭串口.具体语法为:MSComm. PortOpen=True/False.


SerialPort类则是调用类的Open()和Close()方法来实现串口的打开和关闭。


API函数是通过CreateFile来打开串口.因为在Win32系统中,串口被看作一个文件,使用与文件相同的操作方式进行操作。


2)配置串口


在打开通讯设备句柄后,需要对串口进行一些初始化配置工作。串口通讯最常用的参数就是通讯端口号及通讯格式(波特率、数据位、停止位和校验位)。


在MSComm中,通过属性Comport和Settings来进行端口号和通讯格式设置,例如:MSComm1.Comport=1,设定通讯端口为Com1,MSComm1.Settings=”9600,n,8,1”,设置波特率9600,无校验,8位数据位,1位停止位。


SerialPort类是通过PortName属性获取或设置通信端口,并分别通过BaudRate、Parity、DataBits、StopBits属性来对通讯格式中的波特率、数据位、停止位和校验位进行设置,其中的Parity和StopBits属性都是枚举类型,Parity类型中枚举了Odd(奇)、Even(偶)、Mark、None、Space共5个枚举成员.StopBits类型中枚举了None、One、OnePointFive、Two共4个枚举成员。


使用API,则需要通过一个DCB结构(包含了诸如波特率、数据位数、奇偶校验和停止位数等信息)来进行,将串口的几个重要参数如波特率、数据位、停止位、校验位改成符合实际设计要求的值。


3)读写串口


设置工作完成后,对串口进行读写操作。


MSComm控件通过Input属性返回和删除接收缓冲区中的字符,通过Output属性将字符串写入发送缓冲区。


SerialPort类则是通过调用重载的Write和WriteLine方法发送数据,其中WriteLine可发送字符串并在字符串末尾加入换行符。


SerialPort类对于串口缓冲区的读取方法有许多,其中除了ReadExisting和Readto.之外,其余的方法都是同步调用,即,方法调用时,线程将被阻塞,直到缓冲区有相应的数据或读超时(大于ReadTimeOut属性设定的时间值后,引发ReadExisting异常)。


API函数是分别通过ReadFile和Writefile对串口进行读/写操作。


4)关闭串口


串口是非共享资源,某应用程序打开串行口后,即独占该资源,使其它应用程序无法再访问,直到该应用程序释放串口。所以对串口操作完成后,一定要关闭串口。


MSComm控件通过将PortOpen属性值设置为False来关闭串口。


SerialPort类则是调用Close()方法来关闭串口。


API函数是通过使用CloseHandle()来关闭串口,该函数唯一参数即为用CreateFile打开串口时所创建的句柄。


3结束语


在.NET平台下,通过SerialPort类可以实现与MSComm控件相同的串口通讯程序,比起复杂的API,SerialPort类使用方便,开发快速.在今后工业控制中.SerialPort类必将广泛地应用于串口通讯程序的设计中。


MSComm控件


串行端口的本质功能是作为CPU和串行设备间的编码转换器。在发送数据时,字节数据转换为串行的位。在接收数据时,串行的位被转换为字节数据。利用微机RS-232口进行串行通信的一般步骤如下:


(1)打开串口在32位Windows中,串口和其他通信设备都被作为文件进行处理,在使用前必须先将其打开。


(2)配置串口串口配置主要包括波特率、数据位数、停止位数、奇偶校验、发送缓冲区大小、接收缓冲区大小等。


(3)超时设置在串口通信时如果数据传输突然中断,对串口的读写操作可能会进入无限期的等待状态,为避免这种情况发生,必须设置串口读写操作的等待时间。若等待时间超过后,串口的读写操作将被主动放弃。


(4)数据读写对串口的读写操作可采用查询、同步、异步和事件驱动等方式。


(5)关闭串口在串口使用完后应将其关闭,否则其他应用程序就无法打开或使用它。


VS2003下要先注册mscomm32.ocx组件才能使用。在.net 2003光盘下面有目录ExtrasWB6 Controls,此目录中有一个包含所有VB 6.0控件授权信息的注册表文件:VB6Controls.reg。我们通过RegEdit.exe将VB6Controls.reg中的控件注册信息添加到注册表中,从而注册这些控件。如果机器上已经安装过Visual c++6.0就不用上述步骤了


1常用控件属性


Vc++.net中控件Mscomm32的主要属性有:

CommPort属性,设置/返回通信端口号;

Settings属性,设置/返回波特率、奇偶校验、数据位和停止位参数;

PortOpen属性,设置/返回通信端口的状态(开或关)。

InBuffercount属性,返回接受缓冲区中等待的字符数,也可以用他来清除输入缓冲区。

InBufferSize属性,设置并返回接受缓冲区的字节数。

Input属性,返回并删除接收缓冲区中的数据流。

OutBufferCount属性,返回在传输缓冲区中等待的字符数。也可以用它来清除输出缓冲区。

OutBufferSize属性,以字节的形式设置并返回传输缓冲区的大小。

Output属性,将数据写入发送缓冲区

Rthrehold属性,设置并返回Rthrehold数值;

InputMode属性,设置/返回Input属性所检取数据的类型;

CommEvent属性,返回最近的通信事件或错误

2通信方式的选择

Mscomm32控件提供了两种处理通信问题的方法:事件驱动法和查询法。

事件驱动法利用OnComm事件捕获并处理通信中发生的事件,实时性强,可靠性高。每当有新字符到达,或端口状态改变,或发生错误时,Mscomm控件将触发OnComm事件,应用程序在捕获该事件后,通过检查Mscomm控件的CommEvent属性可获知所发生的事件(包括错误)并采取相应的操作。

查询法适合于应用程序较小、实时性要求不是很高的系统。在这种情况下,每当应用程序执行完某一串口操作后,将不断检查Mscomm控件的CommEvent属性以检查执行结果或者检查某一事件是否发生

基于 API 的串行口通信软件设计

串行口的硬件使用 3 线结构,即: RXD,TXD 和 GND, 在开发 PC 上位机的通信程序中


常用的编程语言可分为3类: 1) 直接面向底层硬件系统的汇编语言; 2) DOS 环境下的高级编程语言如 C 语言; 3) Windows 环境下的高级编程语言,如 Visual C+ + 6. 0, 而这 3种方式中Windows 环境下的串口编程以其设备无关性、可移植性以及界面友好而得到广泛应用, 开发 Windows 环境下的通信程序,主要有以下两种方式:

1) 利用 Windows API ( Application Program Interface 用户程序接口) 函数

2) 利用 ActiveX 控件, MSComm 控件

对于简单的串行口操作 MSComm 控件使用方便、控制简单,但是对于较为复杂的串行口操作,它不够灵活,它常用在对话框中,这也限制了它的使用。基于 API 的串口编程,其功能强大,控制手段更为灵活 配合 Win32的重叠 I/O 操作和多线程设计 就可以编写出高效、灵活的通信程序,

串口的打开与初始化

串口的打开是通过 Win32的文件操作函数 CreateFile 完成的, 该函数的原型如下,

Handle CreateFile (

LPCTSTR lpFileName                          //指向文件名称

DWORD dwDeSiredAcceSS           //存取模式 ( 读或写)

DWORD dwShareMode             //共享模式

LPSECURITY_ATTRIBUTES lpSecurityAttributeS    //指向安全属性结构

DWORD dwCreationDiSpoSition     //创建方式

DWORD dwFlagSAndAttributeS          //文件属性和标志

Handle  hTemplateFile     //临时文件句柄通常为 NULL)

如果调用成功, 则该函数返回文件的句柄, 否则, 返回 INVALID_HANDLE_VALUE, 注意在打开一个通信端口的时候, 应该以独占方式打开, 即 dwShareMode 应该为 O, 另外, 应该指定存取模式为 GENERIC_READ|GENERIC_WRITE, 允 许 对 端 口 读 和 写, 因 为 串 口 是 存 在 的, 所 以,dwCreationDisposition 应该为 OPEN_EXISTING, 此外, 应该指定FILE_ATTRIBUTE_NORMAL属性, 如果要打开重叠I/O, 则应该指定 FILE_FLAG_OVERLAPPED 属性, 这里, 重叠 I/O 的概念很重要。

在使用 ReadFile 和 WriteFile 读写串口的时候, 既可以使用同步方式, 也可以使用异步 ( 重叠) 方式, 使用同步方式的时候, 函数直到操作完成后才返回, 这就意味着在执行同步方式时, 线程将被阻塞, 导致效率下降, 如果通信出现错误, 将导致系统挂起的危险出现, 而使用重叠方式的时候, 费时的 I/O 操作在后台进行, 主线程则完成别的事情而不用担心效率会降低, 而 ReadFile 和 WriteFile 是否执 行 重 叠 I/O 操 作 则 是 由 CreateFile 决 定 的, CreateFile 中 如 果 指 定 了 FILE_FLAG_OVERLAPPEDA 标志, 那么执行重叠操作, 否则执行同步操作, 比如, 要用重叠方式打开 COM1, 则应该这样使用 CreateFile 函数。

HANDLE M_hCOm = CreateFile (OPEN_EXISTING,”COM1”,FILE_ATTRIBUTE_NORMAL |FILE_GENERIC_READ|generic_write,flag_overlapped,0,null,null,);

当 通 信 设 备 的 句 柄 创 建 成 功 后, 接 下 来 就 要 完 成 串 行 口 的 初 始 化 操 作 了, 初 始 化 是 通 过 DCB( Device Control Block) 结构和 COMMTIMEOUTS 结构来实现的, 此外还利用 SetupComm 函数设置输入与接收缓冲区大小等。


DCB 结构包含了波特率、数据位、奇偶校验位、停止位、文本方式或二进制方式等信息。 串口打开后, 调用 GetCommState 函数可以获取串口当前的配置, 修改完 DCB 结构后, 调用 SetCommState 函数, 用新的 DCB 设置重新配置串口, 比如, 设置波特率位 56 OOO, 8 位数据位, 无校验, 1 位停止位,二进制方式。

if ( m_hCOmm = = NULL ) return;

DCB dcb;

GetCOmmState (m_hComm, &dcb) ;

dcb. BaudRate= 56OOO;

dcb. ByteSize= DATABITS_8;

dcb. Parity= FALSE;

dcb. StopBits= ONESTOPBIT;

dcb. fBinary= TRUE;

SetCommState ( m_hComm, &dcb) ;

在用 ReadFile 和 WriteFile 读写串口时, 还需要考虑超时问题, 如果在指定的时间内没有读出或写入指定数量的字符, 那么 ReadFile 和 WriteFile 将立即返回。调用 GetCOmmTimeOuts 可以获取当前的超 时 设 置, 该 函 数 将 填 充 一 个 COMMTIMEOUTS 结 构, 调 用 SetCommTimeouts 可 以 用 某 个COMMTIMEOUTS 结构来设置超时, 该结构定义如下,

typedef struct COMMTIMEOUTS {

DWORD ReadIntervalTimeOut ;           //读间隔超时

DWORD ReadTOtalTimeOutMultiplier;     读时间系数

DWORD ReadTOtalTimeOutCOnstant;       读时间常量

DWORD WriteTOtalTimeOutMultiplier;    写时间系数

DWORD WriteTOtalTimeOutCOnstant     写时间常量

} COMMTIMEOUTS, e LPCOMMTIMEOUTS;

有两种超时, 间隔超时和总超时, 他们之间的设置是不相关的, 写操作只支持总超时, 读操作两种超时都支持, 间隔超时是指接收时两个字符之间的最大延迟时间, 总超时是指读/ 写操作总共花费的最大时间, COMMTIMEOUTS 结构的所有成员都是以毫秒为单位, 总超时的计算公式为

总超时= 读/ 写时间系数> 要求读/ 写的字符数+ 读/ 写时间常量

如果超时为 O, 那么就不用该超时, 比如读间隔超时为 O, 则不用读间隔超时, 如果所有写操作参数均为 O, 则不用写超时。

如果读间隔超时为 MAXDWORD, 且读总超时为 O, 那么在读一次缓冲区中的内容后读操作就立即完成, 而不管是否读入了要求的字符数。

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

自此, 串行口打开并且完成了初始化, 通信管道已建立起来, 可以对端口进行读写操作



串口的读写操作

串口的读写是通过 Readfile 和 Writefile 来实现的, 这两个函数的参数几乎是一样的, 这里只列出Readf ile 的原型。

BOOL Readfile (HANDLE hfile,  文件句柄

LPVOID lpBuffer,     数据缓冲区

DWORD nNumberOfByteSToRead,   要求读入的字节数

LPDWORD lpNumberofByteSRead,  实际读入的字节数

LPOVERLAPPED lpoverlapped   指向一个 OVERLAPPED 结构);

注 意 这 里 的 lpoverlapped 指 针, 在重叠操作 时 应 该 指 向 一个 OVERLAPPED 结 构, 如 果 为NULL, 那么函数将进行同步操作, 而不管句柄是否由FILE_FLAG_OVERLAPPED标志建立。

在使用重叠操作时, 需要建立一个 OVERLAPPED 结构, 而 OVERLAPPED 结构最重要的成员是hEvent, 它是一个事件对象句柄, 它将作为线程的同步对象使用。

这里提出了线程的概念。 在很多工业控制系统中, 常常通过扩展串口连接多个外设, 各外设发送数据的频率不同, 这就要求后台要实时无差错捕捉、采集、处理和记录各端口数据, 从而需要创建串口监视线程, 以实时监控串口事件的发生, 并且通知相应的窗口进行处理。

Win32 区分两种不同类型的线程, 一种是用户界面 ( UI, USer Interface) 线程, 它包含消息循环或消息泵, 用于处理接收到的消息; 另一种是工作者 ( Worker) 线程, 它没有消息循环, 用于执行后台任务。 串口监视线程就属于工作者线程。


工作者线程的创建可以通过 AfxBeginThread 实现, 其声明为:

CWinThreade * AfxBeginThread (    

AFX_THREADPROC pfnThreadProc,        / / 指向工作者线程的函数的指针

LPVOID pParam,                        / / 传递给线程函数的参数

int nPriority = THREAD_PRIORITY_NORMAL, / / 线程优先级

UINT nStackSize = 0,                   / / 线程堆栈尺寸

DWORD dwCreateflags =0      / / 线程初始状态, 为 0 则创建后立即执行, 为create_suspended则创建后被挂起, 知道调用 ResumeThread 才开始运行

LPSECURITY_ATTRIBUTES lpSecurityAttrS = NULL  //线程保密性);

线程函数的声明必须如下,

UINT MyControllingFunction ( LPVOID pParam );

其中 pParam 是创建线程时的第 2 个参数, 如下例, 传递的参数为指向 CECLView的this 指针;

void CECLView::CreateCommReceiveThread ()

{    CWinThread * m_pReadCommThread;

m_pReadCommThread=AfxBeginThread(ReadcommThreadProc,this,THREAD_PRIORITY_NOMAL,0,CREATE_SUSPENDED,NULL);

m_pReadCommThread->:ResumeThread();

}

UNIT ReadcommThreadProc(LPVOID pPrarm)

{  CECLView *pView=(CECLView *)pParam;

……

Return 0;}

多线程的使用会带来一些问题, 主要是如何保证线程之间的协调运行, 纽荷尔拍照显微镜给观测研究提供成像解决方案,从而提出了同步对象。 同步对象主要有事件、 mutex 和信号灯 3 种。 事件对象是最简单的同步对象, 它包括有信号和无信号两种状态。 事件对象是用 CreateEvent 创建的。该函数可以指定事件对象的类型和初始状态。如果是手工重置, 则它总是保持有信号状态, 直到用 ResetEvent 函数重置成无信号的事件; 如果是自动重置, 则它的状态在单个等待线程释放后会自动变为无信号的。 用 SetEvent 可以把事件对象设置成有信号状态。


串口监视线程需要等待主线程完成串口数据的读取后才能运行, 此时, 该线程需要暂时挂起, 以减少对 CPU 的占用时间, 提高程序的执行效率。 当主线程完成了串口数据的读取后, 将同步事件对象置为有信号, 从而激活串口监视线程监测串口事件的发生, 保证串口监视线程与主线程之间的同步, 避免错误的发生。

在读取串口数据的时候, 使用了 ReadFile, 该函数的返回值是 BOOL 值。 若该函数返回 TRUE, 则表示操作成功。 但是, 需要注意, 该函数因为超时也将返回 TRUE。 另外, 如果返回值为 FALSE, 也不表示操作就失败了, 应该调用 GetLastError 函数分析返回的结果。 如果 GetLastError 返回

 ERROR_IO_PENDING, 则说明重叠操作还未完成, 需要等待操作结束, 目前有两种等待方法。



Win32 API 提供了一组能使线程阻塞其自身执行的等待函数。这些函数只有在作为其参数的一个或多个同步对象产生信号时才返回。 在超过规定的等待时间后, 函数将立即返回, 而不管有无信号。 在等 待函数未返回时, 线程处于等待状态, 此时线程只消耗很少的 CPU 时间。 最常 用 的 等 待 函 数 是WaitForSingleObject,其声明为:

DWORD WaitForSingleObject(

  HANDLE hHandle, //同步对象句柄

  DWORD dwMilliseconds   //超时间隔,单位为微妙。

)。


如果超时间隔为 0, 则该函数立即返回, 如果为 INFINITE, 则超时间隔无限。该函数返回值如表1所示。用GetOverlappedResult函数等待。如果指定该函数的bWait参数为True,那么该函数将等待OVERLAPPED结构的hEvent事件。GetOverlappedResult可以返回一个OVERLAPPED结构来报告包括实际传输字节在内的重叠操作作结果。


在调用 ReadFile 和 WriteFile 之前, 线程应该调用 ClearCommError 函数清除错误标志。该函数负责报告指定的错误和设备的当前状态。调用 PurgeComm 函数可以终止正在进行的读写操作, 该函数还会清除输入或输出缓冲区中的内容。


API和MSComm32的应用比较


1性能


两者均可使用ASCIl码或二进制形式的数据。但是如果使用的是MSComm32控件,无论是在PC机读取上传数据时还是在PC机发送下行命令时,都只能使用vARIANT数据类型。所以不论是ASC|l码还是二进制,发送前都要转换一下。如果下位机是单片

机,则在单片机的程序中不需要做其他额外的转换。使用API函数则不需要做这种转换。


2扩展


在使用APl函数进行串口通讯时,常常用一个类为每一个申口添加一个控件。MSComm32控件的源码是不公开的,所有的修改必须在它的外面,以至于代码的重用性比较差。


3编程复杂性


从上面的这两个例子可以看出,用API函数编写通讯程序,涉及的函数比较多,一次代码编写比较复杂,而MSComm32控件则比较简单。而且MSComm32控件的文档说明详细,在vB中文版中,还可以找到中文的使用帮助。控件的可靠性很高,调试时完全可以不考虑这一部分的错误的可能,这又能节省一部分时间。所以在开发周期上,MSComm32控件远胜过API函数。至今为止,使用API函数编写通讯类的实际工作也做的比较多,已经出现了一些功能强大的共享类,这就使我们不需要重头做起,降低了首次编写时的难度。


移植性


API函数是各种windows编程工具所共同支持的,但是各种语言可能有不同的表示方法,所以,API串口通讯类只可用在其他windows的C++平台上,如C++ Builder。如果是在VC++中开发程序,并用到了某些MFC中已经包装过的类或数据,则不能直接在其他编程环境下运行。API函数编出来的类是源代码级的共享,而Active×控件是基于二进制代码级的共享,所以可以在VB,Dephi,C++ Builder中使用此控件,但是具体的实现代码则需要有所更改。需要注意的是,因为不能确保每一台计算机上都有MSComm32控件,所以在使用前要注意有个注册的过程。这个工作可以在应用程序中做,也可以在用于应用程序发布的安装程序中做。


两者均可以使用文本或二进制数据。MSComm32控件能满足比较基本的需要,而且上手比较快,调试起来也方便。使用APl函数缩写的类自己扩展的余地大,比较灵活,容易添加一些特定的功能。我们认为,如果注重的是开发周期,请选用控件来进行串行通讯,如果注重的是功能强大,或有特殊来封装所有功能。一般说来,这个类除了初始化串需要,请使用API函数。


CSerialPot串口类的使用


CSerialPort串口类可以很方便地实现上位机和仪表的串口通讯,串口类可从Remon Spekreijse免费得到。该类是基于多线程的,其接收数据工作流程如下:首先初始化串口,再开启串口监测工作线程,当串口监测工作线程监测到串口接收到的数据、流控制事件或其他串口事件后,就以消息方式通知主程序,激发消息处理函数进行数据处理。数据可直接向串口发送。


实现串口通信的过程中,要用到几个成员函数。InitPort():初始化串口,即设置串口的通信参数:串口号、波特率、校验方式、数据位、停止位等。StartMonitoring():启动串口检测线程。WriteToPort()函数:向串口发送字符。ClosePort():关闭串口。

CSerialPort串口类在数据采集过程中的使用方法如下:


(1)串口类的引用

先将串口类的头文件SerialPort.h和源文件SerialPort.cpp复制到所建工程的文件夹中,在VC.NET环境下,通过菜单Project/Add To Project/files选中两文件加入到工程中。CMainFrame.h中引入了SerialPort.h并定义了公共CSerialPort类对象m_serialport.



(2)串口的初始化

本系统对串口的初始设置为:端口为l,波特率为9600,数据位为8,无数据校验位;停止位为2,接受缓冲区为512字节。

If(m_serialport.InitPort(this,1,9600,N,8,2,EV_RXFLAG|EV_RXCHAR,512))//串口初始化

{//启动串口检测线程

M_serialport.StartMonitoring();

Settime(1,200,null); }

Else

Messagebox(“没有发现此串口或串口已被占用”,”注意”,);


(3)添加串口事件响应函数

在CSerialPort类中有多个串口事件可以响应,所有的消息均需要人工添加消息处理函数,在一般串口编程中,只需处理WM_COMM_RXCHA消息就可以了。此处将处理函数定义为OnComm()。

LONG CMainFrame::ONComm(WPARAM ch,LPARAM port)

{//将接受的字符赋给Public型m_recedate变量

m_recedata+=cn;

return 0; }


(4)向串口发迭字符

系统用定时器方法以200ms为周期向串口发送读数据的命令,实现对温度的实时采集:首先建立定时器SetTime(1,200,null),定时器用按周期触发的Ontime(UINT nIDEvent)函数。纽荷尔拍照显微镜给观测研究提供成像解决方案

中的m_serialport调用WriteToPort().

SerialPort类提供了同步I/O和事件驱动的I/O、对管脚和中断状态的访问以及对串行驱动程序属性的访问。SerialPort类的常用属性和常用方法如表l所示。利用表1中的属性和方法,实现智能化汽车衡系统中上位机与下位机的数据传输。

利用MicorSoft.NetFramework 2.0中的SerialPort类,实现汽车衡称重系统上位机与下位机串口通信接收功能的主要程序如下:

Private void SerialPort1_dataReceived(object sender,System.IO.Ports.serialdatareceivedEventArgs e)

{If(flag==false)//flag初始值为false,用于标示是否处理数据值

{if(this.serialport1.readbyte()==0x0a)//判断受到询问信号’0A’

{this.serialport1.wire(0x0B,0,1);flag=!flag})//回复确认信号’0b’

Else if(flag)

{system.threading.thread.sleep(100);//线程中断100毫秒

This.serialport1.read(rec_barray,0,4)//读取缓冲区数据

Rec_barray_data=crcdata(rec_barray,2)//对接受crc编码解码

Temp=convert.todouble(rec_barray_data[0]*256+rec_barray_data[1]);//按规约处理数据

Rec_dou=temp/100;//单位转换

Rec_strarray=convert.tostring(rec_dou);

Flag=!flag;

Settext(rec_strarray//显示数据。)}

每当上位机串口缓冲区收到新数据时,即触发此函数。


为了提高汽车衡称重系统串口通信的抗干扰能力和降低误码率,上位机与下位机通信采用了CRC编码技术,并设计了一种握手协议,即对于每32bit数据,由下位机向上位机发送数据传输询问信号‘0A’,上位机接收到‘0A’信号后,向下位机发送‘0B’确认信号。下位机接收到‘0B’后传输2bit数据信息,上位机将数据按约定规则处理后显示。若下位机没有受到‘0B’确认信号,下位机将持续向上位机发送询问信号,上位机数据信息保持不变,避免因干扰而产生数据大幅振荡。若此状态超过2s,系统将弹出串口通信异常警告对话框。