Chinaunix首页 | 论坛 | 博客
  • 博客访问: 14517820
  • 博文数量: 5645
  • 博客积分: 9880
  • 博客等级: 中将
  • 技术积分: 68081
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-28 13:35
文章分类

全部博文(5645)

文章存档

2008年(5645)

我的朋友

分类:

2008-04-28 21:00:42

下载本文示例代码
  1、API描述  在WIN32 API中,串口使用文件方式进行访问,其操作的API基本上与文件操作的API一致。  打开串口  Win32 中用于打开串口的API 函数为CreateFile,其原型为: HANDLE CreateFile ( LPCTSTR lpFileName, //将要打开的串口逻辑名,如COM1 或COM2 DWORD dwAccess, //指定串口访问的类型,可以是读取、写入或两者并列 DWORD dwShareMode, //指定共享属性,由于串口不能共享,该参数必须置为0 LPSECURITY_ATTRIBUTES lpsa, //引用安全性属性结构,缺省值为NULL DWORD dwCreate, //创建标志,对串口操作该参数必须置为OPEN EXISTING DWORD dwAttrsAndFlags, //属性描述,用于指定该串口是否可进行异步操作, //FILE_FLAG_OVERLAPPED:可使用异步的I/O HANDLE hTemplateFile //指向模板文件的句柄,对串口而言该参数必须置为NULL);  例如,以下程序用于以同步读写方式打开串口COM1: HANDLE hCom;DWORD dwError;hCon = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);if (hCom == (HANDLE)0xFFFFFFFF){ dwError = GetLastError(); MessageBox(dwError);}  对于dwAttrsAndFlags参数及FILE_FLAG_OVERLAPPED标志的由来,可解释如下:Windows文件操作分为同步I/O和重叠I/O(Overlapped I/ O)两种方式,在同步I/O方式中,API会阻塞直到操作完成以后才能返回(在多线程方式中,虽然不会阻塞主线程,但是仍然会阻塞监听线程);而在重叠I/O方式中,API会立即返回,操作在后台进行,避免线程的阻塞。重叠I/O非常灵活,它也可以实现阻塞(例如我们可以设置一定要读取到一个数据才能进行到下一步操作)。如果进行I/O操作的API 在没有完成操作的情况下返回,我们可以通过调用GetOverLappedResult()函数阻塞到I/O操作完成后返回。  配置串口  配置串口是通过改变设备控制块DCB(Device Control Block) 的成员变量值来实现的,接收缓冲区和发送缓冲区的大小可通过SetupComm函数来设置。  DCB结构体定义为: typedef struct _DCB { // dcb  DWORD DCBlength; // sizeof(DCB)  DWORD BaudRate; // current baud rate  DWORD fBinary: 1; // binary mode, no EOF check  DWORD fParity: 1; // enable parity checking  DWORD fOutxCtsFlow:1; // CTS output flow control  DWORD fOutxDsrFlow:1; // DSR output flow control  DWORD fDtrControl:2; // DTR flow control type  DWORD fDsrSensitivity:1; // DSR sensitivity  DWORD fTXContinueOnXoff:1; // XOFF continues Tx  DWORD fOutX: 1; // XON/XOFF out flow control  DWORD fInX: 1; // XON/XOFF in flow control  DWORD fErrorChar: 1; // enable error replacement  DWORD fNull: 1; // enable null stripping  DWORD fRtsControl:2; // RTS flow control  DWORD fAbortOnError:1; // abort reads/writes on error  DWORD fDummy2:17; // reserved  WORD wReserved; // not currently used  WORD XonLim; // transmit XON threshold  WORD XoffLim; // transmit XOFF threshold  BYTE ByteSize; // number of bits/byte, 4-8  BYTE Parity; // 0-4=no,odd,even,mark,space  BYTE StopBits; // 0,1,2 = 1, 1.5, 2  char XonChar; // Tx and Rx XON character  char XoffChar; // Tx and Rx XOFF character  char ErrorChar; // error replacement character  char EofChar; // end of input character  char EvtChar; // received event character  WORD wReserved1; // reserved; do not use } DCB; 而SetupComm函数的原型则为:BOOL SetupComm( HANDLE hFile, // handle to communications device DWORD dwInQueue, // size of input buffer DWORD dwOutQueue // size of output buffer);  以下程序将串口设置为:波特率为9600,数据位数为7位,停止位为2 位,偶校验,接收缓冲区和发送缓冲区大小均为1024个字节,最后用PurgeComm函数终止所有的后台读写操作并清空接收缓冲区和发送缓冲区: DCB dcb;dcb.BaudRate = 9600; //波特率为9600dcb.ByteSize = 7; //数据位数为7位dcb.Parity = EVENPARITY; //偶校验dcb.StopBits = 2; //两个停止位dcb.fBinary = TRUE;dcb.fParity = TRUE;if (!SetCommState(hCom, &dcb)){ MessageBox("串口设置出错!");} SetupComm(hCom, 1024, 1024);PurgeComm(hCom, PURCE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);  超时设置  超时设置是通过改变COMMTIMEOUTS结构体的成员变量值来实现的,COMMTIMEOUTS的原型为: typedef struct _COMMTIMEOUTS{ DWORD ReadIntervalTimeout; //定义两个字符到达的最大时间间隔,单位:毫秒 //当读取完一个字符后,超过了ReadIntervalTimeout,仍未读取到下一个字符,就会 //发生超时 DWORD ReadTotalTimeoutMultiplier;  DWORD ReadTotalTimeoutConstant; //其中各时间所满足的关系如下: //ReadTotalTimeout = ReadTotalTimeOutMultiplier* BytesToRead ReadTotalTimeoutConstant DWORD WriteTotalTimeoutMultiplier; DWORD WriteTotalTimeoutConstant;} COMMTIMEOUTS, *LPCOMMTIMEOUTS;  设置超时的函数为SetCommTimeouts,其原型中接收COMMTIMEOUTS的指针为参数: BOOL SetCommTimeouts( HANDLE hFile, // handle to communications device LPCOMMTIMEOUTS lpCommTimeouts // pointer to comm time-out structure);  以下程序将串口读操作的超时设定为10 毫秒: COMMTIMEOUTS to;memset(&to, 0, sizeof(to));to.ReadIntervalTimeout = 10;SetCommTimeouts(hCom, &to);  与SetCommTimeouts对应的GetCommTimeouts()函数的原型为: BOOL GetCommTimeouts( HANDLE hFile, // handle of communications device LPCOMMTIMEOUTS lpCommTimeouts // pointer to comm time-out structure);  事件设置  在读写串口之前,需要用SetCommMask ()函数设置事件掩模来监视指定通信端口上的事件,其原型为: BOOL SetCommMask( HANDLE hFile, //标识通信端口的句柄 DWORD dwEvtMask //能够使能的通信事件);  有了Set当然还会有Get,与SetCommMask对应的GetCommMask()函数的原型为: BOOL GetCommMask( HANDLE hFile, //标识通信端口的句柄 LPDWORD lpEvtMask // address of variable to get event mask);  串口上可以发生的事件可以是如下事件列表中的一个或任意组合:EV_BREAK、EV_CTS、EV_DSR、EV_ERR、EV_RING、EV_RLSD、EV_RXCHAR、EV_RXFLAG、EV_TXEMPTY。  我们可以用WaitCommEvent()函数来等待串口上我们利用SetCommMask ()函数设置的事件: BOOL WaitCommEvent( HANDLE hFile, //标识通信端口的句柄 LPDWORD lpEvtMask, // address of variable for event that occurred LPOVERLAPPED lpOverlapped, // address of overlapped structure);  WaitCommEvent()函数一直阻塞,直到串口上发生我们用所SetCommMask ()函数设置的通信事件为止。一般而言,当WaitCommEvent()返回时,程序员可以由分析*lpEvtMask而获得发生事件的类别,再进行相应的处理。  读串口  对串口进行读取所用的函数和对文件进行读取所用的函数相同,读函数原型如下: BOOL ReadFile( HANDLE hFile, // handle of file to read LPVOID lpBuffer, // pointer to buffer that receives data DWORD nNumberOfBytesToRead, // number of bytes to read LPDWORD lpNumberOfBytesRead, // pointer to number of bytes read LPOVERLAPPED lpOverlapped // pointer to structure for overlapped I/O);  写串口  对串口进行写入所用的函数和对文件进行写入所用的函数相同,写函数原型如下: BOOL WriteFile( HANDLE hFile, // handle to file to write to LPCVOID lpBuffer, // pointer to data to write to file DWORD nNumberOfBytesToWrite, // number of bytes to write LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written LPOVERLAPPED lpOverlapped // pointer to structure for overlapped I/O);  关闭串口  利用API 函数实现串口通信时关闭串口非常简单,只需使用CreateFile 函数返回的句柄作为参数调用CloseHandle 即可: BOOL CloseHandle( HANDLE hObject // handle to object to close);共2页。 1 2 :   1、API描述  在WIN32 API中,串口使用文件方式进行访问,其操作的API基本上与文件操作的API一致。  打开串口  Win32 中用于打开串口的API 函数为CreateFile,其原型为: HANDLE CreateFile ( LPCTSTR lpFileName, //将要打开的串口逻辑名,如COM1 或COM2 DWORD dwAccess, //指定串口访问的类型,可以是读取、写入或两者并列 DWORD dwShareMode, //指定共享属性,由于串口不能共享,该参数必须置为0 LPSECURITY_ATTRIBUTES lpsa, //引用安全性属性结构,缺省值为NULL DWORD dwCreate, //创建标志,对串口操作该参数必须置为OPEN EXISTING DWORD dwAttrsAndFlags, //属性描述,用于指定该串口是否可进行异步操作, //FILE_FLAG_OVERLAPPED:可使用异步的I/O HANDLE hTemplateFile //指向模板文件的句柄,对串口而言该参数必须置为NULL);  例如,以下程序用于以同步读写方式打开串口COM1: HANDLE hCom;DWORD dwError;hCon = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);if (hCom == (HANDLE)0xFFFFFFFF){ dwError = GetLastError(); MessageBox(dwError);}  对于dwAttrsAndFlags参数及FILE_FLAG_OVERLAPPED标志的由来,可解释如下:Windows文件操作分为同步I/O和重叠I/O(Overlapped I/ O)两种方式,在同步I/O方式中,API会阻塞直到操作完成以后才能返回(在多线程方式中,虽然不会阻塞主线程,但是仍然会阻塞监听线程);而在重叠I/O方式中,API会立即返回,操作在后台进行,避免线程的阻塞。重叠I/O非常灵活,它也可以实现阻塞(例如我们可以设置一定要读取到一个数据才能进行到下一步操作)。如果进行I/O操作的API 在没有完成操作的情况下返回,我们可以通过调用GetOverLappedResult()函数阻塞到I/O操作完成后返回。  配置串口  配置串口是通过改变设备控制块DCB(Device Control Block) 的成员变量值来实现的,接收缓冲区和发送缓冲区的大小可通过SetupComm函数来设置。  DCB结构体定义为: typedef struct _DCB { // dcb  DWORD DCBlength; // sizeof(DCB)  DWORD BaudRate; // current baud rate  DWORD fBinary: 1; // binary mode, no EOF check  DWORD fParity: 1; // enable parity checking  DWORD fOutxCtsFlow:1; // CTS output flow control  DWORD fOutxDsrFlow:1; // DSR output flow control  DWORD fDtrControl:2; // DTR flow control type  DWORD fDsrSensitivity:1; // DSR sensitivity  DWORD fTXContinueOnXoff:1; // XOFF continues Tx  DWORD fOutX: 1; // XON/XOFF out flow control  DWORD fInX: 1; // XON/XOFF in flow control  DWORD fErrorChar: 1; // enable error replacement  DWORD fNull: 1; // enable null stripping  DWORD fRtsControl:2; // RTS flow control  DWORD fAbortOnError:1; // abort reads/writes on error  DWORD fDummy2:17; // reserved  WORD wReserved; // not currently used  WORD XonLim; // transmit XON threshold  WORD XoffLim; // transmit XOFF threshold  BYTE ByteSize; // number of bits/byte, 4-8  BYTE Parity; // 0-4=no,odd,even,mark,space  BYTE StopBits; // 0,1,2 = 1, 1.5, 2  char XonChar; // Tx and Rx XON character  char XoffChar; // Tx and Rx XOFF character  char ErrorChar; // error replacement character  char EofChar; // end of input character  char EvtChar; // received event character  WORD wReserved1; // reserved; do not use } DCB; 而SetupComm函数的原型则为:BOOL SetupComm( HANDLE hFile, // handle to communications device DWORD dwInQueue, // size of input buffer DWORD dwOutQueue // size of output buffer);  以下程序将串口设置为:波特率为9600,数据位数为7位,停止位为2 位,偶校验,接收缓冲区和发送缓冲区大小均为1024个字节,最后用PurgeComm函数终止所有的后台读写操作并清空接收缓冲区和发送缓冲区: DCB dcb;dcb.BaudRate = 9600; //波特率为9600dcb.ByteSize = 7; //数据位数为7位dcb.Parity = EVENPARITY; //偶校验dcb.StopBits = 2; //两个停止位dcb.fBinary = TRUE;dcb.fParity = TRUE;if (!SetCommState(hCom, &dcb)){ MessageBox("串口设置出错!");} SetupComm(hCom, 1024, 1024);PurgeComm(hCom, PURCE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);  超时设置  超时设置是通过改变COMMTIMEOUTS结构体的成员变量值来实现的,COMMTIMEOUTS的原型为: typedef struct _COMMTIMEOUTS{ DWORD ReadIntervalTimeout; //定义两个字符到达的最大时间间隔,单位:毫秒 //当读取完一个字符后,超过了ReadIntervalTimeout,仍未读取到下一个字符,就会 //发生超时 DWORD ReadTotalTimeoutMultiplier;  DWORD ReadTotalTimeoutConstant; //其中各时间所满足的关系如下: //ReadTotalTimeout = ReadTotalTimeOutMultiplier* BytesToRead ReadTotalTimeoutConstant DWORD WriteTotalTimeoutMultiplier; DWORD WriteTotalTimeoutConstant;} COMMTIMEOUTS, *LPCOMMTIMEOUTS;  设置超时的函数为SetCommTimeouts,其原型中接收COMMTIMEOUTS的指针为参数: BOOL SetCommTimeouts( HANDLE hFile, // handle to communications device LPCOMMTIMEOUTS lpCommTimeouts // pointer to comm time-out structure);  以下程序将串口读操作的超时设定为10 毫秒: COMMTIMEOUTS to;memset(&to, 0, sizeof(to));to.ReadIntervalTimeout = 10;SetCommTimeouts(hCom, &to);  与SetCommTimeouts对应的GetCommTimeouts()函数的原型为: BOOL GetCommTimeouts( HANDLE hFile, // handle of communications device LPCOMMTIMEOUTS lpCommTimeouts // pointer to comm time-out structure);  事件设置  在读写串口之前,需要用SetCommMask ()函数设置事件掩模来监视指定通信端口上的事件,其原型为: BOOL SetCommMask( HANDLE hFile, //标识通信端口的句柄 DWORD dwEvtMask //能够使能的通信事件);  有了Set当然还会有Get,与SetCommMask对应的GetCommMask()函数的原型为: BOOL GetCommMask( HANDLE hFile, //标识通信端口的句柄 LPDWORD lpEvtMask // address of variable to get event mask);  串口上可以发生的事件可以是如下事件列表中的一个或任意组合:EV_BREAK、EV_CTS、EV_DSR、EV_ERR、EV_RING、EV_RLSD、EV_RXCHAR、EV_RXFLAG、EV_TXEMPTY。  我们可以用WaitCommEvent()函数来等待串口上我们利用SetCommMask ()函数设置的事件: BOOL WaitCommEvent( HANDLE hFile, //标识通信端口的句柄 LPDWORD lpEvtMask, // address of variable for event that occurred LPOVERLAPPED lpOverlapped, // address of overlapped structure);  WaitCommEvent()函数一直阻塞,直到串口上发生我们用所SetCommMask ()函数设置的通信事件为止。一般而言,当WaitCommEvent()返回时,程序员可以由分析*lpEvtMask而获得发生事件的类别,再进行相应的处理。  读串口  对串口进行读取所用的函数和对文件进行读取所用的函数相同,读函数原型如下: BOOL ReadFile( HANDLE hFile, // handle of file to read LPVOID lpBuffer, // pointer to buffer that receives data DWORD nNumberOfBytesToRead, // number of bytes to read LPDWORD lpNumberOfBytesRead, // pointer to number of bytes read LPOVERLAPPED lpOverlapped // pointer to structure for overlapped I/O);  写串口  对串口进行写入所用的函数和对文件进行写入所用的函数相同,写函数原型如下: BOOL WriteFile( HANDLE hFile, // handle to file to write to LPCVOID lpBuffer, // pointer to data to write to file DWORD nNumberOfBytesToWrite, // number of bytes to write LPDWORD lpNumberOfBytesWritten, // pointer to number of bytes written LPOVERLAPPED lpOverlapped // pointer to structure for overlapped I/O);  关闭串口  利用API 函数实现串口通信时关闭串口非常简单,只需使用CreateFile 函数返回的句柄作为参数调用CloseHandle 即可: BOOL CloseHandle( HANDLE hObject // handle to object to close);共2页。 1 2 : 下载本文示例代码


深入浅出VC 串口编程之基于Win32 API深入浅出VC 串口编程之基于Win32 API深入浅出VC 串口编程之基于Win32 API深入浅出VC 串口编程之基于Win32 API深入浅出VC 串口编程之基于Win32 API深入浅出VC 串口编程之基于Win32 API深入浅出VC 串口编程之基于Win32 API深入浅出VC 串口编程之基于Win32 API深入浅出VC 串口编程之基于Win32 API深入浅出VC 串口编程之基于Win32 API深入浅出VC 串口编程之基于Win32 API深入浅出VC 串口编程之基于Win32 API深入浅出VC 串口编程之基于Win32 API深入浅出VC 串口编程之基于Win32 API深入浅出VC 串口编程之基于Win32 API
阅读(204) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~