谢谢各位了。现在是需要写一个名为Dmeasure的类,类的作用是输入端口和波特率,发送命令之后,再把接收到的数据打印出来。
这是名为Dmeasure.h的头文件
ifndef Dmeasure_H
#define Dmeasure_H
#include <windows.h>
#include <winNt.h>
#include <stdlib.h>
#include <iostream>
#include <conio.h>
class Dmeasure
{
public:
Dmeasure(char* Pname,int rate_arg=9600);
int getdistance();//测量距离的函数声明
private:
int rate;
char* portname;
int m_distance;
OVERLAPPED m_ov;
COMSTAT comstat;
HANDLE hComm;
HANDLE hCanReceiveEvent;
char ConvertHexChar(char ch);//将字符转换为相应的十六进制值
bool ProcessErrorMessage(char* ErrorText);//错误处理
bool openport();//打开一个串口
bool setupdcb(int rate_arg);//设置波特率
bool setuptimeout(DWORD ReadInterval,DWORD ReadTotalMultiplier,DWORD ReadTotalconstant,DWORD WriteTotalMultiplier,DWORD WriteTotalconstant);
bool WriteChar(BYTE *m_szWriteBuffer,DWORD m_nToSend); //向串口写入命令
void Writepart();
};
#endif
以下是Dmeasure.cpp文件
#include "stdafx.h"
#include "Dmeasure.h"
Dmeasure::Dmeasure(char* Pname,int rate_arg) //构造函数,包括打开串口和波特率设置
{
portname = Pname;
rate = rate_arg;
hCanReceiveEvent = CreateEvent(NULL,FALSE,FALSE,NULL);//这句是不是不用线程的话,可以省略?
if(openport())
printf("open comport success\n");
//printf("%p\n",hComm);
if(setupdcb(rate))
printf("setupDCB success\n");
if(setuptimeout(0,0,0,0,0))
printf("setuptimeout success\n");
PurgeComm(hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
}
bool Dmeasure::openport()//打开一个串口
{
DWORD dwNum = MultiByteToWideChar (CP_ACP, 0, portname, -1, NULL, 0);
wchar_t *pwText;
pwText = new wchar_t[dwNum];
if(!pwText)
{
delete []pwText;
}
MultiByteToWideChar (CP_ACP, 0, portname, -1, pwText, dwNum);
hComm = CreateFile(pwText,//串口号
GENERIC_READ | GENERIC_WRITE,//允许读写
0, //通讯设备必须以独立方式打开
0, //无安全属性
OPEN_EXISTING, //通讯设备存在
FILE_ATTRIBUTE_NORMAL, //异步I/O
0); //通讯设备不能用模板打开
if (hComm == INVALID_HANDLE_VALUE)
return FALSE;
else
return true;
}
bool Dmeasure::setupdcb(int rate)
{
DCB dcb;
memset(&dcb,0,sizeof(dcb));//清零dcb
if(!GetCommState(hComm,&dcb))//获取当前DCB配置
{
ProcessErrorMessage("GetCommState()");
return FALSE;
}
/* -------------------------------------------------------------------- */
// set DCB to configure the serial port
dcb.DCBlength = sizeof(dcb);
/* ---------- Serial Port Config ------- */
dcb.BaudRate = rate;//波特率9600
dcb.ByteSize = 8;//8数据位
dcb.Parity = NOPARITY;//无校验位
dcb.StopBits = ONESTOPBIT;//1停止位
dcb.fParity = 0;//无奇偶校验
dcb.fBinary = 1;//二进制方式
/* -------------------------------------------------------------------- */
// set DCB
if(!SetCommState(hComm,&dcb))
{
ProcessErrorMessage("SetCommState()");
return false;
}
else
return true;
}
bool Dmeasure::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))
{
ProcessErrorMessage("SetCommTimeouts()");
return false;
}
else
return true;
}
bool Dmeasure::WriteChar(BYTE *m_szWriteBuffer,DWORD m_nToSend)
{
BOOL bWrite = TRUE;
BOOL bResult = TRUE;
DWORD BytesSent = 0;
//HANDLE m_hWriteEvent;
//if(SetEvent(m_hWriteEvent))
//ResetEvent(m_hWriteEvent);
if (bWrite)
{
m_ov.Offset = 0;
m_ov.OffsetHigh = 0;
// Clear buffer
//printf("%p\n",hComm);
bResult = WriteFile(hComm, // Handle to COMM Port
m_szWriteBuffer, // Pointer to message buffer in calling finction
m_nToSend, // Length of message to send
&BytesSent, // 这里就回出问题,得到已经发送的字节数为0.不知道为什么
&m_ov ); // Overlapped structure
//printf("bResult=%d\n",bResult);
if (!bResult)
{
DWORD dwError = GetLastError();
//printf("dwError=%d",dwError);
switch (dwError)
{
case ERROR_IO_PENDING:
{
// continue to GetOverlappedResults()
BytesSent = 0;
bWrite = FALSE;
break;
}
default:
{
// all other error codes
ProcessErrorMessage("WriteFile()");
}
}
}
} // end if(bWrite)
if (!bWrite)
{
bWrite = TRUE;
bResult = GetOverlappedResult(hComm, // Handle to COMM port
&m_ov, // Overlapped structure
&BytesSent, // Stores number of bytes sent
TRUE); // Wait flag
// deal with the error code
if (!bResult)
{
ProcessErrorMessage("GetOverlappedResults() in WriteFile()");
}
} // end if (!bWrite)
// Verify that the data size send equals what we tried to send
if (BytesSent != m_nToSend)
{
printf("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)m_szWriteBuffer));
}
return true;
}
void Dmeasure::Writepart()
{
char get_command[12]="22 00 00 22";//需要写入的
/********把字符串转换为16进制数组********/
BYTE senddata[4];
int hexdata,lowhexdata;
int hexdatalen=0;
for(int i=0;i<12;)
{
char lstr,hstr=get_command[i];
if(hstr==' '||hstr=='\0 ')
{
i++;
continue;
}
i++;
if(i>=12)
break;
lstr=get_command[i];
hexdata=ConvertHexChar(hstr);
lowhexdata=ConvertHexChar(lstr);
if((hexdata==16)||(lowhexdata==16))
break;
else
hexdata=hexdata*16+lowhexdata;
i++;
senddata[hexdatalen]=(BYTE)hexdata;
hexdatalen++;
}
/***************************************/
WriteChar(senddata,4); //写入
//SetEvent(hCanReceiveEvent);
//printf("send cmd...\n");
//Sleep(50);
}
int Dmeasure::getdistance()
{
Writepart();//写入数据部分,以下为接收数据并打印
BOOL bRead = TRUE;
BOOL bResult = TRUE;
DWORD dwError = 0;
DWORD BytesRead = 0;
char *RXBuff=new char[5];
bResult = ClearCommError(hComm, &dwError, &comstat);
if (comstat.cbInQue == 0)
{
printf("接收数据失败!\n");
return 0;}
else
{
printf("接收到数据!\n");
if (bRead)
{
bResult = ReadFile(hComm, // Handle to COMM port
RXBuff, // RX Buffer Pointer
4, // Read one byte
&BytesRead, // Stores number of bytes read
&m_ov); // pointer to the m_ov structure
for(int i=0;i<4;i++)
{
printf("%.2x",RXBuff[i]);
}
printf("\n");
if((RXBuff[3]-RXBuff[0])==((RXBuff[1]*16*16+RXBuff[2])&0xff))//对接收到的数据进行校验,满足要求才赋给m_distance
{
m_distance=RXBuff[1]*16*16+RXBuff[2];
printf("m_distance=%d",m_distance);
printf("\n");
return m_distance;
}
if (!bResult)
{
switch (dwError = GetLastError())
{
case ERROR_IO_PENDING:
{
bRead = FALSE;
break;
}
default:
{
break;
}
}
return 0;}
else
{
bRead = TRUE;
return 0;
}
} // close if (bRead)
else{
bRead = TRUE;
bResult = GetOverlappedResult(hComm, // Handle to COMM port
&m_ov, // Overlapped structure
&BytesRead, // Stores number of bytes read
TRUE); // Wait flag
return 0;
}
}
}
char Dmeasure::ConvertHexChar(char ch) //将字符转换为相应的十六进制值
{
if((ch>='0')&&(ch<='9'))
return ch-0x30;
else if((ch>='A')&&(ch<='F'))
return ch-'A'+10;
else if((ch>='a')&&(ch<='f'))
return ch-'a'+10;
else return (-1);
}
bool Dmeasure::ProcessErrorMessage(char* ErrorText)
{
char *Temp = new char[200];
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
sprintf(Temp, "WARNING: %s Failed with the following error: \n%s\nPort: %d\n", (char*)ErrorText, lpMsgBuf, "com2");
//MessageBox(NULL, Temp, "Application Error", MB_ICONSTOP);
LocalFree(lpMsgBuf);
delete[] Temp;
return true;
}
主函数是这样用这个类的:
#include "stdafx.h"
#include "Dmeasure.h"
int _tmain(int argc, _TCHAR* argv[])
{
Dmeasure juli("com6");
int distance;
distance=juli.getdistance();
return 0;
}
最后得到的运行显示 打开串口等等都成功了,但是 WriteFile《》error Bytes Sent:0; Message Length:1
就是说数据没发送出去。 不知道怎么回事。
谢谢各位了~ (不知道该不该在这个版问这个问题。。。请见谅)
------解决思路----------------------
帮顶下,PC程序不是很熟悉
不过串口相关的类网上很多,
要检查下下位机接收和PC发送的设置是不是一样,比如说PC端启用流控制,那些CTS等线,而下位机没有.
不要自己发自己收,最好用2个,一个主一个从
------解决思路----------------------
直接Debugg调试,看看是不是串口没有打开?hComm是不是空值,默认上来给他付空值,在hComm = CreateFile()的时候付有效值。
------解决思路----------------------
建议你把2、3相连,然后用mcutool之类的串口监视工具测试一下,看看到底是否成功发送。