计算机的com1,com2口有差别吗?同样的程序为什么相差那么远。

xqls 2002-06-17 07:01:58
在windwos 2000系统下。

通过计算机的com口与称重用的仪表通信,读取仪表的数据。
在com1口完全正常,怎么折腾都没关系,而换在com2口时,
如果仪表是刚上电的,则可以正常读取一次,以后都不能
正常读取了。如果在把仪表断电重新上电,又可以读取一次,
为什么会这样?

程序只是在createfile()函数中的第一个参数"com1"改成
"com2",其他完全一样。又因为仪表断一次电就可以读取一
次,可见连线应该也没问题。会是什么原因呢?把可能或者
也许有一点点可能性的改进都提出来吧。谢谢!

仪表的通信是RS232协议,只有三条线联接,发送接受和地线
在windows里面没有用流控,不知道程序如何设置不用流控?

下面是程序,用最简单的通信方式:非重叠操作,查询方式,
即往com口写数据后用sleep()延时,然后就一个字符一个字符
的循环读取,直到读取到完整的以<stx>开头,以<cr>结尾的
数据。几乎把所有可能用到的函数都用上了。

DCB Dcb={0};
COMMTIMEOUTS CommTimeOuts;
BOOL fSuccess;
LPDWORD lpErrors;
HANDLE hCom;
//------以下代码是打开端口并且进行初始化的操作---------
hCom=INVALID_HANDLE_VALUE;
hCom=CreateFile("COM2",GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if(hCom==INVALID_HANDLE_VALUE)
{
CloseHandle(hCom);
AfxMessageBox("Open port failure!");
return;
}

//setup the input and output buffer
if(!SetupComm(hCom,1024,1024))
{

CloseHandle(hCom);
AfxMessageBox("Set buffer failure!");
return;
}

if(!PurgeComm(hCom,PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR))
{
CloseHandle(hCom);
AfxMessageBox("Clear buffer failure!");
return;
}

lpErrors = 0;
if(!ClearCommError(hCom,lpErrors,NULL))
{
CloseHandle(hCom);
AfxMessageBox("Clear Error flag failure!");
return;
}

fSuccess = GetCommState(hCom,&Dcb);
if(!fSuccess)
{
CloseHandle(hCom);
AfxMessageBox("Get Dcb failure!");
return;
}

Dcb.BaudRate=9600;
Dcb.ByteSize=8;
Dcb.Parity =NOPARITY;
Dcb.StopBits=ONESTOPBIT;
Dcb.fBinary = 1;
Dcb.fParity=0;

fSuccess = SetCommState(hCom,&Dcb);
if(!fSuccess)
{
CloseHandle(hCom);
AfxMessageBox("Set Dcb failure!");
return;
}

CommTimeOuts.ReadIntervalTimeout=MAXWORD;
CommTimeOuts.ReadTotalTimeoutMultiplier =0;
CommTimeOuts.ReadTotalTimeoutConstant =60;
CommTimeOuts.WriteTotalTimeoutMultiplier=0;
CommTimeOuts.WriteTotalTimeoutConstant =60;
if(!SetCommTimeouts(hCom,&CommTimeOuts))
{
CloseHandle(hCom);
AfxMessageBox("Set TimeOuts failure!");
return;
}
//----------下面是往仪表发送命令及读取仪表发回的数据------------------------------
char szOrder[5]; //buffer of char will be send to device
char szReceive; //one byte buffer for receive data from comm
DWORD dwSize; //size of szOrder[]
CString sTemp; //strTmp record all chars received from device
int i;
bool flag;

fSuccess =false;
// order : <STX>2UB<CR>,发往仪表的命令
szOrder[0]=0x02;
szOrder[1]=0x32;
szOrder[2]=0x55;
szOrder[3]=0x42;
szOrder[4]=0x0D;
dwSize = 5;


//send command to device
fSuccess=WriteFile(hCom,szOrder,dwSize,&dwSize,NULL);
if(!fSuccess)
{
CloseHandle(hCom);
AfxMessageBox("Send data to port failure!");
return;
}

Sleep(2300);
//--A是想看看有什么错误标志位,但结果都是0----------------------------------
lpErrors = 0;
DWORD A;
A =0;
A = GetLastError();
if(!ClearCommError(hCom,lpErrors,NULL))
{
CloseHandle(hCom);
AfxMessageBox("Clear Error flag failure!");
return;
}


//read all datas from maximize to about 1 records.
flag=true;
i=0;
//---循环读取,知道找到起始符<stx>即0x02符号。
while(flag)
{
dwSize=1;
fSuccess=ReadFile(hCom,&szReceive,dwSize,&dwSize,NULL);
A = GetLastError();
if (!fSuccess)
{
AfxMessageBox("Read data from port failure!");
CloseHandle(hCom);
return;
}
if(szReceive==0x02)
{
flag=false;
}
if(i>50)
{
CloseHandle(hCom);
hCom=INVALID_HANDLE_VALUE;
AfxMessageBox("Read data from port failure,I>100!");
return;
}
i++;
}
//----以下是取得数据

sTemp = "";
for(i=0;i<9;i++)
{
dwSize=1;
fSuccess=ReadFile(hCom,&szReceive,dwSize,&dwSize,NULL);
if (!fSuccess)
{
CloseHandle(hCom);
AfxMessageBox("Read data from port failure!");
return;
}
sTemp+=szReceive;
}
//---------------下面是处理数据
sTemp = sTemp.Right(6);
m_sdata = sTemp;
UpdateData(FALSE);
AfxMessageBox("finish");
CloseHandle(hCom);
...全文
2055 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
zf925 2002-06-19
  • 打赏
  • 举报
回复
应该问题不大,建议你换换系统到别人机器上试试

肯定不是什么大问题,当年我的程序在98下很好,但2000下不行,
整整调了一个星期,才知道是打开串口时设定有问题,多想想办法,
你定能调出来!

祝你成功!
zf925 2002-06-19
  • 打赏
  • 举报
回复
我的函数

void CSendDataDlg::CloseConnection()
{
if(!m_bConnected)
{
return;
}
m_bConnected = FALSE;
CloseHandle(m_hCom);
}
xiaofish 2002-06-19
  • 打赏
  • 举报
回复
我也曾经有过这个方面的开发经验,也有过类似的问题:

最关键的问题是因为COM PORT不是热插拔的, 你没有必要在程序部分区任何的改动, 你可以跟别人解释说,COM PORT不是热插拔的,她的连接也不是简单的软件部分的连接,其中还包括种种的初始化,等方面的问题,你如果是USB就不会有这个方面的问题。

leeseon 2002-06-19
  • 打赏
  • 举报
回复
我最近也在做这类的串口通讯的问题,应该是COM1与COM2没有什么区别的,所以应该不会是软件本身编写的问题。有可以是硬件,或者是BIOS的问题。

我在XP下写的程序与你类似,互换COM也没有任何问题,建议你用如wizport之类的专门进行串口测试与调试软件测试一下口的问题。

好象串口与RS232是一个东西的两个方面。
xqls 2002-06-19
  • 打赏
  • 举报
回复
to: zj_zyq(飞鸽)

非重叠操作在win2000系统下不行的话为什么com1口没问题呢?com1读写完全正常。因为他们所有的机器2000,也不可能安装98等来用,所以没办法试。:(

to : zf925(天下哪来那么多高手)
你是哪里打开设置有问题?可否记得,我也来试试。我把com1,com2在运行时的
dcb核对一遍,完全相同,什么都不设置,只在控制面板中设置com口,结果仍然是com1可以com2不行。
PC机是:IBM M/I 6578-kcc
这种机型的两个串口都是用RS232协议的吗?
谢谢!
bljbljbljblj 2002-06-19
  • 打赏
  • 举报
回复
gz
zj_zyq 2002-06-19
  • 打赏
  • 举报
回复
我给你一个回答:

非重叠操作在win2000系统下是不行的,你到Win98\winme下试一下。

有些使用Delphi的控件的在win2000下也有不稳定的现象。如:

http://emouze.com的comdebug
xqls 2002-06-19
  • 打赏
  • 举报
回复
吐血,搞定,开心,结贴
方法:保持端口打开,重复读写两次。
要点:保持端口打开。
前两天重复读试过,但每次都是打开,读写,不成功,关闭,在打开读写,所以仍然不行。现在保持打开就开以了。只有com2需要这样。
xqls 2002-06-18
  • 打赏
  • 举报
回复
今天忙了一天也没解决问题。:(((
to: zf925(天下哪来那么多高手)
CloseConnection();这个函数是自己编的吗?怎么没参数。用来干什么的。
用CloseHandle(hCom);关闭com口有没问题?
还有什么特别的地方吗,比如其他软件冲突等。
我修改了com2的地址,中断号什么的,都没用。
谢谢!
xqls 2002-06-17
  • 打赏
  • 举报
回复
先多谢各位热心帮助。
因为只用3条线,所以不存在硬件流控(没有控制线)
软件流控也没有,因为不发送,接受xon/xoff之类的控制字符。
而且现在是com1用得很正常。刚听人说IBM PC的com2口确实有问题,听说要在bios中设置什么,一说是缓存,一说是与红外设备冲突,明天试试才知道是不是,如果不是在根据各位的方法改进读数程序。感觉com1没事,跟程序应该没什么关系。要知道只是createfile中的com1改成com2 而已啊。
谢谢各位。
zenyivon 2002-06-17
  • 打赏
  • 举报
回复
流控制?
zf925 2002-06-17
  • 打赏
  • 举报
回复
不要用sleep延时,用


#define MAXOUTTIME 190000
inline BOOL CSendDataDlg::WaitDataAdvent()
{
for(long i=0; i<MAXOUTTIME; i++)
{
ClearCommError(m_hCom, &m_dwErrorFlags, &m_cComStat);
if(m_cComStat.cbInQue) //检测到信号
{
ReadComm(ReceiveChar, 1); //读回来
SetupComm(m_hCom, 2, 2);
return TRUE;
}
}

CloseConnection();
return FALSE; //出错
}
zf925 2002-06-17
  • 打赏
  • 举报
回复



#define MAXBLOCK 2048
#define XON 0x11
#define XOFF 0x13


DCB dcb;

if(!GetCommState(m_hCom, &dcb))
{
return FALSE;
}

dcb.fBinary = TRUE;
dcb.BaudRate = Baud; // 波特率
dcb.ByteSize = 8; // 每字节位数
dcb.fParity = TRUE;
dcb.Parity = EVENPARITY; // 校验设置
dcb.StopBits = ONESTOPBIT; // 停止位

// 硬件流控制设置
dcb.fOutxCtsFlow = FALSE;
dcb.fRtsControl = RTS_CONTROL_ENABLE;

// XON/XOFF流控制设置
dcb.fInX = dcb.fOutX = FALSE;
dcb.XonChar = XON;
dcb.XoffChar = XOFF;
dcb.XonLim = 50;
dcb.XoffLim = 50;
return SetCommState(m_hCom, &dcb);

com2比com1中断优先级高,所以modem等设备插在com2上会快

但不应出现向你说的现象,或许是你的设定有问题,参考以上
nuaawyd 2002-06-17
  • 打赏
  • 举报
回复
我用vc api效果也不错呀,而且com1,com2区别不大。
不知你是什么原因,帮你up
liqi 2002-06-17
  • 打赏
  • 举报
回复
我做过称重用的仪表通信。不过我用的是VFP加MSCOMM控件,效果很好。你也试试?

16,472

社区成员

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

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

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