线程中使用COMM口的问题

carefulman 2006-04-17 09:31:50
代码如下:
//先获取COM口状态
if(ClearCommError(m_COMHandle, &error, &stat) && error > 0) //清除错误
{
PurgeComm(m_COMHandle, PURGE_TXABORT | PURGE_TXCLEAR); /*清除输入缓冲区*/
return false;
}
//ClearCommError(m_COMHandle, &error, &stat);

unsigned long len = 0;
char buf[64];
len =(int)stat.cbInQue; //将缓冲区中的全部数据都取出
if (len<m_nbarCodeLen) //没有达到指定的数据长度则退出
{
return false;
}
if(!ReadFile(m_COMHandle, buf, len, &len, NULL)) //取数据失败
{
len = 0;
}
buf[len] = '\0';

使用以上代码从COM口获取数据,在非线程中调用时没有任何问题,但是在线程中调用失败,每次CLEARCOMMERROR时都出现错误16,MSDN的解释是CE_BREAK The hardware detected a break condition.
请问有大虾遇到过同样的问题没有?
...全文
301 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
一条晚起的虫 2006-04-17
  • 打赏
  • 举报
回复
mark,慢慢看
carefulman 2006-04-17
  • 打赏
  • 举报
回复
中午顶一下
carefulman 2006-04-17
  • 打赏
  • 举报
回复
试了下直接从COM口取数据,在COM口有数据输入时每次都是数据长度为38,COM口状态为16,获取的数据为混乱状态(线程中调用,调用时已经进行线程同步)
在非线程中调用正常
请各位帮帮忙看下什么地方有问题!
carefulman 2006-04-17
  • 打赏
  • 举报
回复
一气之下,贴出全部代码献丑了,请各位指点下,急得不行了
cpp文件
CSJYTScannerDLL::CSJYTScannerDLL()
{
//默认设置为:COM,9600,条码长度13
m_nComRate = 9600;
m_nCOM = 1;
m_nbarCodeLen=13;
m_COMHandle = INVALID_HANDLE_VALUE;
return;
}

