求助:USB转串口通信数据无法正常接收

zhouming113213 2010-10-19 01:45:36
我用windows API 写了一个串口通信的程序,由于要用到两个串口,因此一条要用到USB转串口,在用电脑现有串口测试程序时收发数据正常,但用USB转串口发送数据会出错,哪为高手能帮我分析下,问题出在哪里,不甚感激!!!!!!
代码如下:
//定义的串口通信类SerialPort.h
class CSerialPort
{
public:

typedef enum tagParity
{
NON,
ODD,
EVEN,
MARKY,
SPACE
}PLARITY;

CSerialPort(void);
~CSerialPort(void);
bool Init_SerialPort(LPTSTR szPort=L"COM4", UINT nBaudRate = 9600 , PLARITY cParity = EVEN,
UINT ndatabits = 8, UINT nStopbits = 1);

DWORD SerialWrite(PBYTE wrBuffer, int nSize);
DWORD SerialRead(PBYTE rdBuffer, int nSiz);
void CloseSerialPort(void);
bool IsOpened(void);

protected:
HANDLE m_CommPort;
bool m_Opened;
};
//类成员函数Serial.cpp
#include "SteAfx.h"
#include "serialport.h"
#include "stdio.h"

CSerialPort::CSerialPort(void)
: m_CommPort(0), m_Opened(false)
{
}

CSerialPort::~CSerialPort(void)
{
}

bool CSerialPort::Init_SerialPort(LPTSTR szPort,
UINT nBaudRate,
PLARITY cParity,
UINT ndatabits,
UINT nStopbits)
{
BOOL bPortReady = FALSE;
DWORD dwError = 0, dwRC = 0;
DCB dcb;
COMMTIMEOUTS CommTimeouts;
/* Modified *******************************/
//CString errStr; // remove
/*******************************************************************/
m_CommPort = CreateFile(
szPort,
GENERIC_READ|GENERIC_WRITE,
0, // exclusive
NULL, // sec attr
OPEN_EXISTING,
0, // no attributes
NULL); // no template

if (m_CommPort == INVALID_HANDLE_VALUE)
{
LPVOID lpMsgBuf;
lpMsgBuf = NULL;

dwError = GetLastError();
dwRC = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwError, // from GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL);

if (dwRC && lpMsgBuf)
{
/* Modi *******************************/
// errStr.Format(L"COM open failed: Port = %s Error = %d - %s", szPort, dwError, lpMsgBuf); //remove
//AfxMessageBox(errStr);
/*******************************************************************/
}
else
{
/* Modified By*******************************/
// errStr.Format(L"COM open failed: Port = %s Error = %d ", szPort, dwError); // remove
// AfxMessageBox(errStr);
/*******************************************************************/
} // end if

if (dwRC && lpMsgBuf)
{
LocalFree( lpMsgBuf );
} // end if
return false;
}
else
{
bPortReady = SetupComm(m_CommPort, 256, 256); // set buffer sizes
if (!bPortReady)
{
dwError = GetLastError();
/* Modified *******************************/
// errStr.Format(L"SetupComm failed: Port = %s Error = %d", szPort, dwError); // remove
// AfxMessageBox(errStr);
/*******************************************************************/
}

bPortReady = GetCommState(m_CommPort, &dcb);
if (!bPortReady)
{
dwError = GetLastError();
/* *******************************/
// errStr.Format(L"GetCommState fai
/********************led: Port = %s Error = %d", szPort, dwError); // remove
// AfxMessageBox(errStr);***********************************************/
} // end if

dcb.DCBlength = sizeof(DCB);
dcb.BaudRate = nBaudRate;
dcb.ByteSize = ndatabits;
dcb.Parity = cParity;//NOPARITY;
dcb.StopBits = nStopbits;
dcb.fAbortOnError = TRUE;

bPortReady = SetCommState(m_CommPort, &dcb);
if (!bPortReady)
{
dwError = GetLastError();

/* *******************************/
// errStr.Format(L"SetCommState failed: Port = %s Error = %d", szPort, dwError); // remove
// AfxMessageBox(errStr);
/*******************************************************************/
}

bPortReady = GetCommTimeouts (m_CommPort, &CommTimeouts);
if (!bPortReady)
{
dwError = GetLastError();
/* Modified *******************************/
// errStr.Format(L"GetCommTimeouts failed: Port = %s Error = %d", szPort, dwError); // remove
// AfxMessageBox(errStr);
/*******************************************************************/
} // end if

CommTimeouts.ReadIntervalTimeout = 300;
CommTimeouts.ReadTotalTimeoutConstant = 1000;
CommTimeouts.ReadTotalTimeoutMultiplier = 300;
CommTimeouts.WriteTotalTimeoutConstant = 1000;
CommTimeouts.WriteTotalTimeoutMultiplier = 10;

bPortReady = SetCommTimeouts (m_CommPort, &CommTimeouts);
PurgeComm(m_CommPort,PURGE_TXCLEAR | PURGE_RXCLEAR);
if (!bPortReady)
{
dwError = GetLastError();

/* Modified By *******************************/
// errStr.Format(L"SetCommTimeouts failed: Port = %s Error = %d", szPort, dwError); // remove
// AfxMessageBox(errStr);
/*******************************************************************/
} // end if
printf("the serial initial success!");
}

m_Opened = true;
return true;
}

