c语言串口通讯过程?

Python010

c语言串口通讯过程?,第1张

分接收端和发送端。

接收端:

1·打开com1端口

fd=fopen("/dev/ttys0",方式)

2·取得当前串口值,保存到结构体变量oldtio

tcgetattr(fd,&oldtio)

3·串口结构体变量newtio清0.

bzero(&newtio,sizeof(newtio))

4·设置串口参数

主要设置比特率、是否忽略奇偶校验错误,启用正规模式等等。

接收端

1·打开com端口

2·取得当前串口值

3·串口结构体变量清0

4·设置串口参数。

基本方法是使用CreateFile来建立一个串口文件,然后用overlap的方式进行读写

#define SERAIL_PORT_BUF_MAX (1024*8)

typedef HRESULT (*PFN_CMD_PARSE_DATA)(HANDLE hParseApp, LPCSTR szRspCmd, int nCmdLen)

class CUsbSrvApp// : public CWinApp

{

public:

CUsbSrvApp()

~CUsbSrvApp()

BOOL OnSendData(const char *szBuf, int nLen)// 发送数据

int ComConnect(CString strPort)// 连接COM口

HANDLE OpenComPort(CString strPort, int nBaudRate, int nDataBits, int nStopBits, int nParity, int nFlowCtrlType)// 打开串口

void Close()// 关闭串口

HANDLE m_hCom

BOOL m_bConnected

OVERLAPPED m_OverlappedRead

OVERLAPPED m_OverlappedWrite

CWinThread *m_pThread

PFN_CMD_PARSE_DATA m_pRspCmdFunc// 用来处理接受数据的CALLBACK

HANDLE m_hParseApp

}

CUsbSrvApp::CUsbSrvApp()

{

// TODO: add construction code here,

// Place all significant initialization in InitInstance

m_bConnected = false

m_hCom = NULL

m_pRspCmdFunc = NULL

}

CUsbSrvApp::~CUsbSrvApp()

{

}

//打开串口通信,并返回串口句柄

HANDLE CUsbSrvApp::OpenComPort(CString strPortName,

int nBaudRate,

int nDataBits,

int nStopBits,

int nParity,

int nFlowCtrlType)

{

DCB dcb

COMMTIMEOUTS CommTimeOuts

COMMCONFIG ComConfig

HANDLE hComPort

CString strPort

strPort.Format("\\\\.\\%s",strPortName)// COM口的文件名应该是 \\.\COMXX

//打开窗口其实就是创建一个文件

hComPort = CreateFile(strPort,

GENERIC_READ | GENERIC_WRITE,

FILE_SHARE_READ | FILE_SHARE_WRITE,

NULL,

OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,

NULL)

if (INVALID_HANDLE_VALUE == hComPort)

return INVALID_HANDLE_VALUE

// 设置一些COM口通讯参数和OVERLAP

CommTimeOuts.ReadIntervalTimeout = -1

CommTimeOuts.ReadTotalTimeoutConstant = 0

CommTimeOuts.ReadTotalTimeoutMultiplier = 0

CommTimeOuts.WriteTotalTimeoutConstant = 0

CommTimeOuts.WriteTotalTimeoutMultiplier = 0x1388

SetCommTimeouts( m_hCom, &CommTimeOuts )

SetDefaultCommConfig(strPortName, &ComConfig, sizeof(COMMCONFIG))

GetCommState(m_hCom, &dcb )

dcb.BaudRate = nBaudRate

dcb.ByteSize = nDataBits

dcb.StopBits = nStopBits

dcb.fParity = (NOPARITY != nParity)

dcb.Parity = nParity

//set the receive char

dcb.EvtChar = 0x0D

switch(nFlowCtrlType)

{

case 0: //no flow control

break

case 1://HARD_FLOW_CTRL:

dcb.fOutxCtsFlow = TRUE

dcb.fOutxDsrFlow = TRUE

dcb.fDtrControl = DTR_CONTROL_DISABLE

dcb.fDsrSensitivity = TRUE

dcb.fRtsControl = RTS_CONTROL_TOGGLE

break

case 2://SOFT_FLOW_CTRL:

dcb.fOutX = TRUE

dcb.fInX = TRUE

break

}

BuildCommDCB(_T("baud=115200 parity=N data=8 stop=1"),&dcb)

SetCommState(hComPort, &dcb )

SetCommMask(hComPort, 0)

SetCommMask(hComPort, EV_RXCHAR|EV_CTS|EV_DSR|EV_RLSD|EV_RING)

SetupComm( hComPort, SERAIL_PORT_BUF_MAX,SERAIL_PORT_BUF_MAX)

//clear read and write buffer

PurgeComm( hComPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR )

return hComPort

}

void CUsbSrvApp::Close()

{

if(m_bConnected)

{

m_bConnected = false

CloseHandle(m_hCom)

m_hCom = NULL

}

}

// 这个线程是监视串口数据,一旦有数据则读取并调用CALLBACK通知客户端

