关于Seriesport串口通信实现单片机与PC之间数据交互

现在大部分串口助手都是使用的MFC自带的串口类,但是附在界面上使用受到了很大限制,所以不断搜寻查找,找到了seriesport这个类,使用方便,特别适用于单片机与PC之间的相互传输数据使用。现在项目主要用在1.控制继电器定时开关,单线结构光需要把细线提取出来,有两种办法,一种是加一个滤光片,直接留下激光线即可(滤光片采用的卓美30

.5mm,850波段的红外滤光片,相机采用pointgrey的Flea3 FL3-U3-13Y3M)。一种方法是拍一张无激光图片,然后给单片机发送信号,单片机接收到信号闭合继电器,再拍一张有激光的图案。这时就需要串口通信,可实现自动拍照采集数据。 2.控制6掌灯亮灭配合相机拍照,为了快速获得图片,也需要进行串行口通信。

接下来把程序附在下边,只是改了改别人的程序,需要的可以拿去用,已经测试通过

#include <iostream>     
#include <cstdlib>  
#include <windows.h>  


HANDLE hComm;
OVERLAPPED OverLapped;
COMSTAT Comstat;
DWORD dwCommEvents;


bool OpenPort();  //打开串口  
bool SetupDCB(int rate_arg);  //设置DCB  
bool SetupTimeout(DWORD ReadInterval, DWORD ReadTotalMultiplier, DWORD
ReadTotalConstant, DWORD WriteTotalMultiplier, DWORD WriteTotalConstant);   //设置超时  
void ReciveChar();   //接收字符  
bool WriteChar(char* szWriteBuffer, DWORD dwSend);  //发送字符  


bool OpenPort()
{
hComm = CreateFile(L"COM4",
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);
if (hComm == INVALID_HANDLE_VALUE)
return FALSE;
else
return true;
}


bool SetupDCB(int rate_arg)
{
DCB dcb;
memset(&dcb, 0, sizeof(dcb));
if (!GetCommState(hComm, &dcb))//获取当前DCB配置  
{
return FALSE;
}
dcb.DCBlength = sizeof(dcb);
/* ---------- Serial Port Config ------- */
dcb.BaudRate = rate_arg;
dcb.Parity = NOPARITY;
dcb.fParity = 0;
dcb.StopBits = ONESTOPBIT;
dcb.ByteSize = 8;
dcb.fOutxCtsFlow = 0;
dcb.fOutxDsrFlow = 0;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fDsrSensitivity = 0;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fOutX = 0;
dcb.fInX = 0;
dcb.fErrorChar = 0;
dcb.fBinary = 1;
dcb.fNull = 0;
dcb.fAbortOnError = 0;
dcb.wReserved = 0;
dcb.XonLim = 2;
dcb.XoffLim = 4;
dcb.XonChar = 0x13;
dcb.XoffChar = 0x19;
dcb.EvtChar = 0;
if (!SetCommState(hComm, &dcb))
{
return false;
}
else
return true;
}


bool SetupTimeout(DWORD ReadInterval, DWORD ReadTotalMultiplier, DWORD
ReadTotalConstant, DWORD WriteTotalMultiplier, DWORD WriteTotalConstant)
{
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = ReadInterval;
timeouts.ReadTotalTimeoutConstant = ReadTotalConstant;
timeouts.ReadTotalTimeoutMultiplier = ReadTotalMultiplier;
timeouts.WriteTotalTimeoutConstant = WriteTotalConstant;
timeouts.WriteTotalTimeoutMultiplier = WriteTotalMultiplier;
if (!SetCommTimeouts(hComm, &timeouts))
{
return false;
}
else
return true;
}


void ReciveChar()
{
bool bRead = TRUE;
bool bResult = TRUE;
DWORD dwError = 0;
DWORD BytesRead = 0;
;

char RXB[11];
memset(RXB, 0, sizeof(RXB));





bResult = ReadFile(hComm,  //通信设备(此处为串口)句柄,由CreateFile()返回值得到  
RXB,  //指向接收缓冲区  


10,  //指明要从串口中读取的字节数  
&BytesRead,   //  
&OverLapped);  //OVERLAPPED结构  

//因为是overlapped操作,ReadFile会将读文件请求放入读队列之后立即返回(false),
//而不会等到文件读完才返回(true)
if (bResult)
{
std::cout << RXB << std::endl;


//文件真是被读完了,rc为true
// 或当数据被放入cache中,或操作系统认为它可以很快速地取得数据,rc为true
}
else
{
if (GetLastError() == ERROR_IO_PENDING)
{//当错误是ERROR_IO_PENDING,那意味着读文件的操作还在进行中
//等候,直到文件读完


GetOverlappedResult(hComm, &OverLapped, &BytesRead, TRUE);
std::cout << RXB << std::endl;



}
else
{
//出错了
}
}
   
PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
 
}






bool WriteChar(char* szWriteBuffer, DWORD dwSend)
{
bool bWrite = TRUE;
bool bResult = TRUE;
DWORD BytesSent = 0;
HANDLE hWriteEvent = NULL;
ResetEvent(hWriteEvent);
if (bWrite)
{
OverLapped.Offset = 0;
OverLapped.OffsetHigh = 0;
bResult = WriteFile(hComm,  //通信设备句柄,CreateFile()返回值得到  
szWriteBuffer,  //指向写入数据缓冲区  
dwSend,  //设置要写的字节数  
&BytesSent,  //  
&OverLapped);  //指向异步I/O数据  
if (!bResult)
{
DWORD dwError = GetLastError();
switch (dwError)
{
case ERROR_IO_PENDING:
BytesSent = 0;
bWrite = FALSE;
break;
default:
break;
}
}
}
if (!bWrite)
{
bWrite = TRUE;
bResult = GetOverlappedResult(hComm,
&OverLapped,
&BytesSent,
TRUE);
if (!bResult)
{
std::cout << "GetOverlappedResults() in WriteFile()" << std::endl;
}
}
if (BytesSent != dwSend)
{
std::cout << "WARNING: WriteFile() error.. Bytes Sent:" << BytesSent << "; Message Length: " << strlen((char*)szWriteBuffer) << std::endl;
}
return TRUE;
}
int main()
{
if (OpenPort())
std::cout << "Open port success" << std::endl;
if (SetupDCB(9600))
std::cout << "Set DCB success" << std::endl;
if (SetupTimeout(0, 0, 0, 0, 0))
std::cout << "Set timeout success" << std::endl;
PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);


for (int i = 0; i < 20; i++){
if (i % 2 == 0){
char a[] = "0";
WriteChar(a, 1);
Sleep(1000);
}
else{
char a[] = "1";
WriteChar(a, 1);
Sleep(1000);
}
ReciveChar();

}




CloseHandle(hComm);


return EXIT_SUCCESS;
}

猜你喜欢

转载自blog.csdn.net/konglingshneg/article/details/80495461