串口异步收发的有关问题
串口异步收发的问题
PC机和单片机通过串口通讯,PC机发送一个字符时,单片机会返回2个BYTE,手动点发送按纽
启动OnCommTXD时,PC机会收到数据,但自动调用WriteComm()函数时,却不能自动收到数据。
单片机没问题,收到一个字符,会立即发送数据。
------解决方案--------------------
自动调用的地方估计有问题
------解决方案--------------------
串口线程调用WriteFile,一个字符瞬间发出,之后串口线程再调用WaitCommEvent,此时EV_TXEMPTY已经丢失了,你的m_bTX永远成不了真.
不用太严谨,发送一般不会出问题.EV_TXEMPTY只会把程序搞得更复杂,不用管它.
PC机和单片机通过串口通讯,PC机发送一个字符时,单片机会返回2个BYTE,手动点发送按纽
启动OnCommTXD时,PC机会收到数据,但自动调用WriteComm()函数时,却不能自动收到数据。
单片机没问题,收到一个字符,会立即发送数据。
DWORD WINAPI CC51Dlg::CommThread(LPVOID lpParam)
{
CC51Dlg* dlg = (CC51Dlg*)lpParam;
::SetCommMask(dlg->m_hCom, 0x05FF);
DWORD dwReadBytes = 0;
OVERLAPPED ol = {0};
ol.hEvent = CreateEvent(NULL,TRUE,TRUE,NULL);
DWORD dwEventMask = 0;
while(1)
{
::WaitCommEvent(dlg->m_hCom, &dwEventMask, &ol);
if (::WaitForSingleObject(ol.hEvent, INFINITE) == 0)
{
if (::GetOverlappedResult(dlg->m_hCom, &ol, &dwReadBytes, FALSE))
{
if (dwEventMask & EV_TXEMPTY)
{
dlg->m_bTX = TRUE;
}
if (dlg->m_bTX && (dwEventMask & EV_RXCHAR))
{
dlg->ReadComm();
}
}
}
}
return 1;
}
BOOL CC51Dlg::WriteComm(char *pBuf, int nBytes)
{
OVERLAPPED ol = {0};
HANDLE hEvent = CreateEvent(NULL,TRUE,TRUE,NULL);
ol.hEvent = hEvent;
DWORD dwNumberOfWritten = 0;
::WriteFile(m_hCom, pBuf, nBytes, &dwNumberOfWritten, &ol);
if (!::WriteFile(m_hCom, pBuf, nBytes, &dwNumberOfWritten, &ol))
{
if (::WaitForSingleObject(hEvent, INFINITE) == 0)
{
if (::GetOverlappedResult(m_hCom, &ol, &dwNumberOfWritten, FALSE))
{
m_bTX = FALSE;
}
}
}
m_bTX = FALSE;/**/
::CloseHandle(hEvent);
return TRUE;
}
void CC51Dlg::OnCommTXD()
{
char str[8] = {0};
::GetDlgItemText(m_hWnd, IDC_TXD, str, sizeof(str));
WriteComm(str, 1);
}
BOOL CC51Dlg::ReadComm()
{
OVERLAPPED ol = {0};
HANDLE hEvent = CreateEvent(NULL,TRUE,TRUE,NULL);
ol.hEvent = hEvent;
DWORD dwNumberOfReaded = 0;
WORD wBuf = 0;
if (!::ReadFile(m_hCom, &wBuf, 2, &dwNumberOfReaded, &ol))
{
if (::WaitForSingleObject(hEvent, INFINITE) == 0)
{
if (::GetOverlappedResult(m_hCom, &ol, &dwNumberOfReaded, FALSE))
{
float fVoltage = 5 * (float)wBuf / 1024;
char str[8] = {0};
sprintf(str, "%0.2f", fVoltage);
::SetDlgItemText(m_hWnd, IDC_VOLTAGE, str);
char buf = 'A';
WriteComm(&buf, 1);//这句好象不起作用
}
}
}
::CloseHandle(hEvent);
return TRUE;
}
------解决方案--------------------
自动调用的地方估计有问题
------解决方案--------------------
串口线程调用WriteFile,一个字符瞬间发出,之后串口线程再调用WaitCommEvent,此时EV_TXEMPTY已经丢失了,你的m_bTX永远成不了真.
不用太严谨,发送一般不会出问题.EV_TXEMPTY只会把程序搞得更复杂,不用管它.