UINT ReceiveComData(LPVOID pParam)

{

CUsbSrvApp *pUsbSrv = (CUsbSrvApp *)pParam

HANDLE hComPort = pUsbSrv->m_hCom

DWORD dwEvtMask=0

DWORD dwErrorFlags

SetCommMask( hComPort, EV_RXCHAR)

OVERLAPPED osRead

osRead.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL)

DWORD dwTransfer = 0

while(pUsbSrv->m_bConnected)

{

if( !WaitCommEvent( hComPort, &dwEvtMask,&osRead))

{

if( GetLastError()== ERROR_IO_PENDING)

{

WaitForSingleObject(osRead.hEvent, INFINITE)

if(dwEvtMask&EV_RXCHAR==EV_RXCHAR)

{

COMSTAT ComStat={0}

DWORD dwReadLen = 0

DWORD dwBytesRead = 0

DWORD dwTotalLen = 0

ClearCommError(hComPort, &dwErrorFlags, &ComStat )

dwTotalLen = ComStat.cbInQue

dwReadLen = (SERAIL_PORT_BUF_MAX >dwTotalLen)?dwTotalLen:SERAIL_PORT_BUF_MAX

BYTE *pBuf = new BYTE[dwTotalLen+1]

memset(pBuf, 0 , dwTotalLen+1)

DWORD nReadBufLen=0

while(dwTotalLen>0)

{

if(FALSE == ReadFile( hComPort, pBuf+nReadBufLen,dwReadLen, &dwBytesRead,&pUsbSrv->m_OverlappedRead))

{

if(GetLastError() == ERROR_IO_PENDING)

{

GetOverlappedResult(hComPort,&osRead, &dwTransfer, TRUE )

}

break

}

nReadBufLen +=dwBytesRead

dwTotalLen -=dwBytesRead

dwReadLen -= dwBytesRead

dwReadLen = (SERAIL_PORT_BUF_MAX>dwReadLen)?dwReadLen:SERAIL_PORT_BUF_MAX

}

if(pUsbSrv->m_pRspCmdFunc!=NULL&&nReadBufLen!=0)

{

pUsbSrv->m_pRspCmdFunc(pUsbSrv->m_hParseApp, (char*)pBuf,nReadBufLen)

}

delete pBuf

ClearCommError(hComPort, &dwErrorFlags, &ComStat )

int len =0//= m_retList.GetSize()

}//endif if(dwEvtMask&EV_RXCHAR==EV_RXCHAR)

}//endif if( GetLastError()== ERROR_IO_PENDING)

}//endif if( !WaitCommEvent( hComPort, &dwEvtMask,&o))

else

{

if(GetLastError() == ERROR_IO_PENDING) {

GetOverlappedResult(hComPort, &osRead, &dwTransfer, TRUE )// sleep thread

}

}

Sleep(1)

} //endwhile while(m_bConnected)

return 0

}

int CUsbSrvApp::ComConnect(CString strPort)

{

int nBaudRate = 115200

int nDataBits = 8

int nStopBits = 1

int nParity = 0

int nFlowCtrl = 1

if (NULL != m_hCom || m_bConnected)

{

return 0

}

m_hCom = OpenComPort(strPort,nBaudRate,nDataBits,nStopBits,nParity,nFlowCtrl)

if( INVALID_HANDLE_VALUE == m_hCom)

{

m_hCom = NULL

return 0

}

memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) )

memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) )

m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL )

m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL )

m_pThread = AfxBeginThread( ReceiveComData,(void*)this,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED ,NULL )

if( NULL == m_pThread )

{

CloseHandle( m_hCom )

m_hCom = NULL

return FALSE

}

else

{

m_bConnected = TRUE

m_pThread->ResumeThread( )

}

return TRUE

}

int CUsbSrvApp::OnSendData(const char *szBuf, int nLen)

{

BOOL bWriteStat

BOOL bWrite = TRUE

DWORD dwBytesWrite = 0

DWORD dwBytesWritten = 0

int dwByteswrittenTotal = 0

if (NULL == m_hCom)

return 0

int nSentTimes=0

while(dwByteswrittenTotal<nLen&&nSentTimes<10)

{

nSentTimes++

dwBytesWrite = nLen-dwByteswrittenTotal

bWriteStat = WriteFile( m_hCom, szBuf+dwByteswrittenTotal, dwBytesWrite, &dwBytesWritten, &m_OverlappedWrite )

if( !bWriteStat)

{

if ( GetLastError() == ERROR_IO_PENDING )

{

dwBytesWritten = 0

bWrite = FALSE

}

}

if (!bWrite)

{

bWrite = TRUE

bWriteStat = GetOverlappedResult(m_hCom, // Handle to COMM port

&m_OverlappedWrite, // Overlapped structure

&dwBytesWritten, // Stores number of bytes sent

TRUE)// Wait flag

//deal with the error code

}

dwByteswrittenTotal += dwBytesWritten

}

if(dwByteswrittenTotal<nLen)

return 0

else

return 1

}