bool CSJYTScannerDLL::OpenScanner(int nCOM,long nComRate)
{
//连接条码扫描仪
char szPort[10];
m_nCOM = nCOM;
m_nComRate = nComRate;
sprintf(szPort, "COM%d", nCOM);
m_COMHandle = CreateFile(szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == m_COMHandle)
{
return false;
}
//说明:关键在于初始化超时设置和设备控制设置
COMMTIMEOUTS CommtimeOuts;
memset((void*)&CommtimeOuts, 0, sizeof(CommtimeOuts));
CommtimeOuts.ReadIntervalTimeout = 0x10;
CommtimeOuts.ReadTotalTimeoutMultiplier = 1;
CommtimeOuts.ReadTotalTimeoutConstant = 1;
CommtimeOuts.WriteTotalTimeoutConstant = 1;
CommtimeOuts.WriteTotalTimeoutMultiplier = 1;//5000;
SetCommTimeouts(m_COMHandle, &CommtimeOuts);

DCB dcb;
memset((void*)&dcb, 0, sizeof(dcb));
GetCommState(m_COMHandle, &dcb);
dcb.BaudRate = m_nComRate;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.EofChar = 0;
dcb.ErrorChar = 0;
dcb.EvtChar = 0;
dcb.fErrorChar = 0;
dcb.XoffChar = 0x13;
dcb.XonChar = 0x11;
dcb.XonLim = 2048;
dcb.XoffLim = 512;
dcb.fBinary = TRUE;
//设置超时和设备控制设置
if (!SetCommState(m_COMHandle, &dcb)
|| !SetupComm(m_COMHandle, 64, 64))
{
CloseScanner();
}
//清除所有缓冲区
PurgeComm(m_COMHandle, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
return true;
}

bool CSJYTScannerDLL::CloseScanner()
{
//断开条码扫描仪连接
if (INVALID_HANDLE_VALUE == m_COMHandle)
{
return true;
}
PurgeComm(m_COMHandle, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
//关键在于关闭设备句柄
CloseHandle(m_COMHandle);
m_COMHandle = INVALID_HANDLE_VALUE;
return true;
}

bool CSJYTScannerDLL::GetBarCode(char * szBarCode)
{
//memset(szBarCode,0,255);
szBarCode[0] = '\0';

COMSTAT stat;
DWORD error;
unsigned long len = 0;
char buf[64];
//先获取COM口状态

if(ClearCommError(m_COMHandle, &error, &stat) && error > 0) //清除错误
{
//PurgeComm(m_COMHandle, PURGE_TXABORT | PURGE_TXCLEAR); //清除输入缓冲区
return false;
}
//ClearCommError(m_COMHandle, &error, &stat);


len =(int)stat.cbInQue; //将缓冲区中的全部数据都取出
if (len<m_nbarCodeLen) //没有达到指定的数据长度则退出
{
return false;
}

if(!ReadFile(m_COMHandle, buf, len, &len, NULL)) //取数据失败
{
len = 0;
}
buf[len] = '\0';
if (len<m_nbarCodeLen) //如果没有获取足够长的
{
return false;
}
//如果有足够长的数据则获取截取最新的一个条码长度
for (int nCount=0;nCount<m_nbarCodeLen;++nCount)
{
szBarCode[nCount]=buf[len-m_nbarCodeLen-1+nCount];
}
szBarCode[nCount]='\0';
return true;
}

bool CSJYTScannerDLL::ClearComData()
{
//清除可能存在的COM缓冲区数据
if (INVALID_HANDLE_VALUE == m_COMHandle)
{
return true;
}
PurgeComm(m_COMHandle, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
return true;
}

bool CSJYTScannerDLL::SetBarCodeLen(int len)
{
if (INVALID_HANDLE_VALUE == m_COMHandle)
{
return false;
}
m_nbarCodeLen=len;
return true;
}

///H文件
class SJYTSCANNERDLL_API CSJYTScannerDLL {
public:
CSJYTScannerDLL(void); //构造函数
bool OpenScanner(int nCOM,long nComRate); //连接扫描仪
bool CloseScanner(); //断开扫描仪
bool SetBarCodeLen(int len); //设置读取的条码长度
bool GetBarCode(char * szBarCode); //获取条码
bool ClearComData(); //清除条码仪的缓冲区数据
private:
int m_nCOM; //COM端口
long m_nComRate; //COM口速率
HANDLE m_COMHandle; //COM句柄
DCB dcb; //DCB
COMMTIMEOUTS commtimeouts; //超时设置
int m_nbarCodeLen; //条码长度

//CString m_szCOM;
// TODO: add your methods here.
};
kkw2006 2006-04-17
  • 打赏
  • 举报
回复
没有遇到过,建立楼主查查m_COMHandle。线程使用的指针啥的。。。。。
carefulman 2006-04-17
  • 打赏
  • 举报
回复
急,干着急
carefulman 2006-04-17
  • 打赏
  • 举报
回复
我在外面线程中调用时用了线程同步的,应该不会出现线程冲突
菜牛 2006-04-17
  • 打赏
  • 举报
回复
用到了多线程,尤其涉及到I/O读写的,一定要考虑多线程的同步问题。
pripor 2006-04-17
  • 打赏
  • 举报
回复
线程不安全,建议重看msdn祥解
carefulman 2006-04-17
  • 打赏
  • 举报
回复
我是封装在动态库中使用,莫非跟传说中线程安全有关系?
在线等待!!!!
Featured 2006-04-17
  • 打赏
  • 举报
回复
没有试过,帮你顶下
Featured 2006-04-17
  • 打赏
  • 举报
回复
非常遗憾没能帮上忙
楼主不妨公布下问题的原因。说不定可以上FAQ赚些信誉分
也可以给大家长长见识
Featured 2006-04-17
  • 打赏
  • 举报
回复
非常遗憾没能帮上忙
楼主不妨公布下问题的原因。说不定可以上FAQ赚些信誉分
也可以给大家长长见识
Featured 2006-04-17
  • 打赏
  • 举报
回复
非常遗憾没能帮上忙
楼主不妨公布下问题的原因。说不定可以上FAQ赚些信誉分
也可以给大家长长见识
carefulman 2006-04-17
  • 打赏
  • 举报
回复
问题终于解决了,无人问津,可怜啊
散分
carefulman 2006-04-17
  • 打赏
  • 举报
回复
救命呢,哪位大侠指点下啊
ririhaoma 2006-04-17
  • 打赏
  • 举报
回复

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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