第一幅图是我自己写的软件的串口流程;
这个流程是我自己的软件的流程;第二幅图是另一个比较成熟的软件的流程;都是用串口监视精灵进行检测的;
可以看到,在第一图中,高亮显示的部分,两次设置了波特率,但是值却改变了,导致我无法对下位机进行读取;
第二图则是在利用别人的软件打开过一次后,再利用我自己的软件进行读取之后的流程;
很明显的,波特率被改变了,而我现在无法找到是哪里的设置错误;
导致我每次在一个新的串口使用时,都得先用其他软件读取一次,将串口的数据进行设置,然后才可以用自己的软件进行读取,而不这样的话,就无法正确读取了。望各位路过的帮忙看看哪里的错误以下是comm口的打开函数BOOL CSerial::OpenComm(int nPort,LONG32 nPaud,char parity /* = */,
DWORD dwCommEvents /* = EV_RXCHAR */,UINT databits /* = 8 */, UINT stopbits /* = 1 */)
{
COMMTIMEOUTS tous;
DCB dcb;
CString strComm;
memset(&tous,0,sizeof(tous));
tous.ReadIntervalTimeout = MAXWORD;
tous.ReadTotalTimeoutMultiplier = 1000 ; tous.ReadTotalTimeoutConstant = 1000 ; tous.WriteTotalTimeoutMultiplier = 1000; tous.WriteTotalTimeoutConstant = 1000 ; if (nPort >=10)
{
strComm.Format(_T("\\\\.\\%d"),nPort);
}
else
strComm.Format(_T("COM%d"),nPort); m_hComm = CreateFile(strComm,GENERIC_READ|GENERIC_WRITE,0,
NULL,OPEN_EXISTING,0,NULL);
if (m_hComm!=INVALID_HANDLE_VALUE)
{
GetCommState(m_hComm,&dcb);
dcb.BaudRate = nPaud;
dcb.Parity = parity;
dcb.fOutxCtsFlow = dcb.fOutxDsrFlow = 0;
dcb.fOutX = dcb.fInX = 0;
dcb.fRtsControl = RTS_CONTROL_ENABLE;
dcb.fDtrControl = DTR_CONTROL_ENABLE; dcb.ByteSize = databits;
dcb.StopBits = stopbits; dcb.XonLim = 512;
dcb.XoffLim = 1; SetCommState(m_hComm,&dcb);
SetupComm(m_hComm,2048,2048);
SetCommTimeouts(m_hComm,&tous);
EscapeCommFunction(m_hComm,SETDTR);
EscapeCommFunction(m_hComm,SETRTS); // PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
m_nPaud = nPaud;
m_nPort = nPort;
return TRUE;
}
return FALSE;
{
strComm.Format(_T("\\\\.\\%d"),nPort);
}
else
strComm.Format(_T("COM%d"),nPort);我记得串口超过10也可以用COM10,COM11等来设置,你先去掉判断试试:
strComm.Format(_T("COM%d"),nPort);
tous.ReadTotalTimeoutMultiplier = 1000 ; tous.ReadTotalTimeoutConstant = 1000 ; tous.WriteTotalTimeoutMultiplier = 1000; tous.WriteTotalTimeoutConstant = 1000 ;
把这几个值设成再大些试试,1ms好象太小了(和波特率有关),比如60000
同时,DCB还有一个属性binary,这个是二进制传输,也要设上,并去掉下面几句,使用默认的值:
dcb.fOutxCtsFlow = dcb.fOutxDsrFlow = 0;
dcb.fOutX = dcb.fInX = 0;
dcb.fRtsControl = RTS_CONTROL_ENABLE;
dcb.fDtrControl = DTR_CONTROL_ENABLE;
dcb.XonLim = 512;
dcb.XoffLim = 1;
在代码中,是在
SetCommState
之后,被重复了,若是我的opencomm函数是在某个我不知道的地方也被调用的话,那也应该是整个被
调用,而不是在
SetCommState
之前的步骤进行重复;
还有关于
COMMTIMEOUTS tous;
这几个值得设置,一般来说,我上面的设置数值应该是够了,应该在第二幅图中,它是可以进行通讯的;但还是很感谢hdg3707提供的思路
只知道被什么地方给又设置了一次SetCommState,并且估计还是以默认值的形式进行设置的感谢 schlafenhamster 的捧场
呵呵,这个是我没说清楚。
下位机的串口波特率是已经固定好的了,这点应该不用担心,现在是,另外一个软件,虽然功能是相同的,但是是其他公司的软件,而我要发布给其他客户的话,肯定不能拿别人家的软件发给别人吧,于是就是让我来COPY这么一个功能软件,而原始的软件代码,我的手头有比较早期的版本,现行的版本虽然手头没有,但是以前也看过,关于串口的设置是没啥变化的。
下面这图是另一个软件打开串口时的流程下面是人家的opencomm函数
BOOL CSerial::OpenComm(int port, long baud)
{
COMMTIMEOUTS touts;
DCB dcb;
CString fileComName;
memset(&touts,0,sizeof(touts));
touts.ReadIntervalTimeout = MAXDWORD;
if(port>=10)
fileComName.Format("\\\\.\\COM%d",port);
else
fileComName.Format("COM%d",port);
m_hComm = CreateFile(fileComName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
if(m_hComm != INVALID_HANDLE_VALUE)
{
GetCommState(m_hComm,&dcb); dcb.BaudRate = baud;
dcb.Parity = NOPARITY;
dcb.fOutxCtsFlow= dcb.fOutxDsrFlow=0;
dcb.fOutX = dcb.fInX = 0;
dcb.fRtsControl = RTS_CONTROL_ENABLE; //RTS_CONTROL_DISABLE;
dcb.fDtrControl = DTR_CONTROL_ENABLE; //DTR_CONTROL_DISABLE;
dcb.ByteSize = 8;
dcb.StopBits = ONESTOPBIT;
SetCommState(m_hComm,&dcb); SetupComm(m_hComm,3600,3600);
SetCommTimeouts(m_hComm,&touts); EscapeCommFunction(m_hComm,SETDTR);
EscapeCommFunction(m_hComm,SETRTS); //set DTR & RTS high
// EscapeCommFunction(m_hComm,CLRDTR);
// EscapeCommFunction(m_hComm,CLRRTS);
return TRUE;
}
return FALSE;
}
那样的话要hook CreateFile(A,W) 在你的 SetupComm 中返回 波特率。
我的意思是,这两个软件,都是实现同样的功能,但是其中功能比较完善的,同时也是我要复制人家功能的那个软件,是有版权的,只提供给我们内部使用,所以不能对外发布啊;
而我自己写的这个,是属于我们公司的,用于发布给客户,版权是我们自己的;
这两个软件,都可以对同一个下位机进行操作,下位机的波特率是同样的,都是115200,不变的;
只是我写的软件,现在出现了这个问题,但是我的串口类基本上是照搬人家的,同样的情况下,却产生了我这种错误,这才是让我疑惑的地方
在以上的代码中,当执行到
SetCommState(m_hComm,&dcb);
时设置断点,串口设置就会如图1那样,设置了两次,而且第二次还会把我传入的数值进行改变,导致我无法通讯
SetCommState(m_hComm,&dcb);
GetCommState(m_hComm,&dcb); //新增发现确实再次获取到的DCB的值变化了,一个是波特率,还有一个是parity
这为啥啊
{
m_nPaud = nPaud;
m_nPort = nPort;
GetCommState(m_hComm,&dcb);// dcb.fBinary = 1; dcb.BaudRate = nPaud;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.ByteSize = 8; SetCommState(m_hComm,&dcb);
GetCommState(m_hComm,&dcb); SetupComm(m_hComm,2048,2048);
SetCommTimeouts(m_hComm,&tous); EscapeCommFunction(m_hComm,SETDTR);
EscapeCommFunction(m_hComm,SETRTS); // PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
return TRUE;
}