在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);
我做过称重用的仪表通信。不过我用的是VFP加MSCOMM控件,效果很好。你也试试?
我用vc api效果也不错呀,而且com1,com2区别不大。
不知你是什么原因,帮你up
#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上会快
但不应出现向你说的现象,或许是你的设定有问题,参考以上
流控制?
我给你一个回答:
非重叠操作在win2000系统下是不行的,你到Win98\winme下试一下。
有些使用Delphi的控件的在win2000下也有不稳定的现象。如:
http://emouze.com的comdebug
gz
我最近也在做这类的串口通讯的问题,应该是COM1与COM2没有什么区别的,所以应该不会是软件本身编写的问题。有可以是硬件,或者是BIOS的问题。
我在XP下写的程序与你类似,互换COM也没有任何问题,建议你用如wizport之类的专门进行串口测试与调试软件测试一下口的问题。
好象串口与RS232是一个东西的两个方面。