串口碰到的怪问题!请大虾门看看!

txhby0395 2003-10-18 12:14:51
我的程序有两个问题1、可以发送数据,但接收数据有问题。2、设置串口也会出现问题,无法设置成功!
代码在:http://www.vchelp.net/cndevforum/subject_view.asp?subject_id=56482&forum_id=34
...全文
95 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
txhby0395 2003-10-20
  • 打赏
  • 举报
回复
我的问题已经解决了
txhby0395 2003-10-18
  • 打赏
  • 举报
回复
谢谢huanyun(无妻徒刑) ,你的代码我已经收录了.但我还是希望大侠们看看我的程序什么地方有问题,给我指正一下!!!!!!!!
huanyun 2003-10-18
  • 打赏
  • 举报
回复
void CCommCtrl::ReceiveChar(CCommCtrl *pSerialComm, COMSTAT &comstat)
{
BOOL bRead = TRUE;
BOOL bResult = TRUE;
DWORD dwError = 0;
DWORD BytesRead = 0;
DWORD BytesReadCount = 0;
BOOL bXOFF = FALSE;
int dwReadLen = 0;
unsigned char RXBuff[RX_BUFFER_SIZE];

while(1)
{
if(pSerialComm->m_deqbuff.isdata() > 1024)
{
if(dwReadLen != RX_BUFFER_SIZE)
{
dwReadLen = RX_BUFFER_SIZE;
}
}
else
dwReadLen = 1;
//临界区
EnterCriticalSection(&pSerialComm->m_CriticalSection);
bResult = ClearCommError(pSerialComm->m_hComm, &dwError, &comstat);
LeaveCriticalSection(&pSerialComm->m_CriticalSection);

if (comstat.cbInQue == 0) break; //读取完成

//临界区
EnterCriticalSection(&pSerialComm->m_CriticalSection);
if (bRead)
{
//读取接收到的数据
bResult = ReadFile(pSerialComm->m_hComm, // Handle to COMM port
RXBuff, // RX Buffer Pointer
dwReadLen, // Read one byte
&BytesRead, // Stores number of bytes read
&pSerialComm->m_Overlapped); // pointer to the m_ov structure
//读取发生错误
if (!bResult)
{
switch (dwError = GetLastError())
{
case ERROR_IO_PENDING: //异步I/O处理未完成
{
bRead = FALSE;
break;
}
default://其他类型的错误
{
pSerialComm->ProcessErrorMessage("ReadFile()");
break;
}
}
}
}
if (!bRead)
{
bRead = TRUE;
//获取交迭操作的起因
bResult = GetOverlappedResult(pSerialComm->m_hComm, // Handle to COMM port
&pSerialComm->m_Overlapped, // Overlapped structure
&BytesRead, // Stores number of bytes read
TRUE); // Wait flag

//读取发生错误
if (!bResult)
{
pSerialComm->ProcessErrorMessage("GetOverlappedResults() in ReadFile()");
//出临界区
LeaveCriticalSection(&pSerialComm->m_CriticalSection);
return ;
}
}

//出临界区
LeaveCriticalSection(&pSerialComm->m_CriticalSection);
if (BytesRead<=0) continue ; ////&&&&&&&&&&没有数据
BytesReadCount += BytesRead;
if(BytesReadCount > 512)
{
::PostMessage(pSerialComm->m_hWnd, WM_STATE_CHANGE, pSerialComm->m_bIsBP?REFLASH_BPDATA:REFLASH_MAINDATA, BytesRead);
BytesReadCount = 0;
}

for(int j=0;j<(int)BytesRead;j++)
{
// 如果收到XON/XOFF,转换发送标志
if (!TranByte(pSerialComm,RXBuff[j])) continue; //// 2002.2.12
// 获取数据
pSerialComm->m_deqbuff.push((char *)(RXBuff+j),1);
if(pSerialComm->m_deqbuff.isfull() && pSerialComm->m_bRcvFlag)
{
::TransmitCommChar(pSerialComm->m_hComm, XOFF);
pSerialComm->m_bRcvFlag = FALSE;
::PostMessage(pSerialComm->m_hWnd, WM_STATE_CHANGE, 0, 0);
}
}

if(pSerialComm->m_bSave)
{
FILE * fp;
if ((fp = fopen("COM_in.txt", "a+b"))!=NULL) {fwrite((char *)RXBuff, 1, BytesRead, fp); fclose(fp);}
}
}
if(BytesReadCount > 0)::PostMessage(pSerialComm->m_hWnd, WM_STATE_CHANGE, pSerialComm->m_bIsBP?REFLASH_BPDATA:REFLASH_MAINDATA, BytesRead);
}
huanyun 2003-10-18
  • 打赏
  • 举报
