⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 subject_15211.htm

📁 一些关于vc的问答
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<p>
序号:15211 发表者:忧河 发表日期:2002-09-16 15:33:27
<br>主题:如何用VC在WINNT下实现对I/O端口的读写操作?
<br>内容:在95/98里,可以用_inp , _outp 操作,但是它在WINNT下不可以,请问各位高手,象这个问题该怎么写?
<br><a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p>
<hr size=1>
<blockquote><p>
回复者:不灵 回复日期:2002-09-16 18:15:26
<br>内容:在Win32(包括Windows95、Windows98、Windows NT、Windows2000)环境下,系统将串行口和其它通信设备如Modern、打印机、传真机等统一视作文件,对串行口的打开、关闭、读、写等操作提供了与操作普通文件相同的API函数。
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:r0 回复日期:2002-09-16 18:22:17
<br>内容:但是,这种 device io control 的方法有很大的限制<BR>一个方法是构造一个 IDT<BR>一个方法是写一个 device driver<BR>www.driverdevelop.com 会有的,那里的人对 MM 很关照的<BR>毕竟作 kernel mode 开发的 MM 太少了。<BR>good luck.
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:忧河 回复日期:2002-09-17 09:18:08
<br>内容:Z1947:我同事告诉我不是这么简单的读写就可以的!可惜他目前不在公司:(<BR><BR>r0:多谢,我会上去看看的!
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:不灵 回复日期:2002-09-17 09:34:17
<br>内容:看看这个,应该有用的<BR><BR><BR><BR>掌握串行通信API函数的用法是掌握串行通信编程技术的关键。在Win32中,系统将串行口与文件统一了起来,<BR>对它们的打开、读写、关闭等操作都使用相同的API函数,但是它们之间又有差别,这些差别主要体现在API函<BR>数中部分参数的设置上。有关通信的API主要包括打开串口、关闭串口、配置串口、设置缓冲区、设置超时、<BR>事件驱动、读串口、写串口等。下面结合GPS的具体情况对串口操作函数的使用方法进行详细的介绍和分析。<BR><BR>一:串口的打开和关闭<BR>&nbsp;&nbsp;&nbsp;&nbsp;1:串口的打开。由于在Windows环境中,串口作为一种文件来使用,打开串口用打开文件同样的API函数<BR>CreateFile()。<BR>函数原型为:<BR>HANDLE CreateFile( LPCTSTR lpFileName,<BR>&nbsp;&nbsp;&nbsp;&nbsp;DWORD dwDesiredAccess, <BR>&nbsp;&nbsp;&nbsp;&nbsp;DWORD dwShareMode,<BR>&nbsp;&nbsp;&nbsp;&nbsp;LPSECURITY_ATTRIBUTES lpSecurityAttributes,<BR>&nbsp;&nbsp;&nbsp;&nbsp;DWORD dwCreationDisposition,<BR>&nbsp;&nbsp;&nbsp;&nbsp;DWORD dwFlagsAndAttributes,<BR>&nbsp;&nbsp;&nbsp;&nbsp;HANDLE hTemplateFile);<BR>其中几个参数的含义分别为:<BR>lpFileName指定文件名或设备名,串口通讯时,它必须是“COMx”,其中的“x”为串口编号,如第一个串口<BR>则为“COM1”;dwDesiredAccess 为串口读写属性; dwShareMode指定该端口的共享属性,串行口不能作为共<BR>享设备,故参数值必须为0;lpSecurityAttributes为安全属性,对于串口应该为0 ;<BR>dwCreationDisposition指文件的创建模式,对于串口必须为OPEN—EXISTING;<BR>dwFlagsAndAttributes描述了创建文件的其它属性,对于串行口,有效的设置只能是FILE-FLAG-OVERLAPPED<BR>或者0,分别表示异步或同步读写;<BR>参数hTemplateFile必须为NULL。<BR>返回值:若成功,返回创建的句柄;否则返回INVALID—HANDLE—VALUE。<BR><BR>2:串口的关闭。关闭串口相对简单,通过关闭句柄BOOL CloseHandle(HANDLE hObject )函数进行,<BR>hObject为打开串口时所得到的句柄。句柄关闭后,串口资源即释放,其它程序可以使用。<BR><BR>二:配置串口<BR>串行口在打开后,将保持上一次使用的配置,要使之和外设进行通信,必须对串口进行配置,使之和外设保持<BR>相同的串口配置,这样才能有效地配置外设并接收数据。在WIN32中,串口的配置主要通过一个称之为<BR>COMMCONFIG的结构来实现,此结构包含了一个DCB结构,在DCB中,有波特率、数据位数、停止位、校验位等串<BR>行口通信参数,对串口的配置主要即是对这些参数的配置。对COMMCONFIG进行配置的WIN32 API 主要有一下几<BR>个:<BR>1:获取默认配置函数。其原型为:<BR>BOOL GetDefaultCommConfig( LPCSTR lpszName, LPCOMMCONFIG lpCC, LPDWORD lpdwSize)<BR>其参数如下:<BR>LpszName为设备名,如“COM1”;<BR>lpCC为COMMCONFIG结构体的指针。<BR>LpdwSize是lpCC的大小。<BR>通过使用此函数可以得到某串口的默认配置,此函数与机器硬件相关,在不同的机器上会有不同的结果,因而<BR>容易出错,所以建议用户自己重写此函数,分别对COMMCONFIG的成员进行赋值,这样才稳定可靠。<BR>2:得到串口的当前配置,原形如下:<BR>BOOL GetCommConfig( HANDLE hCommDev, LPCOMMCONFIG lpCC, LPDWORD lpdwSize )<BR>其参数同GetDefaultCommConfig();<BR>3:配置串口<BR>BOOL SetCommConfig( HANDLE hCommDev,LPCOMMCONFIG lpCC, DWORD dwSize);<BR>此函数将由hCommDev指定的串口按lpCC结构体中的内容进行配置。LPCOMMCONFIG结构体中的主要成员是设备控<BR>制块结构DCB,在DCB中指定了设备的波特率,奇偶校验位,流控,停止位等参数。<BR>4:配置串口的对话框<BR>BOOL CommConfigDialog(LPCSTR lpszName,HWND hWnd,LPCOMMCONFIG lpCC )<BR>此函数提供了一个用户熟悉的串口配置对话框,其句柄为hWnd。用户可在此对话框中进行对lpszName指示的串<BR>口配置,配置结果存放在lpCC所指向的COMMCONFIG结构体中。<BR>5:设置缓冲区<BR>WIN32环境下读写串口已经不是传统方式下针对串口的UART进行,而是提供一缓冲区,串口的读写都是针对于此<BR>缓冲区进行。确定缓冲区的大小比较重要,太大浪费资源,太小又会使有效数据丢失。用户必须在串口读写前<BR>计算出外设流量的大小,按照宁大勿小、有所冗余的原则确定合适大小的缓冲区,再使用SetupComm()函数对串<BR>口进行设置。其原型如下:<BR>BOOL SetupComm(HANDLE hFile,DWORD dwInQueue,DWORD dwOutQueue);<BR>hFile为打开串口时所得到的句柄;<BR>dwInQueue为输入缓冲区的大小,以字节为单位;<BR>dwOutQueue为输出缓冲区的大小。<BR>6:设置超时<BR>数据通信过程中可能会发生的不可预测的事件,如数据传输电缆损坏、外设意外失效中断,或者发送数据突然<BR>停止等等。通信应用程序的一个关键问题就是如何处理通信中的不可预测的事件,处理错误事件的能力是一个<BR>通信应用程序优劣的重要标志。这些问题处理的不好可能会引起I/O线程挂起或者线程被无限阻塞。Windows对<BR>于这类问题提供了安全措施,用户可以通过超时设置来决定通信是否异常并作相应处理。因此超时设置在串行<BR>通信中显得尤为重要。在Win32中提供了SetCommTimeouts()函数设置串口的超时值。<BR>BOOL SetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts);<BR>hFile为打开串口时所得到的句柄;<BR>lpCommTimeouts为指向超时结构体的指针。<BR>三:读写串口<BR>&nbsp;&nbsp;&nbsp;&nbsp;在打开串口并对其进行正确地和必要的配置后就可以用它进行通信即读写数据。读数据就是接收输入,些<BR>数据就是向外设发送数据。读写数据通过两个API函数完成。<BR>1:读数据函数<BR>BOOL ReadFile ( HANDLE hFile, <BR>LPVOID lpBuffer,<BR>DWORD nNumberOfBytesToRead,<BR>LPDWORD lpNumberOfBytesRead,<BR>LPOVERLAPPED lpOverlapped data);<BR>hFile是由CreateFile()返回的句柄;<BR>lpBuffer是读取的数据缓冲区指针;<BR>nNumberOfBytesToRead是要读取的字节数;<BR>lpNumberOfBytesRead是实际读取的字节数的首地址;<BR>lpOverlapped 是指向一个可重叠I/O(异步)的数据结构指针。如果lpOverlapped设置为NULL,则ReadFile()工<BR>作在同步方式;如果lpOverlapped指向一个重叠结构,则工作在异步方式。不管是同步还是异步,<BR>ReadFile()函数执行后将立刻返回。<BR>2:写串口函数<BR>BOOL WriteFile( HANDLE hFile, <BR>LPVOID lpBuffer,<BR>DWORD nNumberOfBytesToRead,<BR>LPDWORD lpNumberOfBytesRead,<BR>LPOVERLAPPED lpOverlapped data);<BR>其参数的意义与读串口相似。<BR><BR>四:工作模式<BR>&nbsp;&nbsp;&nbsp;&nbsp;在串口读写操作时,存在多种操作模式,从同步控制角度讲,有同步和异步方式,从编程角度讲,有查询<BR>方式和事件驱动方式。在同步读串口时,如果串口缓冲区中内容没有读完,系统将处于等待状态,直至读完才<BR>返回;如果是异步读,即使缓冲区中没有读完,系统也将下行,执行下一句代码。如果串口的交互频繁,则宜<BR>使用异步读写,但对于一般采集而言,主要是读数据,写命令不多,一次读取的数据量又不会太大,所以使用<BR>同步较好,更易于控制。查询方式是指在一个无穷循环中直接读写串口数据,对于从串口读取数据来说,查询<BR>是最为直接、最简单的方法,但是这种方法效率较低,要花费大量的CPU时间。事件驱动方式是指线程通过监<BR>视通信资源中的一组事件来进行读写操作,这种方式类似于DOS下的中断工作方式,效率高。监视事件的工作<BR>是通过SetCommMask()和WaitCommEvent()函数进行的。在读或写操作中可以通过SetCommMask()函数设置事件<BR>屏蔽来监视指定通信资源上的事件,指定一组事件后,线程可以使用WaitCommEvent()函数等待其中一个事件发<BR>生,在等待过程中线程将挂起,这样将花费极少的CPU时间,一旦有相应事件发生,WaitCommEvent()将返回,<BR>告诉系统发生的事件,用户可以根据事件的内容确定相应的处理方式。在等待事件时,WaitCommEvent()函数将<BR>独占串口,此时串口既不能读也不能写,读写工作必须等WaitCommEvent()函数返回后进行。<BR>&nbsp;&nbsp;&nbsp;&nbsp;设置同步控制模式在打开串口时进行,由其第三个参数指定。<BR>&nbsp;&nbsp;&nbsp;&nbsp;而在编程时采用事件驱动模式的函数有以下几个。<BR><BR>1:设置事件掩码<BR>BOOL SetCommMask(HANDLE hFile,DWORD dwEvtMask);<BR>其中hFile为打开串口的文件句柄。<BR>DwEvtMask是设置的掩码,其形式和意义如下表所示<BR>掩码&nbsp;&nbsp;&nbsp;&nbsp;事件<BR>EV_BREAK&nbsp;&nbsp;&nbsp;&nbsp;在输入中检测到断点<BR>EV_CTS&nbsp;&nbsp;&nbsp;&nbsp;CTS (clear-to-send) 信号改变状态<BR>EV_DSR&nbsp;&nbsp;&nbsp;&nbsp;DSR (data-set-ready) 信号改变状态<BR>EV_ERR&nbsp;&nbsp;&nbsp;&nbsp;出现线路状态错误。<BR>EV_RING&nbsp;&nbsp;&nbsp;&nbsp;检测到振铃指示<BR>EV_RLSD&nbsp;&nbsp;&nbsp;&nbsp;RLSD (receive-line-signal-detect) 信号改变状态<BR>EV_RXCHAR&nbsp;&nbsp;&nbsp;&nbsp;一个字符到达并存放于接收缓冲区<BR>EV_RXFLAG&nbsp;&nbsp;&nbsp;&nbsp;一个事件字符到达并存放于接收缓冲区,事件字符包含在设备的DCB中,由SetCommState 函数应用到串口<BR>EV_TXEMPTY&nbsp;&nbsp;&nbsp;&nbsp;发送缓冲区中的最后一个字符被送出<BR><BR>2:等待事件到来<BR>BOOL SetCommMask(HANDLE hFile,DWORD dwEvtMask,LPOVERLAPPED lpOverlapped);<BR>其参数意义与设置掩码相似。这个函数表示等待由SetCommMask()函数设置的事件的到来,在此函数工作时,串口处于阻<BR>塞模式独占串口。<BR>&nbsp;&nbsp;&nbsp;&nbsp;如果定义的事件到来,我们就可以采取相应的措施来处理。在数据采集时,通常设置的事件为:<BR>EV_RXCHAR,在此事件到来时就可以读出接收缓冲区中的数据并交给后台线程处理。<BR>&nbsp;&nbsp;&nbsp;&nbsp;如果使用的串口不止一个,则需要利用Win32的多任务特性。<BR>
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>
<blockquote><p>
回复者:不灵 回复日期:2002-09-17 09:37:51
<br>内容:我还没试过
<br>
<a href="javascript:history.go(-1)">返回上页</a><br><a href=http://www.copathway.com/cndevforum/>访问论坛</a></p></blockquote>
<hr size=1>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -