根據某本天書說明
首先要Configure a serial port
1.呼叫 CreateFile() 來開一個預設設定的新埠。
2.初始化 DCB 結構內的 DCBlength 的成員。
3.呼叫 GetCommState() 看剛剛開的埠的參數設定。
4.修改 DCB 以符合需求。
5.呼叫 SetCommState() 設定參數。
於是有了以下的範例
// Open the serial port. // 參數1. Pointer to the name of the port // 參數2. Access (read/write) mode // 參數3. Share mode // 參數4. Pointer to the security attribute // 參數5. How to open the serial port // 參數6. Port attributes // Handle to port with attribute to copy HANDLE hPort;
hPort = CreateFile(lpszPortName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); // If it fails to open the port, return error. if ( hPort == INVALID_HANDLE_VALUE ) { CloseHandle(hPort); // Could not open the port. LocalFree( lpMsgBuf ); // Free the buffer. return EC_FOPEN; } PortDCB.DCBlength = sizeof(DCB); GetCommState(hPort, &PortDCB); // Get the default port setting info // Change the DCB structure settings. PortDCB.BaudRate = 9600; // Current baud rate PortDCB.fBinary = TRUE; // Binary mode; no EOF check PortDCB.fParity = TRUE; // Enable parity checking. PortDCB.fOutxCtsFlow = FALSE; // No CTS output flow control PortDCB.fOutxDsrFlow = FALSE; // No DSR output flow control PortDCB.fDtrControl = DTR_CONTROL_ENABLE; // DTR flow control type PortDCB.fDsrSensitivity = FALSE; // DSR sensitivity PortDCB.fTXContinueOnXoff = TRUE; // XOFF continues Tx PortDCB.fOutX = FALSE; // No XON/XOFF out flow control PortDCB.fInX = FALSE; // No XON/XOFF in flow control PortDCB.fErrorChar = FALSE; // Disable error replacement. PortDCB.fNull = FALSE; // Disable null stripping. PortDCB.fRtsControl = RTS_CONTROL_ENABLE; // RTS flow control PortDCB.fAbortOnError = FALSE; // Do not abort reads/writes on error PortDCB.ByteSize = 8; // Number of bits/bytes, 4-8 PortDCB.Parity = NOPARITY; // 0-4=no,odd,even,mark,space PortDCB.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2 // Configure the port according to the specifications of the DCB structure. if (!SetCommState (hPort, &PortDCB)) { printf("Unable to configure the port & Err Info. = %s\n", (LPCTSTR)lpMsgBuf); // Free the buffer. LocalFree( lpMsgBuf ); return EC_INVAL_CONFIG; } // Retrieve the time-out parameters for all read and write operations on the port. GetCommTimeouts(hPort, &CommTimeouts); // Change the COMMTIMEOUTS structure settings. CommTimeouts.ReadIntervalTimeout = MAXDWORD; CommTimeouts.ReadTotalTimeoutMultiplier = 0; CommTimeouts.ReadTotalTimeoutConstant = 0; CommTimeouts.WriteTotalTimeoutMultiplier = 10; CommTimeouts.WriteTotalTimeoutConstant = 1000; // Set the time-out parameters for all read and write operations on the port. if (!SetCommTimeouts (hPort, &CommTimeouts)) { // Could not create the read thread. dwError = GetLastError(); printf("Unable to set the time-out parameters & Err code = %ld\n", dwError); return EC_TIMEOUT_SET; } EscapeCommFunction(hPort, SETDTR); EscapeCommFunction(hPort, SETRTS); pCreate->h_Port = hPort; // reserve the port handle
資料的寫入
再度引用天書的說法
WriteFile()是將資料送到UART寫入資料緩衝內。
以下是天書的步驟說明
1.Pass the port handler to the WriteFile() function in the hPort parameter.
TheCreateFile() function returns this handler when our program opens a new port.
2.Specify a pointer to the data to be written in lpBuffer. Typically, this will be binarydata or a character array.
3.Specify the number of characters to write in nNumberOfBytesToWrite.
For Win-dows CE–based devices, only one character is usually written, because the applicationmust convert Unicode characters to
ASCII characters to enable a text transfer to adevice at the opposite end of a serial connection.
4.Specify in lpNumberOfBytesWritten a pointer to the number of bytes actuallywritten.
WriteFile() fills this variable so that our program can determine if the datahas been transferred.
5.Be sure that the lpOverlapped parameter is set to NULL.
超簡短寫入的範例
if (!WriteFile (hPort, // Port handle NumByte, // Number of bytes to write &dwNumBytesWritten, // Pointer to the number of bytes written NULL)) // Must be NULL for Windows CE { // WriteFile failed. Report error. printf("Unable to write the port ...& Err Info. = %s", (LPCTSTR)lpMsgBuf); // Free the buffer. LocalFree( lpMsgBuf ); ……. }
資料的讀取
天書又再度開示了步驟
1.Pass the port handler to ReadFile() in the hPort parameter. The CreateFile()
function returns this handler when a new port is created.
2.Specify a pointer to the data to be read in lpBuffer.
3.Specify the number of characters to read in nNumberOfBytesToRead.
4.Specify a pointer to the number of bytes actually read in the argument
lpNumberOfBytesRead.
5.Be sure that lpOverlapped is set to NULL. Windows CE does not support the
overlapped I/O.
另外還有一個要點:
如果要使用 WaitCommEvent() ,最好另開一個thread去讀取序列埠。
後面漏漏等,我貼範例比較快。
if (!(hThread = CreateThread(NULL, // no security attributes 0, // use default stack size (LPTHREAD_START_ROUTINE) ThreadFunc, (LPVOID)hCommPort, // parameter to thread function CREATE_SUSPENDED, // creation flag - suspended &IDThread) ) ) // returns thread ID { printf("Create Read Thread failed\n"); return EC_CREATE_THREAD; } ResumeThread(hThread); // start thread function now Ret = WaitForSingleObject(hThread, dTimeout); if (Ret == WAIT_OBJECT_0) { // data received & process it... // Need do nothing, the data has been stored in the hCommPort in Thread Func. // close thread handle CloseHandle(hThread); } else if (Ret == WAIT_TIMEOUT) { // time out happened, warning & kill thread Ret = GetExitCodeThread(hThread, &ExitCode); if (ExitCode == STILL_ACTIVE) { printf("Time out happened!\n"); // debug purpose TerminateThread(hThread, ExitCode); CloseHandle(hThread); return EC_PORT_TIMEOUT; } else { printf("ERROR in GetExitCodeThread: != STILL_ACTIVE\n"); ecStatus = EC_EXIT_CODE; } } else { printf("ERROR in WaitFor SingleObject...\n"); ecStatus = EC_WAIT_SINGLEOBJ; } ……
關於thread的內容如下
void WINAPI ThreadFunc(void* hCommPorts) { …… // Specify a set of events to be monitored for the port. SetCommMask(CommPorts->handlePort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING); // Wait for an event to occur for the port. WaitCommEvent(CommPorts->handlePort, &dwCommModemStatus, 0); // Re-specify the set of events to be monitored for the port. SetCommMask(CommPorts->handlePort, EV_RXCHAR | EV_CTS | EV_DSR |EV_RLSD| EV_RING); if (dwCommModemStatus & EV_RXCHAR||dwCommModemStatus & EV_RLSD) { // received the char_event // Read the data from the serial port. bResult = ReadFile(CommPorts->handlePort, &Byte, 1, &dwBytesTransferred, 0); if (!bResult) { printf("Unable to read the port ...& Err Info. = %s\n", (LPCTSTR)lpMsgBuf); LocalFree( lpMsgBuf ); // Free the buffer. printf("ERROR in PortRead - Timeout\n"); } else { // store the data read. CommPorts->bByte = Byte; nTotRead++; } } return; }
如果沒有WaitCommEvent()怎麼辦?
我也不知道怎麼辦
這只是個節錄,不是傳道授業用。