1 串口是一种时常用来与外界通信的一种设备,虽然现在网络已经很普及,但由于PC机时常需要通过MODEM与远距离主机或是与单片机设备进行通信所以串口的用途还是很广泛。
2 串口在Win32的开发中可以以文件的形式来进行打开和关闭,并且串口的读写也可以利用ReadFile和WriteFile来进行操作。以前在Windows 3.X下的OpenComm等部分串口操作函数已经被废弃。 3 串口的开打可以使用下面的方法: 4 HANDLE hDev = CreateFile( "COM1", 指明串口名称,COM1代表第一个串口,COM2代表第二个串口 5 GENERIC_READ | GENERIC_WRITE, 用于读和写 6 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 指明为异步操作方式 7 8 NULL ); 9 串口被打开后,马上要进行的操作就是设置串口的状态和属性,通过指定一个DCB的结构来对串口进行设置,所使用的函数有下面这些 10 BOOL SetCommState( 11 HANDLE hFile, handle to communications device 12 LPDCB lpDCB device-control block 13 ); 14 15 其中DCB结构为 16 typedef struct _DCB { 17 DWORD DCBlength; sizeof(DCB) 结构长度 18 DWORD BaudRate; current baud rate 波特率 可取下面的值,表示每秒的速率(bit per second) 19 /* 20 CBR_110 CBR_19200 CBR_300 CBR_38400 CBR_600 CBR_56000 CBR_1200 CBR_57600 21 CBR_2400 CBR_115200 CBR_4800 CBR_128000 CBR_9600 CBR_256000 CBR_14400 */ 22 DWORD fBinary: 1; binary mode, no EOF check 二进制方式 23 DWORD fParity: 1; enable parity checking 允许奇偶校验 24 DWORD fOutxCtsFlow:1; CTS output flow control CTS(clear-to-send)流控 25 DWORD fOutxDsrFlow:1; DSR output flow control DSR(data-set-ready)流控 26 DWORD fDtrControl:2; DTR flow control type DTR(data-terminal-ready)流制 27 DWORD fDsrSensitivity:1; DSR sensitivity 是否检测握手信号 28 DWORD fTXContinueOnXoff:1; XOFF continues Tx 29 DWORD fOutX: 1; XON/XOFF out flow control 30 DWORD fInX: 1; XON/XOFF in flow control 31 DWORD fErrorChar: 1; enable error replacement 32 DWORD fNull: 1; enable null stripping 33 DWORD fRtsControl:2; RTS flow control 34 DWORD fAbortOnError:1; abort on error 35 DWORD fDummy2:17; reserved 36 WORD wReserved; not currently used 37 WORD XonLim; transmit XON threshold 38 WORD XoffLim; transmit XOFF threshold 39 BYTE ByteSize; number of bits/byte, 4-8 数据位 40 BYTE Parity; 0-4=no,odd,even,mark,space 校验方式 41 BYTE StopBits; 0,1,2 = 1, 1.5, 2 停止位 42 char XonChar; Tx and Rx XON character 43 char XoffChar; Tx and Rx XOFF character 44 char ErrorChar; error replacement character 45 char EofChar; end of input character 46 char EvtChar; received event character 47 WORD wReserved1; reserved; do not use 48 } DCB; 49 通过一个字符串来建立DCB结构 50 例如字符串:baud=1200 parity=N data=8 stop=1 表明使用1200BPS速率,偶校验,8位数据位,1位停止位 51 BOOL BuildCommDCB( 52 LPCTSTR lpDef, device-control string 53 LPDCB lpDCB device-control block 54 ); 55 设置端口的缓冲区大小 56 BOOL SetupComm( 57 HANDLE hFile, handle to communications device 58 DWORD dwInQueue, size of input buffer 输入缓冲区大小 59 DWORD dwOutQueue size of output buffer 输出缓冲区大小 60 ); 61 62 串口的读写依然可以利用ReadFile和WriteFile函数,这里介绍另一个函数来查询端口状态, 63 BOOL ClearCommError( 64 HANDLE hFile, handle to communications device 65 LPDWORD lpErrors, error codes 66 LPCOMSTAT lpStat communications status 67 ); 68 69 COMSTAT结构如下 70 typedef struct _COMSTAT { 71 DWORD fCtsHold : 1; 72 DWORD fDsrHold : 1; 73 DWORD fRlsdHold : 1; 74 DWORD fXoffHold : 1; 75 DWORD fXoffSent : 1; 76 DWORD fEof : 1; 77 DWORD fTxim : 1; 78 DWORD fReserved : 25; 79 DWORD cbInQue; //接收队列内数据量 80 DWORD cbOutQue; 发送队列内数据量 81 } COMSTAT, *LPCOMSTAT; 82 //从串口内读取数据 83 { 84 BOOL bReadStatus; 85 DWORD dwBytesRead, dwErrorFlags; 86 COMSTAT ComStat; 87 ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat ); 88 if( !ComStat.cbInQue ) return( 0 ); //检查当前是否有数据在接收队列内 89 dwBytesRead = (DWORD) ComStat.cbInQue; 90 if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit; //确定当前可能读入的最大数量 91 bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead ); 92 if( !bReadStatus ) 93 { 94 if( GetLastError() == ERROR_IO_PENDING ) 95 { 96 WaitForSingleObject( m_OverlappedRead.hEvent, 2000 ); //等待读操作完成 97 return( (int) dwBytesRead ); 98 } 99 return( 0 );100 } 101 } 102 103 //在本节提供一个经过封装的类CSerial来完成串口的操作,这份代码来自于网上,我写了一个简单的DEMO用于向MODEM发送AT命令并读回数据。相关代码如下:104 //CSerial ser;假设COM1端口上是一个MODEM,通过发送AT命令来和MODEM进行通信105 //关于AT命令请查询其他资料106 if(ser.Open(1,9600))107 { 108 char szCmd[100],szRet[100];109 strcpy(szCmd,"ATI0\r\n");返回调制解调器默认的速率110 int iSend = ser.SendData(szCmd,strlen(szCmd));111 while(ser.ReadDataWaiting() == 0)112 {//等待数据113 Sleep(100);114 }115 int iRead =ser.ReadData(szRet,99);116 if(iRead != 0)117 { 118 szRet[iRead]='\0';119 printf("send %s read %s\n",szCmd,szRet);120 }121 } 122 else 123 { 124 printf("error open COM port\n");125 }picked from:http://yadang418.blog.163.com/blog/static/2684365620096103126456/