myserial.cpp
来自「一个串行口通讯的例子程序」· C++ 代码 · 共 365 行
CPP
365 行
// CMySerial class implementaion//#include <windows.h>#include "stdafx.h"#include <fstream.h>#include <stdio.h>#include "tty.h"#include "MySerial.h"CMySerial::CMySerial():m_nReadThread(0),m_dwError(0){ m_ReadingBuffer.dwLen=0; m_ReadingBuffer.lpByte=NULL; m_hSerial=INVALID_HANDLE_VALUE;}CMySerial::~CMySerial(){ if(m_hSerial!=INVALID_HANDLE_VALUE) CloseSerial();}CMySerial::InitSerial(UINT nPort/*=1*/, UINT baud/*=2400*/, char parity/*='n'*/, UINT databits/*=8*/, UINT stopbits/*=1*/){ DCB PortDCB; COMMTIMEOUTS CommTimeouts; char buf[10]; sprintf(buf,"COM%d",nPort); // Open the serial port. m_hSerial = CreateFile (buf, // Pointer to the name of the port GENERIC_READ | GENERIC_WRITE, // Access (read/write) mode 0, // Share mode NULL, // Pointer to the security attribute OPEN_EXISTING,// How to open the serial port 0, // Port attributes NULL); // Handle to port with attribute // to copy // If it fails to open the port, return FALSE. if ( m_hSerial == INVALID_HANDLE_VALUE ) { // Could not open the port. MessageBox (NULL, TEXT("Unable to open the port"), TEXT("Error"), MB_OK); m_dwError = GetLastError (); DisplayError(); return FALSE; } PortDCB.DCBlength = sizeof (DCB); // Get the default port setting information. GetCommState (m_hSerial, &PortDCB); // Change the DCB structure settings. PortDCB.BaudRate = baud; // Current baud PortDCB.fBinary = TRUE; // Binary mode; no EOF check PortDCB.fParity = TRUE; // Ensable 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 = databits; // Number of bits/bytes, 4-8 if(parity=='n'||parity=='N') PortDCB.Parity = NOPARITY; // 0-4=no,odd,even,mark,space switch(stopbits) { case 1: PortDCB.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2 break; default: PortDCB.StopBits = TWOSTOPBITS; break; } // Configure the port according to the specifications of the DCB // structure. if (!SetCommState (m_hSerial, &PortDCB)) { // Could not configure the serial port. MessageBox (NULL, TEXT("Unable to configure the serial port"), TEXT("Error"), MB_OK); m_dwError = GetLastError (); DisplayError(); return FALSE; } // Retrieve the time-out parameters for all read and write operations // on the port. GetCommTimeouts (m_hSerial, &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 (m_hSerial, &CommTimeouts)) { // Could not set the time-out parameters. MessageBox (NULL, TEXT("Unable to set the time-out parameters"), TEXT("Error"), MB_OK); m_dwError = GetLastError (); DisplayError(); return FALSE; } // Direct the port to perform extended functions SETDTR and SETRTS. // SETDTR: Sends the DTR (data-terminal-ready) signal. // SETRTS: Sends the RTS (request-to-send) signal. EscapeCommFunction (m_hSerial, SETDTR); EscapeCommFunction (m_hSerial, SETRTS); return TRUE;}BOOL CMySerial::CloseSerial(){ if (m_hSerial != INVALID_HANDLE_VALUE) { // Close the communication port. if (!CloseHandle (m_hSerial)) { m_dwError = GetLastError (); DisplayError(); return FALSE; } else { m_hSerial = INVALID_HANDLE_VALUE; return TRUE; } } return FALSE;}BOOL CMySerial::WritePort(BYTE byte){ DWORD dwNumBytesWritten; if (!WriteFile (m_hSerial, // Port handle &byte, // Pointer to the data to write 1, // Number of bytes to write &dwNumBytesWritten, // Pointer to the number of bytes // written NULL)) // Must be NULL for Windows CE { // WriteFile failed. Report error. m_dwError = GetLastError (); DisplayError(); return FALSE; } return TRUE;}void CMySerial::DisplayError(void){ LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, m_dwError, 0, // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION ); // Free the buffer. LocalFree( lpMsgBuf );}BOOL CMySerial::ReadPort(LPBYTE lpByte, DWORD dwLen/*=1*/, DWORD dwTimeLimit/*=2000*/){ if(m_nReadThread) { MessageBox(0,"已经有一个读串口的线程在工作!\n读串口请求被拒绝","ReadPort",MB_OK); return FALSE; } else //m_nReadThread=0 { InterlockedIncrement(&m_nReadThread); } m_ReadingBuffer.dwLen=dwLen; m_ReadingBuffer.lpByte=lpByte; memset(m_ReadingBuffer.lpByte,0,m_ReadingBuffer.dwLen); HANDLE hReadThread=CreateThread(0,0,(LPTHREAD_START_ROUTINE)ReadThread,this,0,0); if(hReadThread) { DWORD dwRet=WaitForSingleObject(hReadThread,dwTimeLimit); if(dwRet==WAIT_TIMEOUT) { MessageBox(NULL,TEXT("Read thread stopped because time out!"),TEXT("Error"),MB_OK); m_dwError=GetLastError(); DisplayError(); m_ReadingBuffer.dwLen=0; m_ReadingBuffer.lpByte=0; InterlockedDecrement(&m_nReadThread); return FALSE; } } else { MessageBox (NULL, TEXT("Unable to create the read thread"), TEXT("Error"), MB_OK); m_dwError = GetLastError (); DisplayError(); m_ReadingBuffer.dwLen=0; m_ReadingBuffer.lpByte=0; InterlockedDecrement(&m_nReadThread); return FALSE; } m_ReadingBuffer.dwLen=0; m_ReadingBuffer.lpByte=0; InterlockedDecrement(&m_nReadThread); return TRUE;}UINT CMySerial::ReadThread(LPVOID pParam){ ofstream fout; CMySerial *pPort=(CMySerial*)pParam; DWORD dwCommModemStatus, dwBytesTransferred; // Specify a set of events to be monitored for the port. SetCommMask (pPort->m_hSerial, EV_RXCHAR | EV_CTS | EV_DSR | EV_RLSD | EV_RING); DWORD dwCount=0; while ((pPort->m_hSerial != INVALID_HANDLE_VALUE) &&(dwCount<pPort->m_ReadingBuffer.dwLen)) { // Wait for an event to occur for the port. WaitCommEvent (pPort->m_hSerial, &dwCommModemStatus, 0); // Re-specify the set of events to be monitored for the port. SetCommMask (pPort->m_hSerial, EV_RXCHAR | EV_CTS | EV_DSR | EV_RING); if (dwCommModemStatus & EV_RXCHAR) { // Loop for waiting for the data. do { // Read the data from the serial port. ReadFile (pPort->m_hSerial, &pPort->m_ReadingBuffer.lpByte[dwCount], 1, &dwBytesTransferred, 0); // Display the data read. if (dwBytesTransferred == 1) { //receive a byte of data successfully dwCount++; } } while (dwBytesTransferred == 1); } // Retrieve modem control-register values. if(GetCommModemStatus (pPort->m_hSerial, &dwCommModemStatus)==FALSE) { pPort->m_dwError=GetLastError(); pPort->DisplayError(); fout.open("e:\\error.txt",ios::app); fout<<pPort->m_dwError<<endl; fout.close(); } } return 0;}double CMySerial::GetFrequency(){ if(WritePort(0x80)==FALSE) { AfxMessageBox("写串口失败!"); return 0; } BYTE lpByte[20]; memset(lpByte,0,20); if(ReadPort(lpByte,12)==FALSE) { AfxMessageBox("读端口失败"); return 0; } int data[6]; data[5]=0; double freq[6]; freq[5]=0; for(int i=0;i<5;i++) { data[i]=256*((int)lpByte[2*i+3])+(int)lpByte[2*i+2]; freq[i]=((double)data[i])*20.10370; } int max,min; MaxMin(data,5,max,min); for(i=0;i<5;i++) { if((i==max)||(i==min)) continue; else { data[5]+=data[i]; freq[5]+=freq[i]; } } data[5]/=3; freq[5]/=3;// COleDateTime time=::COleDateTime::GetCurrentTime();// char buffer[512];// sprintf(buffer,"%2d时%2d分%2d秒: %2x%2x %2x%2x %2x%2x %2x%2x %2x%2x : %lf",// time.GetHour(),time.GetMinute(),time.GetSecond(),lpByte[3],lpByte[2],lpByte[5],// lpByte[4],lpByte[7],lpByte[6],lpByte[9],lpByte[8],lpByte[11],lpByte[10],freq[5]);// ofstream fout("e:\\data0.txt",ios::app);// fout<<buffer<<endl;// fout.close(); return freq[5];}void CMySerial::MaxMin(int *pInt, int len, int &max, int &min){ max=0; min=0; for(int i=0;i<len;i++) { if(pInt[i]>pInt[max]) max=i; if(pInt[i]<pInt[min]) min=i; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?