回复
void CCommCtrl::WriteChar(CCommCtrl *pSerialComm, char *pBuffer, DWORD dwCount)
{
char* pWriteBuffer;
pWriteBuffer = pBuffer;
BOOL bWrite = TRUE;
BOOL bResult = TRUE;
DWORD BytesSent = 0;

//进入临界区
EnterCriticalSection(&pSerialComm->m_CriticalSection);
if (bWrite)
{
pSerialComm->m_Overlapped.Offset = 0;
pSerialComm->m_Overlapped.OffsetHigh = 0;
//输出数据到端口
bResult = WriteFile(pSerialComm->m_hComm, // Handle to COMM Port
pWriteBuffer, // Pointer to message buffer in calling finction
dwCount, // Length of message to send
&BytesSent, // Where to store the number of bytes sent
&pSerialComm->m_Overlapped); // Overlapped structure

//发生错误
if (!bResult)
{
DWORD dwError = GetLastError();
switch (dwError)
{
case ERROR_IO_PENDING://异步I/O处理未完成
{
BytesSent = 0;
bWrite = FALSE;
break;
}
default://其他错误
pSerialComm->ProcessErrorMessage("WriteFile()");
}
}
else//出临界区
LeaveCriticalSection(&pSerialComm->m_CriticalSection);
}

if (!bWrite)
{
bWrite = TRUE;
bResult = GetOverlappedResult(pSerialComm->m_hComm, // Handle to COMM port
&pSerialComm->m_Overlapped, // Overlapped structure
&BytesSent, // Stores number of bytes sent
TRUE); // Wait flag

LeaveCriticalSection(&pSerialComm->m_CriticalSection);

//发生错误
if (!bResult)
{
pSerialComm->ProcessErrorMessage("GetOverlappedResults() in WriteFile()");
}
}

//根据发送数据的字节数判断发送是否成功完成
if (BytesSent != dwCount)
{
TRACE("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, dwCount);
}
}
huanyun 2003-10-18
  • 打赏
  • 举报
回复
在读写操作需要加入临界区
给你我的代码的一部分

BOOL CCommCtrl::Connect()
{
BOOL bResult = FALSE;
m_bRcvFlag = TRUE;
m_bSndFlag = TRUE;
// m_bXState = TRUE;
char szPort[50];
char szBaud[50];
memset(szPort, 0, sizeof(szPort));
memset(szBaud, 0, sizeof(szBaud));
//如果端口已经连接, 设置信号量断开连接
if (m_bThreadAlive)
{
while (m_bThreadAlive)
{
SetEvent(m_hShutdownEvent);
}
TRACE("Thread ended\n");
}


if(!InitEvent()) return FALSE;

//初始化临界区
InitializeCriticalSection(&m_CriticalSection);
//进入临界区
EnterCriticalSection(&m_CriticalSection);
if (m_hComm != NULL)
{
CloseHandle(m_hComm);
m_hComm = NULL;
}
m_bRcvFlag=m_bSndFlag=TRUE;
//端口设置字符串
sprintf(szPort, "COM%d", m_nPort);//端口号
//波特率, 奇偶效验, 数据位, 停止位
sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d", m_nBaud, m_cParity, m_nDatabits, m_nStopbits);

//建立并获取端口句柄
m_hComm = CreateFile(szPort, // communication port string (COMX)
GENERIC_READ | GENERIC_WRITE, // read/write types
0, // comm devices must be opened with exclusive access
NULL, // no security attributes
OPEN_EXISTING, // comm devices must use OPEN_EXISTING
FILE_FLAG_OVERLAPPED, // Async I/O
0); // template must be 0 for comm devices

if (m_hComm == INVALID_HANDLE_VALUE) return FALSE;

//设置超时延迟
m_CommTimeOuts.ReadIntervalTimeout = READINTERVALTIMEOUT;
m_CommTimeOuts.ReadTotalTimeoutMultiplier = READTOTALTIMEOUTMULTIPLIER;
m_CommTimeOuts.ReadTotalTimeoutConstant = READTOTALTIMEOUTCONSTANT;
m_CommTimeOuts.WriteTotalTimeoutMultiplier = WRITETOTALTIMEOUTMULTIPLIER;
m_CommTimeOuts.WriteTotalTimeoutConstant = WRITETOTALTIMEOUTCONSTANT;

//初始化端口缓冲区
SetupComm(m_hComm,COMBUFLEN,COMBUFLEN);

//设置超时延迟
if (SetCommTimeouts(m_hComm, &m_CommTimeOuts))
{
//指定启动事件
if (SetCommMask(m_hComm, m_dwCommEvents))
{
//获取端口状态
if (GetCommState(m_hComm, &m_DCB))
{
m_DCB.fRtsControl = RTS_CONTROL_ENABLE; // set RTS bit high!

//不进行流控制
m_DCB.fOutX = 0; //XON/XOFF Disable
m_DCB.fInX = 0; //XON/XOFF Disable

m_DCB.XonChar = XON ;
m_DCB.XoffChar = XOFF ;
//设置缓冲区
m_DCB.XonLim = (unsigned short)(COMBUFLEN*0.75);
m_DCB.XoffLim = (unsigned short)(COMBUFLEN*0.75);

//根据参数填充配置
if (BuildCommDCB(szBaud, &m_DCB))
{
//设置端口状态
if (!SetCommState(m_hComm, &m_DCB)) ProcessErrorMessage("SetCommState()");
}
else
ProcessErrorMessage("BuildCommDCB()");
}
else
ProcessErrorMessage("GetCommState()");
}
else
ProcessErrorMessage("SetCommMask()");
}
else
ProcessErrorMessage("SetCommTimeouts()");

//刷新端口
PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
//退出临界区
LeaveCriticalSection(&m_CriticalSection);
TRACE("Initialisation For Communicationport %d Completed.\nUse Startmonitor To Communicate.\n", m_nPort);

m_bIsOpen = TRUE;
//开始监视端口
StartMonitoring();
}
txhby0395 2003-10-18
  • 打赏
  • 举报
回复
up!

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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