DWORD CSerialPort::SerialWrite(PBYTE wrBuffer, int nSize)
{
DWORD dwNumWritten;

WriteFile( m_CommPort,
wrBuffer,
nSize,
&dwNumWritten,
NULL);
return dwNumWritten;
}

DWORD CSerialPort::SerialRead(PBYTE rdBuffer, int nSiz)
{
BOOL bReadRC;
DWORD iBytesRead;
DWORD dwError;
/* Modified By *******************************/
// CString errStr; // remove
/*******************************************************************/
memset(rdBuffer, 0, sizeof(rdBuffer));
bReadRC = ReadFile(m_CommPort, rdBuffer, nSiz, &iBytesRead, NULL);

if (!bReadRC && iBytesRead <= 0)
{
dwError = GetLastError();

/* Modified By *******************************/
// errStr.Format(L"Read length failed: RC=%d Bytes read=%d, Error= %d",bReadRC, iBytesRead, dwError); // remove
// AfxMessageBox(errStr);
/*******************************************************************/
} // end if

return iBytesRead;
}


void CSerialPort::CloseSerialPort(void)
{
if (m_CommPort != INVALID_HANDLE_VALUE)
CloseHandle(m_CommPort);

m_CommPort = 0;
m_Opened = false;
}
bool CSerialPort::IsOpened(void)
{
return m_Opened;
}

//测试主程序
#include "SteAfx.h"
#include "SerialPort.h"
#include "stdio.h"
int main()
{
char wrBuffer[16];
CSerialPort PcPro;
if(PcPro.IsOpened())
PcPro.CloseSerialPort();
if(!PcPro.Init_SerialPort())
printf("you are fail!\n");
sprintf_s(wrBuffer,"%s","* 0 IR 008\r");
PcPro.SerialWrite((PBYTE)wrBuffer,11); //发送数据
PcPro.CloseSerialPort();
return 1;
}
...全文
1240 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhouming113213 2010-10-19
  • 打赏
  • 举报
回复
很感谢qf17331733,谢谢你的支持!
我用VC2008写的,PBYTE是widows.h头文件里面重新定义的字符指针类型
即typedef char *PBYTE,好象是这样一来.
zhouming113213 2010-10-19
  • 打赏
  • 举报
回复
很感谢大家的支持,问题我已经解决了,上面是我修改了的正确代码,与大家分享.
主要问题是我在初始化串口的时候,奇偶校验方式错了,Cparity应设成NON,我设成了EVEN,故接受时把最后一个字节的数据自动当作奇偶校验位,丢失掉,因此导致发送和接受都少一个字节数据.
zhouming113213 2010-10-19
  • 打赏
  • 举报
回复
更新code
* 文件名称: SerialPort.h
* 文件描述: RS232 端口封装标头文件
*/

class CSerialPort
{
public:

typedef enum tagParity
{
NON,
ODD,
EVEN,
MARKY,
SPACE
}PLARITY;

CSerialPort(void);
~CSerialPort(void);
bool Init_SerialPort(LPTSTR szPort=L"COM4", UINT nBaudRate = 9600 , PLARITY cParity = NON,
UINT ndatabits = 8, UINT nStopbits = 1);

DWORD SerialWrite(PBYTE wrBuffer, int nSize);
DWORD SerialRead(PBYTE rdBuffer, int nSiz);
void CloseSerialPort(void);
bool IsOpened(void);

protected:
HANDLE m_CommPort;
bool m_Opened;
};

/*
* 文件名称: SerialPort.cpp
* 文件描述: RS232 端口封装原始程序文档
*/

#include <windows.h>
#include "serialport.h"
#include "stdio.h"

CSerialPort::CSerialPort(void)
: m_CommPort(0), m_Opened(false)
{
}

CSerialPort::~CSerialPort(void)
{
}

