1 #include 2 #include 3 #include 4 5 HANDLE hComm; 6 OVERLAPPED m_ov; 7 COMSTAT comstat; 8 DWORD m_dwCommEvents; 9 10 //如果在调用CreateFile创建句柄时指 11 //定了FILE_FLAG_OVERLAPPED标志,那么调用ReadFile和WriteFile对该句柄进 12 //行的操作就应该是重叠的;如果未指定 13 //重叠标志,则读写操作应该是同步的 14 //在同步执行时,函数直到操作完成后才返回。这意味着同步执行时线程会被阻塞,从 15 //而导致效率下降。在重叠执行时,即使操作还未完成,这两个函数也会立即返回,费 16 //时的I/O操作在后台进行 17 bool openport(char *portname)//打开一个串口 18 { 19 hComm = CreateFile(portname, 20 GENERIC_READ | GENERIC_WRITE, 21 0, 22 0, 23 OPEN_EXISTING, 24 FILE_FLAG_OVERLAPPED, 25 0); 26 if (hComm == INVALID_HANDLE_VALUE) 27 return FALSE; 28 else 29 return true; 30 } 31 32 33 bool setupdcb(int rate_arg) 34 { 35 DCB dcb; 36 int rate= rate_arg; 37 memset(&dcb,0,sizeof(dcb)); //在一段内存块中填充某个给定的值,是对较大的结构//体或数组进行清零操作的一种最快方法 38 if(!GetCommState(hComm,&dcb))//获取当前DCB配置 39 { 40 return FALSE; 41 } 42 /* -------------------------------------------------------------------- */ 43 // set DCB to configure the serial port 44 dcb.DCBlength = sizeof(dcb); 45 /* ---------- Serial Port Config ------- */ 46 dcb.BaudRate = rate; 47 dcb.Parity = NOPARITY; 48 dcb.fParity = 0; 49 dcb.StopBits = ONESTOPBIT; 50 dcb.ByteSize = 8; 51 dcb.fOutxCtsFlow = 0; 52 dcb.fOutxDsrFlow = 0; 53 dcb.fDtrControl = DTR_CONTROL_DISABLE; 54 dcb.fDsrSensitivity = 0; 55 dcb.fRtsControl = RTS_CONTROL_DISABLE; 56 dcb.fOutX = 0; 57 dcb.fInX = 0; 58 /* ----------------- misc parameters ----- */ 59 dcb.fErrorChar = 0; 60 dcb.fBinary = 1; 61 dcb.fNull = 0; 62 dcb.fAbortOnError = 0; 63 dcb.wReserved = 0; 64 dcb.XonLim = 2; 65 dcb.XoffLim = 4; 66 dcb.XonChar = 0x13; 67 dcb.XoffChar = 0x19; 68 dcb.EvtChar = 0; 69 /* -------------------------------------------------------------------- */ 70 // set DCB 71 if(!SetCommState(hComm,&dcb)) 72 { 73 return false; 74 } 75 else 76 return true; 77 } 78 //在用readfile和writefile读写串行口时,需要考虑超时问题, 读写串口的超时有两 79 //种:间隔超时和总超时, 写操作只支持总超时,而读操作两种超时均支持, 如果所有 80 //写超时参数均为0,那么就不使用写超时。 81 bool setuptimeout(DWORD ReadInterval,DWORD ReadTotalMultiplier,DWORD ReadTotalconstant,DWORD WriteTotalMultiplier,DWORD WriteTotalconstant) 82 { 83 COMMTIMEOUTS timeouts; 84 timeouts.ReadIntervalTimeout=ReadInterval; //读间隔超时 85 timeouts.ReadTotalTimeoutConstant=ReadTotalconstant; //读时间系数 86 timeouts.ReadTotalTimeoutMultiplier=ReadTotalMultiplier; //读时间常量 87 timeouts.WriteTotalTimeoutConstant=WriteTotalconstant; // 写时间系数 88 timeouts.WriteTotalTimeoutMultiplier=WriteTotalMultiplier; //写时间常//量, 总超时的计算公式是:总超时=时间系数×要求读/写的字符数+时间常量 89 if(!SetCommTimeouts(hComm, &timeouts)) 90 { 91 return false; 92 } 93 else 94 return true; 95 } 96 void ReceiveChar(){ 97 BOOL bRead = TRUE; 98 BOOL bResult = TRUE; 99 DWORD dwError = 0;100 DWORD BytesRead = 0;101 char RXBuff;102 while(true){103 bResult = ClearCommError(hComm, &dwError, &comstat);104 // 在使用ReadFile 函数进行读操作前,应先使用ClearCommError函数清除错误105 if(comstat.cbInQue==0)// COMSTAT结构返回串口状态信息106 //本文只用到了cbInQue成员变量,该成员变量的值代表输入缓冲区的字节数107 continue;108 if(bRead){109 bResult = ReadFile(hComm, // Handle to COMM port串口的句柄110 &RXBuff,// RX Buffer Pointer// 读入的数据存储的地址,即读入的数据将存//储在以该指针的值为首地址的一片内存区111 1,// Read one byte要读入的数据的字节数,112 &BytesRead, // Stores number of bytes read, 指向一个DWORD//数值,该数值返回读操作实际读入的字节数113 &m_ov); // pointer to the m_ov structure// 重叠操作时,该参数指向一个OVERLAPPED结构,同步操作时,该参数为NULL114 printf("%c",RXBuff);115 if (!bResult){ // 当ReadFile和WriteFile返回FALSE时,不一定就是操作失//败,线程应该调用GetLastError函数分析返回的结果116 switch (dwError = GetLastError()){117 case ERROR_IO_PENDING:118 bRead = FALSE;119 break;120 default:break;121 }122 }else{123 bRead = TRUE;124 }125 } // close if (bRead)126 if (!bRead){127 bRead = TRUE;128 bResult = GetOverlappedResult(hComm, // Handle to COMM port129 &m_ov, // Overlapped structure130 &BytesRead, // Stores number of bytes read131 TRUE); // Wait flag132 }133 }134 }135 BOOL WriteChar(BYTE* m_szWriteBuffer,DWORD m_nToSend){136 BOOL bWrite = TRUE;137 BOOL bResult = TRUE;138 DWORD BytesSent = 0;139 HANDLE m_hWriteEvent;140 ResetEvent(m_hWriteEvent);141 if (bWrite){142 m_ov.Offset = 0;143 m_ov.OffsetHigh = 0;144 // Clear buffer145 bResult = WriteFile(hComm, // Handle to COMM Port, 串口的句柄146 m_szWriteBuffer, // Pointer to message buffer in calling finction147 // 即以该指针的值为首地址的nNumberOfBytesToWrite148 // 个字节的数据将要写入串口的发送数据缓冲区149 m_nToSend, // Length of message to send, 要写入的数据的字节数150 &BytesSent, // Where to store the number of bytes sent151 // 指向指向一个DWORD数值,该数值返回实际写入的字节数152 &m_ov ); // Overlapped structure153 // 重叠操作时,该参数指向一个OVERLAPPED结构,154 // 同步操作时,该参数为NULL155 if (!bResult){ // 当ReadFile和WriteFile返回FALSE时,不一定就是操作失156 //败,线程应该调用GetLastError函数分析返回的结果157 DWORD dwError = GetLastError();158 switch (dwError){159 case ERROR_IO_PENDING: //GetLastError函数返回//ERROR_IO_PENDING。这说明重叠操作还未完成160 // continue to GetOverlappedResults()161 BytesSent = 0;162 bWrite = FALSE;163 break;164 default:break;165 }166 }167 } // end if(bWrite)168 if (!bWrite){169 bWrite = TRUE;170 bResult = GetOverlappedResult(hComm, // Handle to COMM port171 &m_ov, // Overlapped structure172 &BytesSent, // Stores number of bytes sent173 TRUE); // Wait flag174 175 // deal with the error code176 if (!bResult){177 printf("GetOverlappedResults() in WriteFile()");178 }179 } // end if (!bWrite)180 181 // Verify that the data size send equals what we tried to send182 if (BytesSent != m_nToSend){183 printf("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)m_szWriteBuffer));184 }185 return true;186 }187 188 189 void main(){190 if(openport("com4"))191 printf("open comport success\n");192 if(setupdcb(115200))193 printf("setupDCB success\n");194 if(setuptimeout(0,0,0,0,0)) //如果所有写超时参数均为0,那么就不使用写超时195 printf("setuptimeout success\n");196 PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT); // 在读写串口之前,还要用PurgeComm()函数清空缓冲区197 //PURGE_TXABORT 中断所有写操作并立即返回,即使写操作还没有完成。198 //PURGE_RXABORT 中断所有读操作并立即返回,即使读操作还没有完成。199 //PURGE_TXCLEAR 清除输出缓冲区200 //PURGE_RXCLEAR 清除输入缓冲区201 //WriteChar("please send data now",20);202 printf("received data:\n");203 ReceiveChar( );204 system("pause");205 }
http://www.cnblogs.com/zjutlitao/p/3709910.html