如何用C语言控制计算机串口

如何用C语言控制计算机串口,第1张

基本方法是使用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

}

#include <AT89X51.H>//单片机51头文件,存放着单片机的寄存器

unsigned char dat//用于存储单片机接收发送缓冲寄存器SBUF里面的内容

sbit gewei=P2^2//个位选通定义

sbit shiwei=P2^3//十位选通定义

unsigned char code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67,0x77,0x7c,0x39,0x5e,0x79,0x71}

//{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67,}// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9

void Delay(unsigned int tc) //延时程序

{

while( tc != 0 )

{unsigned int i

for(i=0i<100i++)

tc--}

}

void LED() //LED显示接收到的数据

{

shiwei=0

P0=~table[dat/16]

Delay(8)

shiwei=1

gewei=0

P0=~table[dat%16]

Delay(5)

gewei=1

}

void Init_Com(void)//功能:串口初始化,波特率9600,方式1

{

TMOD = 0x20

PCON = 0x00

SCON = 0x50

TH1 = 0xFd

TL1 = 0xFd

TR1 = 1

}

void main()//主程序功能:实现接收数据并把接收到的数据原样发送回去///////

{

Init_Com()//串口初始化

// P1=0xf0

while(1)

{

if ( RI ) //扫描判断是否接收到数据,

{

dat = SBUF //接收数据SBUF赋与dat

RI=0 //RI清零。

SBUF = dat //在原样把数据发送回去

}

LED()//显示接收到的数据

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/12209248.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存