bool CSerialPort::Init_SerialPort(LPTSTR szPort,
UINT nBaudRate,
PLARITY cParity,
UINT ndatabits,
UINT nStopbits)
{
BOOL bPortReady = FALSE;
DWORD dwError = 0, dwRC = 0;
DCB dcb;
COMMTIMEOUTS CommTimeouts;
/*******************************************************************/
m_CommPort = CreateFile(
szPort,
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);

SetupComm(m_CommPort, 256, 256); //设置输入输出缓存大小
/***************设置串口通信参数,baudrate,parity*************/
GetCommState(m_CommPort, &dcb);
dcb.DCBlength = sizeof(DCB);
dcb.BaudRate = nBaudRate;
dcb.ByteSize = ndatabits;
dcb.Parity = cParity;
dcb.StopBits = nStopbits;
dcb.fAbortOnError = TRUE;
SetCommState(m_CommPort, &dcb);
GetCommTimeouts (m_CommPort, &CommTimeouts);
/************设置串口超时参数********************************/
CommTimeouts.ReadIntervalTimeout = 300;
CommTimeouts.ReadTotalTimeoutConstant = 1000;
CommTimeouts.ReadTotalTimeoutMultiplier = 300;
CommTimeouts.WriteTotalTimeoutConstant = 1000;
CommTimeouts.WriteTotalTimeoutMultiplier = 300;
bPortReady = SetCommTimeouts (m_CommPort, &CommTimeouts);
m_Opened = true;
return true;
}
/*********写串口函数******************************************/
DWORD CSerialPort::SerialWrite(PBYTE wrBuffer, int nSize)
{
DWORD dwNumWritten;

WriteFile( m_CommPort,
wrBuffer,
nSize,
&dwNumWritten,
NULL);
return dwNumWritten;
}
/****************读串口函数************************************/
DWORD CSerialPort::SerialRead(PBYTE rdBuffer, int nSiz)
{
BOOL bReadRC;
DWORD iBytesRead;
DWORD dwError;
memset(rdBuffer, 0, sizeof(rdBuffer));
bReadRC = ReadFile(m_CommPort, rdBuffer, nSiz, &iBytesRead, NULL);
return iBytesRead;
}

/*********关闭串口设备*************************/
void CSerialPort::CloseSerialPort(void)
{
if (m_CommPort != INVALID_HANDLE_VALUE)
CloseHandle(m_CommPort);

m_CommPort = 0;
m_Opened = false;
}
/***判断串口是否打开*********************/
bool CSerialPort::IsOpened(void)
{
return m_Opened;
}

//测试程序
#include <windows.h>
#include "SerialPort.h"
#include "stdio.h"
int main()
{

char wrBuffer[16];
CSerialPort PcPro;
if(PcPro.IsOpened())
PcPro.CloseSerialPort();
if(!PcPro.Init_SerialPort())
printf("you are fail!\n");
sprintf_s(wrBuffer,"%s","* 0 IR 008\r");
PcPro.SerialWrite((PBYTE)wrBuffer,11);//通过串口写命令控制终端设备
PcPro.CloseSerialPort();

return 1;
}
qf17331733 2010-10-19
  • 打赏
  • 举报
回复
重头看了下你的程序~
PcPro.SerialWrite((PBYTE)wrBuffer,11); //发送数据
这个是什么类型?
enter333 2010-10-19
  • 打赏
  • 举报
回复
我最近也在学写串口程序,这里有串口调试助手的源码和讲解,你可以去看看,说不定能找到答案;
http://www.gjwtech.com/vcandc/scommassistantcode02.htm

我自己上也是用usb转串口的程序,运行正常的啊。
zhouming113213 2010-10-19
  • 打赏
  • 举报
回复
不好意思,因为比较急,所以没来得及整理,我等会再发一分整理好的上来
这份code在主机自带的串口下,发送是正常的,就是在usb转串口的情况下会出问题
zhouming113213 2010-10-19
  • 打赏
  • 举报
回复
很感谢你的关注!
不好意思,刚才到网上找资料没看到你的回帖
换了USB转串口后是COM4,我为了验证我的程序有问题,我用串口调试终端测试过,用串口调试终端发送数据给我的接受设备,数据能正确接受.
就是换做我的程序会出问题.
qf17331733 2010-10-19
  • 打赏
  • 举报
回复
bool Init_SerialPort(LPTSTR szPort=L"COM4", UINT nBaudRate = 9600 , PLARITY cParity = EVEN,
UINT ndatabits = 8, UINT nStopbits = 1);

问下,你换了USB转串口后串口号还是COM4吗?
aeolus_boy 2010-10-19
  • 打赏
  • 举报
回复
兄弟,你的代码很乱!不过我推荐你看一个视频教程:
http://www.verycd.com/topics/250252/
这个:
20-Linux的串口编程.avi 详情
专门讲串口编程的,嵌入式我不是很了解,我只是看过一遍视频而已。祝你好运,相信你会有提升的

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