如何检测串口 的 DSR 引脚或 DTR 的电平变化?

时间:2021-11-13 10:18:10
我是这么理解的:

 SetCommMask 设置一个串口事件
 GetCommMask 来获取一个事件的发生



SetCommMask(hCom, EV_DSR);
GetCommMask(hCom, &dwEvtMask);
if(dwEvtMask & EV_DSR) 
{
     // DSR 电平发生了跳变!
}


但是这样是不行的

请问:如何 知道 DSR 或 DTR 的电平跳变了,求给点代码提示,谢谢了!

16 个解决方案

#1


SetCommMask(hCom, EV_DSR);

WaitCommEvent(hCom, &dwEvtMask, &OverLapped);
if( dwEvtMask & EV_DSR )
{
    //DSR 发生跳变了!
}

#2


如何检测串口 的 DSR 引脚或 DTR 的电平变化?
求帮助,求指导……

#3


SetCommMask(hCom, EV_DSR);
GetCommMask(hCom, &dwEvtMask);
if(dwEvtMask & EV_DSR) 
{
     // DSR 电平发生了跳变!
}

WaitCommEvent(hCom, &dwEvtMask, &OverLapped);  执行一次就不执行了,DTR远还没有出线就挂了,

太简单了,必须弄一个阻塞线程来等待这个信号量,接受消息就必须在窗口下面,所有的消息都是发往窗口的,在窗口下拦截这个消息,这个就不会占CPU, 0% 因为windows太快了,

如果你用单片机的方式
while(1)
{
    WaitCommEvent(hCom, &dwEvtMask, &OverLapped);  也可以,那windows啥也不干就等信号量
}

#4


98年老外VC下有个CSerialPort类封装,很好的解决这个问题,具体看《串口通讯XX》,VC下将该类加到你的窗口,两三句就解决问题了,我试过,用该类,开10个串口57600高速读写,CPU占用率最多2%,用了N年很稳定,,不要考虑自己弄了,有现在很好用

#5


专门一个线程:

// an work thread to monitor the _CTS and RX_CHAR 
UINT CUload::CommWatchRead(LPVOID lpParam)
{   // return 0=OK 1=Error
    CUload     *pUload=(CUload*)lpParam;
OVERLAPPED os;
DWORD dwEventMask,dwTransfer;

memset(&os,0,sizeof(OVERLAPPED));
os.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);// attrb,Manual,init,name
if (os.hEvent==NULL)
{
AfxMessageBox("Can't create Event",MB_ICONSTOP);
return 1;// error
}
// set 2 events !
    if (!SetCommMask(pUload->m_idComDev,EV_RXCHAR|EV_CTS)) return 1;
    while (pUload->m_bConnected)
{ // break,only if m_bConnected=NULL 
dwEventMask=0;
        if(!WaitCommEvent(pUload->m_idComDev,&dwEventMask,&os))
{ // function fails
if (GetLastError()==ERROR_IO_PENDING)
{// TRUE=WaitForSingleObject() should be called inside
                GetOverlappedResult(pUload->m_idComDev,&os,&dwTransfer,TRUE);
os.Offset+=dwTransfer;
}
}
if((dwEventMask & EV_RXCHAR)==EV_RXCHAR)
{ // some chats received.
             ResetEvent(pUload->m_hPostEventRead);// first reset 
             pUload->PostMessage(WM_COMMNOTIFY,
                 (WPARAM)1,   // EV_RXCHAR
                                 (LPARAM)0);  // not used
// wait answer
             WaitForSingleObject(pUload->m_hPostEventRead,0xFFFFFFFF);
}
// if not at same time,use else if
if((dwEventMask & EV_CTS)==EV_CTS)
{  // CTS changed
ResetEvent(pUload->m_hPostEventRead);// first reset 
            pUload->PostMessage(WM_COMMNOTIFY,
                 (WPARAM)0,   // EV_CTS
                                 (LPARAM)0);  // not used
// wait answer
             WaitForSingleObject(pUload->m_hPostEventRead,0xFFFFFFFF);
}
}
CloseHandle(os.hEvent);
return 0;// OK
}

#6


引用 4 楼 vc8fans 的回复:
98年老外VC下有个CSerialPort类封装,很好的解决这个问题,具体看《串口通讯XX》,VC下将该类加到你的窗口,两三句就解决问题了,我试过,用该类,开10个串口57600高速读写,CPU占用率最多2%,用了N年很稳定,,不要考虑自己弄了,有现在很好用


非常感谢帮我解答疑惑

#7


// Events
//
线程可以监视 DSR:

#define EV_RXCHAR           0x0001  // Any Character received
#define EV_RXFLAG           0x0002  // Received certain character
#define EV_TXEMPTY          0x0004  // Transmitt Queue Empty
#define EV_CTS              0x0008  // CTS changed state
#define EV_DSR              0x0010  // DSR changed state
#define EV_RLSD             0x0020  // RLSD changed state
#define EV_BREAK            0x0040  // BREAK received
#define EV_ERR              0x0080  // Line status error occurred
#define EV_RING             0x0100  // Ring signal detected
#define EV_PERR             0x0200  // Printer error occured
#define EV_RX80FULL         0x0400  // Receive buffer is 80 percent full
#define EV_EVENT1           0x0800  // Provider specific event 1
#define EV_EVENT2           0x1000  // Provider specific event 2

#8


引用 5 楼 schlafenhamster 的回复:
专门一个线程:

// an work thread to monitor the _CTS and RX_CHAR 
UINT CUload::CommWatchRead(LPVOID lpParam)
{   // return 0=OK 1=Error
    CUload     *pUload=(CUload*)lpParam;
OVERLAPPED os;
DWORD dwEventMask,dwTransfer;

memset(&os,0,sizeof(OVERLAPPED));
os.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);// attrb,Manual,init,name
if (os.hEvent==NULL)
{
AfxMessageBox("Can't create Event",MB_ICONSTOP);
return 1;// error
}
// set 2 events !
    if (!SetCommMask(pUload->m_idComDev,EV_RXCHAR|EV_CTS)) return 1;
    while (pUload->m_bConnected)
{ // break,only if m_bConnected=NULL 
dwEventMask=0;
        if(!WaitCommEvent(pUload->m_idComDev,&dwEventMask,&os))
{ // function fails
if (GetLastError()==ERROR_IO_PENDING)
{// TRUE=WaitForSingleObject() should be called inside
                GetOverlappedResult(pUload->m_idComDev,&os,&dwTransfer,TRUE);
os.Offset+=dwTransfer;
}
}
if((dwEventMask & EV_RXCHAR)==EV_RXCHAR)
{ // some chats received.
             ResetEvent(pUload->m_hPostEventRead);// first reset 
             pUload->PostMessage(WM_COMMNOTIFY,
                 (WPARAM)1,   // EV_RXCHAR
                                 (LPARAM)0);  // not used
// wait answer
             WaitForSingleObject(pUload->m_hPostEventRead,0xFFFFFFFF);
}
// if not at same time,use else if
if((dwEventMask & EV_CTS)==EV_CTS)
{  // CTS changed
ResetEvent(pUload->m_hPostEventRead);// first reset 
            pUload->PostMessage(WM_COMMNOTIFY,
                 (WPARAM)0,   // EV_CTS
                                 (LPARAM)0);  // not used
// wait answer
             WaitForSingleObject(pUload->m_hPostEventRead,0xFFFFFFFF);
}
}
CloseHandle(os.hEvent);
return 0;// OK
}


你上面的代码就是这么个意思:

hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
SetCommMask(hCom, EV_CTS);

while(true)
{
  WaitForSingleObject(hEvent, INFINIT);
  if(dwEventMask & EV_CTS)
  {
    RsetEvent(hEvent);
    // CTS 跳变了!!
  }
}


对吗

#9


引用 8 楼 u011642451 的回复:
Quote: 引用 5 楼 schlafenhamster 的回复:

专门一个线程:

// an work thread to monitor the _CTS and RX_CHAR 
UINT CUload::CommWatchRead(LPVOID lpParam)
{   // return 0=OK 1=Error
    CUload     *pUload=(CUload*)lpParam;
OVERLAPPED os;
DWORD dwEventMask,dwTransfer;

memset(&os,0,sizeof(OVERLAPPED));
os.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);// attrb,Manual,init,name
if (os.hEvent==NULL)
{
AfxMessageBox("Can't create Event",MB_ICONSTOP);
return 1;// error
}
// set 2 events !
    if (!SetCommMask(pUload->m_idComDev,EV_RXCHAR|EV_CTS)) return 1;
    while (pUload->m_bConnected)
{ // break,only if m_bConnected=NULL 
dwEventMask=0;
        if(!WaitCommEvent(pUload->m_idComDev,&dwEventMask,&os))
{ // function fails
if (GetLastError()==ERROR_IO_PENDING)
{// TRUE=WaitForSingleObject() should be called inside
                GetOverlappedResult(pUload->m_idComDev,&os,&dwTransfer,TRUE);
os.Offset+=dwTransfer;
}
}
if((dwEventMask & EV_RXCHAR)==EV_RXCHAR)
{ // some chats received.
             ResetEvent(pUload->m_hPostEventRead);// first reset 
             pUload->PostMessage(WM_COMMNOTIFY,
                 (WPARAM)1,   // EV_RXCHAR
                                 (LPARAM)0);  // not used
// wait answer
             WaitForSingleObject(pUload->m_hPostEventRead,0xFFFFFFFF);
}
// if not at same time,use else if
if((dwEventMask & EV_CTS)==EV_CTS)
{  // CTS changed
ResetEvent(pUload->m_hPostEventRead);// first reset 
            pUload->PostMessage(WM_COMMNOTIFY,
                 (WPARAM)0,   // EV_CTS
                                 (LPARAM)0);  // not used
// wait answer
             WaitForSingleObject(pUload->m_hPostEventRead,0xFFFFFFFF);
}
}
CloseHandle(os.hEvent);
return 0;// OK
}


你上面的代码就是这么个意思:

hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
SetCommMask(hCom, EV_CTS);

while(true)
{
  WaitForSingleObject(hEvent, INFINIT);
  if(dwEventMask & EV_CTS)
  {
    RsetEvent(hEvent);
    // CTS 跳变了!!
  }
}


对吗


写错了,是 WaitCommEvent(hEvent, &dwEvtMask, &os);

#10


对,DSR 引脚变化时 产生 #define EV_DSR              0x0010  // DSR changed state
DTR 没有 事件, 但你是知道他的状态的。 就好像 RTS 你是知道的 ,也没事件可监视

#11


引用 7 楼 schlafenhamster 的回复:
// Events
//
线程可以监视 DSR:

#define EV_RXCHAR           0x0001  // Any Character received
#define EV_RXFLAG           0x0002  // Received certain character
#define EV_TXEMPTY          0x0004  // Transmitt Queue Empty
#define EV_CTS              0x0008  // CTS changed state
#define EV_DSR              0x0010  // DSR changed state
#define EV_RLSD             0x0020  // RLSD changed state
#define EV_BREAK            0x0040  // BREAK received
#define EV_ERR              0x0080  // Line status error occurred
#define EV_RING             0x0100  // Ring signal detected
#define EV_PERR             0x0200  // Printer error occured
#define EV_RX80FULL         0x0400  // Receive buffer is 80 percent full
#define EV_EVENT1           0x0800  // Provider specific event 1
#define EV_EVENT2           0x1000  // Provider specific event 2


我使用了上面那段代码编写了一个程序,但是不行呀:


DWORD dwEventMask;
HANDLE hCom;
OVERLAPPED os;
void Delay(int time)
{
while(time--);
}

DWORD WINAPI ThreadProc(LPVOID lpParam);


int main()
{
DWORD dw;
hCom = CreateFile("COM3", GENERIC_READ|GENERIC_WRITE, 0,
NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

if(INVALID_HANDLE_VALUE==hCom)
{
MessageBox(NULL, "COM4 Open Failed!", "", MB_OK);
return -1;
}

CreateThread(NULL, 0, ThreadProc, NULL, 0, &dw);

while(true)
{
  if(kbhit())
{
EscapeCommFunction(hCom, SETDTR);
Delay(0x0FFF);
EscapeCommFunction(hCom, CLRDTR);
Delay(0x0FFF);
EscapeCommFunction(hCom, SETDTR);
Delay(0x0FFF);
EscapeCommFunction(hCom, CLRDTR);
Delay(0x0FFF);
}
}


if(hCom)
CloseHandle(hCom);

return 0;
}


//检测 DSR 信号跳变的线程
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
// COM4 接收 DSR 的消息
hCom = CreateFile("COM4", GENERIC_READ|GENERIC_WRITE, 0,
NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

if(INVALID_HANDLE_VALUE==hCom)
{
MessageBox(NULL, "COM4 Open Failed!", "", MB_OK);
return -1;
}

HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

SetCommMask(hCom, EV_DSR);

while(true)
{
WaitCommEvent(hEvent, &dwEventMask, &os);
if((dwEventMask & EV_DSR)==EV_DSR)
{
ResetEvent(hEvent);
//DSR 跳变了!!
MessageBox(NULL, TEXT("DSR 跳变了!"), TEXT("哈哈!"), MB_OK);
}
}
if(hCom)
CloseHandle(hCom);
return 0;
}

#12


引用 11 楼 u011642451 的回复:
Quote: 引用 7 楼 schlafenhamster 的回复:

// Events
//
线程可以监视 DSR:

#define EV_RXCHAR           0x0001  // Any Character received
#define EV_RXFLAG           0x0002  // Received certain character
#define EV_TXEMPTY          0x0004  // Transmitt Queue Empty
#define EV_CTS              0x0008  // CTS changed state
#define EV_DSR              0x0010  // DSR changed state
#define EV_RLSD             0x0020  // RLSD changed state
#define EV_BREAK            0x0040  // BREAK received
#define EV_ERR              0x0080  // Line status error occurred
#define EV_RING             0x0100  // Ring signal detected
#define EV_PERR             0x0200  // Printer error occured
#define EV_RX80FULL         0x0400  // Receive buffer is 80 percent full
#define EV_EVENT1           0x0800  // Provider specific event 1
#define EV_EVENT2           0x1000  // Provider specific event 2


我使用了上面那段代码编写了一个程序,但是不行呀:


DWORD dwEventMask;
HANDLE hCom;
OVERLAPPED os;
void Delay(int time)
{
while(time--);
}

DWORD WINAPI ThreadProc(LPVOID lpParam);


int main()
{
DWORD dw;
hCom = CreateFile("COM3", GENERIC_READ|GENERIC_WRITE, 0,
NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

if(INVALID_HANDLE_VALUE==hCom)
{
MessageBox(NULL, "COM4 Open Failed!", "", MB_OK);
return -1;
}

CreateThread(NULL, 0, ThreadProc, NULL, 0, &dw);

while(true)
{
  if(kbhit())
{
EscapeCommFunction(hCom, SETDTR);
Delay(0x0FFF);
EscapeCommFunction(hCom, CLRDTR);
Delay(0x0FFF);
EscapeCommFunction(hCom, SETDTR);
Delay(0x0FFF);
EscapeCommFunction(hCom, CLRDTR);
Delay(0x0FFF);
}
}


if(hCom)
CloseHandle(hCom);

return 0;
}


//检测 DSR 信号跳变的线程
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
// COM4 接收 DSR 的消息
hCom = CreateFile("COM4", GENERIC_READ|GENERIC_WRITE, 0,
NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

if(INVALID_HANDLE_VALUE==hCom)
{
MessageBox(NULL, "COM4 Open Failed!", "", MB_OK);
return -1;
}

HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

SetCommMask(hCom, EV_DSR);

while(true)
{
WaitCommEvent(hEvent, &dwEventMask, &os);
if((dwEventMask & EV_DSR)==EV_DSR)
{
ResetEvent(hEvent);
//DSR 跳变了!!
MessageBox(NULL, TEXT("DSR 跳变了!"), TEXT("哈哈!"), MB_OK);
}
}
if(hCom)
CloseHandle(hCom);
return 0;
}


我在同一台机器上的,有两个串口,COM3  和 COM4, 我将 COM3 的 DTR 转接了一下 COM4 的 DSR

#13


引用 10 楼 schlafenhamster 的回复:
对,DSR 引脚变化时 产生 #define EV_DSR              0x0010  // DSR changed state
DTR 没有 事件, 但你是知道他的状态的。 就好像 RTS 你是知道的 ,也没事件可监视


我编写的这个程序测试了一下,但是程序运行后,没有产生预期效果呀?

#14


该回复于2013-11-11 08:54:25被管理员删除

#15



DWORD dwEventMask;
HANDLE hCom;
OVERLAPPED os;
void Delay(int time)
{
    while(time--);
}
 
DWORD WINAPI ThreadProc(LPVOID lpParam);
 
 
int main()
{
    DWORD dw;
    hCom = CreateFile("COM3", GENERIC_READ|GENERIC_WRITE, 0,
        NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
     
    if(INVALID_HANDLE_VALUE==hCom)
    {
        MessageBox(NULL, "COM4 Open Failed!", "", MB_OK);
        return -1;
    }
 
    CreateThread(NULL, 0, ThreadProc, NULL, 0, &dw);
 
    while(true)
    {
         if(kbhit())
        {
            EscapeCommFunction(hCom, SETDTR);
            Delay(0x0FFF);
            EscapeCommFunction(hCom, CLRDTR);
            Delay(0x0FFF);
            EscapeCommFunction(hCom, SETDTR);
            Delay(0x0FFF);
            EscapeCommFunction(hCom, CLRDTR);
            Delay(0x0FFF);
        }
    }
     
     
    if(hCom)
        CloseHandle(hCom);
 
    return 0;
}
 
 
//检测 DSR 信号跳变的线程
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
    // COM4 接收 DSR 的消息
    hCom = CreateFile("COM4", GENERIC_READ|GENERIC_WRITE, 0,
        NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
     
    if(INVALID_HANDLE_VALUE==hCom)
    {
        MessageBox(NULL, "COM4 Open Failed!", "", MB_OK);
        return -1;
    }
     
    HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
     
    SetCommMask(hCom, EV_DSR);
 
    while(true)
    {
        WaitCommEvent(hEvent, &dwEventMask, &os);
        if((dwEventMask & EV_DSR)==EV_DSR)
        {
            ResetEvent(hEvent);
            //DSR 跳变了!!
            MessageBox(NULL, TEXT("DSR 跳变了!"), TEXT("哈哈!"), MB_OK);
        }
    }    
    if(hCom)
        CloseHandle(hCom);
    return 0;
}

我在同一台机器上的,有两个串口,COM3  和 COM4, 我将 COM3 的 DTR 转接了一下 COM4 的 DSR
这个程序 测试,没有检测到 信号的跳变呀,怎么回事呢?小弟不懂,求指教

#16


你这代码有点不对的地方:

 代码中 CreateEvent 创建的事件对象是手动置信号的,初始为无信号,而在二级线程里有 ResetEvent,但是,没有看到哪里有 SetEvent。这肯定不对。

#1


SetCommMask(hCom, EV_DSR);

WaitCommEvent(hCom, &dwEvtMask, &OverLapped);
if( dwEvtMask & EV_DSR )
{
    //DSR 发生跳变了!
}

#2


如何检测串口 的 DSR 引脚或 DTR 的电平变化?
求帮助,求指导……

#3


SetCommMask(hCom, EV_DSR);
GetCommMask(hCom, &dwEvtMask);
if(dwEvtMask & EV_DSR) 
{
     // DSR 电平发生了跳变!
}

WaitCommEvent(hCom, &dwEvtMask, &OverLapped);  执行一次就不执行了,DTR远还没有出线就挂了,

太简单了,必须弄一个阻塞线程来等待这个信号量,接受消息就必须在窗口下面,所有的消息都是发往窗口的,在窗口下拦截这个消息,这个就不会占CPU, 0% 因为windows太快了,

如果你用单片机的方式
while(1)
{
    WaitCommEvent(hCom, &dwEvtMask, &OverLapped);  也可以,那windows啥也不干就等信号量
}

#4


98年老外VC下有个CSerialPort类封装,很好的解决这个问题,具体看《串口通讯XX》,VC下将该类加到你的窗口,两三句就解决问题了,我试过,用该类,开10个串口57600高速读写,CPU占用率最多2%,用了N年很稳定,,不要考虑自己弄了,有现在很好用

#5


专门一个线程:

// an work thread to monitor the _CTS and RX_CHAR 
UINT CUload::CommWatchRead(LPVOID lpParam)
{   // return 0=OK 1=Error
    CUload     *pUload=(CUload*)lpParam;
OVERLAPPED os;
DWORD dwEventMask,dwTransfer;

memset(&os,0,sizeof(OVERLAPPED));
os.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);// attrb,Manual,init,name
if (os.hEvent==NULL)
{
AfxMessageBox("Can't create Event",MB_ICONSTOP);
return 1;// error
}
// set 2 events !
    if (!SetCommMask(pUload->m_idComDev,EV_RXCHAR|EV_CTS)) return 1;
    while (pUload->m_bConnected)
{ // break,only if m_bConnected=NULL 
dwEventMask=0;
        if(!WaitCommEvent(pUload->m_idComDev,&dwEventMask,&os))
{ // function fails
if (GetLastError()==ERROR_IO_PENDING)
{// TRUE=WaitForSingleObject() should be called inside
                GetOverlappedResult(pUload->m_idComDev,&os,&dwTransfer,TRUE);
os.Offset+=dwTransfer;
}
}
if((dwEventMask & EV_RXCHAR)==EV_RXCHAR)
{ // some chats received.
             ResetEvent(pUload->m_hPostEventRead);// first reset 
             pUload->PostMessage(WM_COMMNOTIFY,
                 (WPARAM)1,   // EV_RXCHAR
                                 (LPARAM)0);  // not used
// wait answer
             WaitForSingleObject(pUload->m_hPostEventRead,0xFFFFFFFF);
}
// if not at same time,use else if
if((dwEventMask & EV_CTS)==EV_CTS)
{  // CTS changed
ResetEvent(pUload->m_hPostEventRead);// first reset 
            pUload->PostMessage(WM_COMMNOTIFY,
                 (WPARAM)0,   // EV_CTS
                                 (LPARAM)0);  // not used
// wait answer
             WaitForSingleObject(pUload->m_hPostEventRead,0xFFFFFFFF);
}
}
CloseHandle(os.hEvent);
return 0;// OK
}

#6


引用 4 楼 vc8fans 的回复:
98年老外VC下有个CSerialPort类封装,很好的解决这个问题,具体看《串口通讯XX》,VC下将该类加到你的窗口,两三句就解决问题了,我试过,用该类,开10个串口57600高速读写,CPU占用率最多2%,用了N年很稳定,,不要考虑自己弄了,有现在很好用


非常感谢帮我解答疑惑

#7


// Events
//
线程可以监视 DSR:

#define EV_RXCHAR           0x0001  // Any Character received
#define EV_RXFLAG           0x0002  // Received certain character
#define EV_TXEMPTY          0x0004  // Transmitt Queue Empty
#define EV_CTS              0x0008  // CTS changed state
#define EV_DSR              0x0010  // DSR changed state
#define EV_RLSD             0x0020  // RLSD changed state
#define EV_BREAK            0x0040  // BREAK received
#define EV_ERR              0x0080  // Line status error occurred
#define EV_RING             0x0100  // Ring signal detected
#define EV_PERR             0x0200  // Printer error occured
#define EV_RX80FULL         0x0400  // Receive buffer is 80 percent full
#define EV_EVENT1           0x0800  // Provider specific event 1
#define EV_EVENT2           0x1000  // Provider specific event 2

#8


引用 5 楼 schlafenhamster 的回复:
专门一个线程:

// an work thread to monitor the _CTS and RX_CHAR 
UINT CUload::CommWatchRead(LPVOID lpParam)
{   // return 0=OK 1=Error
    CUload     *pUload=(CUload*)lpParam;
OVERLAPPED os;
DWORD dwEventMask,dwTransfer;

memset(&os,0,sizeof(OVERLAPPED));
os.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);// attrb,Manual,init,name
if (os.hEvent==NULL)
{
AfxMessageBox("Can't create Event",MB_ICONSTOP);
return 1;// error
}
// set 2 events !
    if (!SetCommMask(pUload->m_idComDev,EV_RXCHAR|EV_CTS)) return 1;
    while (pUload->m_bConnected)
{ // break,only if m_bConnected=NULL 
dwEventMask=0;
        if(!WaitCommEvent(pUload->m_idComDev,&dwEventMask,&os))
{ // function fails
if (GetLastError()==ERROR_IO_PENDING)
{// TRUE=WaitForSingleObject() should be called inside
                GetOverlappedResult(pUload->m_idComDev,&os,&dwTransfer,TRUE);
os.Offset+=dwTransfer;
}
}
if((dwEventMask & EV_RXCHAR)==EV_RXCHAR)
{ // some chats received.
             ResetEvent(pUload->m_hPostEventRead);// first reset 
             pUload->PostMessage(WM_COMMNOTIFY,
                 (WPARAM)1,   // EV_RXCHAR
                                 (LPARAM)0);  // not used
// wait answer
             WaitForSingleObject(pUload->m_hPostEventRead,0xFFFFFFFF);
}
// if not at same time,use else if
if((dwEventMask & EV_CTS)==EV_CTS)
{  // CTS changed
ResetEvent(pUload->m_hPostEventRead);// first reset 
            pUload->PostMessage(WM_COMMNOTIFY,
                 (WPARAM)0,   // EV_CTS
                                 (LPARAM)0);  // not used
// wait answer
             WaitForSingleObject(pUload->m_hPostEventRead,0xFFFFFFFF);
}
}
CloseHandle(os.hEvent);
return 0;// OK
}


你上面的代码就是这么个意思:

hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
SetCommMask(hCom, EV_CTS);

while(true)
{
  WaitForSingleObject(hEvent, INFINIT);
  if(dwEventMask & EV_CTS)
  {
    RsetEvent(hEvent);
    // CTS 跳变了!!
  }
}


对吗

#9


引用 8 楼 u011642451 的回复:
Quote: 引用 5 楼 schlafenhamster 的回复:

专门一个线程:

// an work thread to monitor the _CTS and RX_CHAR 
UINT CUload::CommWatchRead(LPVOID lpParam)
{   // return 0=OK 1=Error
    CUload     *pUload=(CUload*)lpParam;
OVERLAPPED os;
DWORD dwEventMask,dwTransfer;

memset(&os,0,sizeof(OVERLAPPED));
os.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);// attrb,Manual,init,name
if (os.hEvent==NULL)
{
AfxMessageBox("Can't create Event",MB_ICONSTOP);
return 1;// error
}
// set 2 events !
    if (!SetCommMask(pUload->m_idComDev,EV_RXCHAR|EV_CTS)) return 1;
    while (pUload->m_bConnected)
{ // break,only if m_bConnected=NULL 
dwEventMask=0;
        if(!WaitCommEvent(pUload->m_idComDev,&dwEventMask,&os))
{ // function fails
if (GetLastError()==ERROR_IO_PENDING)
{// TRUE=WaitForSingleObject() should be called inside
                GetOverlappedResult(pUload->m_idComDev,&os,&dwTransfer,TRUE);
os.Offset+=dwTransfer;
}
}
if((dwEventMask & EV_RXCHAR)==EV_RXCHAR)
{ // some chats received.
             ResetEvent(pUload->m_hPostEventRead);// first reset 
             pUload->PostMessage(WM_COMMNOTIFY,
                 (WPARAM)1,   // EV_RXCHAR
                                 (LPARAM)0);  // not used
// wait answer
             WaitForSingleObject(pUload->m_hPostEventRead,0xFFFFFFFF);
}
// if not at same time,use else if
if((dwEventMask & EV_CTS)==EV_CTS)
{  // CTS changed
ResetEvent(pUload->m_hPostEventRead);// first reset 
            pUload->PostMessage(WM_COMMNOTIFY,
                 (WPARAM)0,   // EV_CTS
                                 (LPARAM)0);  // not used
// wait answer
             WaitForSingleObject(pUload->m_hPostEventRead,0xFFFFFFFF);
}
}
CloseHandle(os.hEvent);
return 0;// OK
}


你上面的代码就是这么个意思:

hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
SetCommMask(hCom, EV_CTS);

while(true)
{
  WaitForSingleObject(hEvent, INFINIT);
  if(dwEventMask & EV_CTS)
  {
    RsetEvent(hEvent);
    // CTS 跳变了!!
  }
}


对吗


写错了,是 WaitCommEvent(hEvent, &dwEvtMask, &os);

#10


对,DSR 引脚变化时 产生 #define EV_DSR              0x0010  // DSR changed state
DTR 没有 事件, 但你是知道他的状态的。 就好像 RTS 你是知道的 ,也没事件可监视

#11


引用 7 楼 schlafenhamster 的回复:
// Events
//
线程可以监视 DSR:

#define EV_RXCHAR           0x0001  // Any Character received
#define EV_RXFLAG           0x0002  // Received certain character
#define EV_TXEMPTY          0x0004  // Transmitt Queue Empty
#define EV_CTS              0x0008  // CTS changed state
#define EV_DSR              0x0010  // DSR changed state
#define EV_RLSD             0x0020  // RLSD changed state
#define EV_BREAK            0x0040  // BREAK received
#define EV_ERR              0x0080  // Line status error occurred
#define EV_RING             0x0100  // Ring signal detected
#define EV_PERR             0x0200  // Printer error occured
#define EV_RX80FULL         0x0400  // Receive buffer is 80 percent full
#define EV_EVENT1           0x0800  // Provider specific event 1
#define EV_EVENT2           0x1000  // Provider specific event 2


我使用了上面那段代码编写了一个程序,但是不行呀:


DWORD dwEventMask;
HANDLE hCom;
OVERLAPPED os;
void Delay(int time)
{
while(time--);
}

DWORD WINAPI ThreadProc(LPVOID lpParam);


int main()
{
DWORD dw;
hCom = CreateFile("COM3", GENERIC_READ|GENERIC_WRITE, 0,
NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

if(INVALID_HANDLE_VALUE==hCom)
{
MessageBox(NULL, "COM4 Open Failed!", "", MB_OK);
return -1;
}

CreateThread(NULL, 0, ThreadProc, NULL, 0, &dw);

while(true)
{
  if(kbhit())
{
EscapeCommFunction(hCom, SETDTR);
Delay(0x0FFF);
EscapeCommFunction(hCom, CLRDTR);
Delay(0x0FFF);
EscapeCommFunction(hCom, SETDTR);
Delay(0x0FFF);
EscapeCommFunction(hCom, CLRDTR);
Delay(0x0FFF);
}
}


if(hCom)
CloseHandle(hCom);

return 0;
}


//检测 DSR 信号跳变的线程
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
// COM4 接收 DSR 的消息
hCom = CreateFile("COM4", GENERIC_READ|GENERIC_WRITE, 0,
NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

if(INVALID_HANDLE_VALUE==hCom)
{
MessageBox(NULL, "COM4 Open Failed!", "", MB_OK);
return -1;
}

HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

SetCommMask(hCom, EV_DSR);

while(true)
{
WaitCommEvent(hEvent, &dwEventMask, &os);
if((dwEventMask & EV_DSR)==EV_DSR)
{
ResetEvent(hEvent);
//DSR 跳变了!!
MessageBox(NULL, TEXT("DSR 跳变了!"), TEXT("哈哈!"), MB_OK);
}
}
if(hCom)
CloseHandle(hCom);
return 0;
}

#12


引用 11 楼 u011642451 的回复:
Quote: 引用 7 楼 schlafenhamster 的回复:

// Events
//
线程可以监视 DSR:

#define EV_RXCHAR           0x0001  // Any Character received
#define EV_RXFLAG           0x0002  // Received certain character
#define EV_TXEMPTY          0x0004  // Transmitt Queue Empty
#define EV_CTS              0x0008  // CTS changed state
#define EV_DSR              0x0010  // DSR changed state
#define EV_RLSD             0x0020  // RLSD changed state
#define EV_BREAK            0x0040  // BREAK received
#define EV_ERR              0x0080  // Line status error occurred
#define EV_RING             0x0100  // Ring signal detected
#define EV_PERR             0x0200  // Printer error occured
#define EV_RX80FULL         0x0400  // Receive buffer is 80 percent full
#define EV_EVENT1           0x0800  // Provider specific event 1
#define EV_EVENT2           0x1000  // Provider specific event 2


我使用了上面那段代码编写了一个程序,但是不行呀:


DWORD dwEventMask;
HANDLE hCom;
OVERLAPPED os;
void Delay(int time)
{
while(time--);
}

DWORD WINAPI ThreadProc(LPVOID lpParam);


int main()
{
DWORD dw;
hCom = CreateFile("COM3", GENERIC_READ|GENERIC_WRITE, 0,
NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

if(INVALID_HANDLE_VALUE==hCom)
{
MessageBox(NULL, "COM4 Open Failed!", "", MB_OK);
return -1;
}

CreateThread(NULL, 0, ThreadProc, NULL, 0, &dw);

while(true)
{
  if(kbhit())
{
EscapeCommFunction(hCom, SETDTR);
Delay(0x0FFF);
EscapeCommFunction(hCom, CLRDTR);
Delay(0x0FFF);
EscapeCommFunction(hCom, SETDTR);
Delay(0x0FFF);
EscapeCommFunction(hCom, CLRDTR);
Delay(0x0FFF);
}
}


if(hCom)
CloseHandle(hCom);

return 0;
}


//检测 DSR 信号跳变的线程
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
// COM4 接收 DSR 的消息
hCom = CreateFile("COM4", GENERIC_READ|GENERIC_WRITE, 0,
NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

if(INVALID_HANDLE_VALUE==hCom)
{
MessageBox(NULL, "COM4 Open Failed!", "", MB_OK);
return -1;
}

HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

SetCommMask(hCom, EV_DSR);

while(true)
{
WaitCommEvent(hEvent, &dwEventMask, &os);
if((dwEventMask & EV_DSR)==EV_DSR)
{
ResetEvent(hEvent);
//DSR 跳变了!!
MessageBox(NULL, TEXT("DSR 跳变了!"), TEXT("哈哈!"), MB_OK);
}
}
if(hCom)
CloseHandle(hCom);
return 0;
}


我在同一台机器上的,有两个串口,COM3  和 COM4, 我将 COM3 的 DTR 转接了一下 COM4 的 DSR

#13


引用 10 楼 schlafenhamster 的回复:
对,DSR 引脚变化时 产生 #define EV_DSR              0x0010  // DSR changed state
DTR 没有 事件, 但你是知道他的状态的。 就好像 RTS 你是知道的 ,也没事件可监视


我编写的这个程序测试了一下,但是程序运行后,没有产生预期效果呀?

#14


该回复于2013-11-11 08:54:25被管理员删除

#15



DWORD dwEventMask;
HANDLE hCom;
OVERLAPPED os;
void Delay(int time)
{
    while(time--);
}
 
DWORD WINAPI ThreadProc(LPVOID lpParam);
 
 
int main()
{
    DWORD dw;
    hCom = CreateFile("COM3", GENERIC_READ|GENERIC_WRITE, 0,
        NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
     
    if(INVALID_HANDLE_VALUE==hCom)
    {
        MessageBox(NULL, "COM4 Open Failed!", "", MB_OK);
        return -1;
    }
 
    CreateThread(NULL, 0, ThreadProc, NULL, 0, &dw);
 
    while(true)
    {
         if(kbhit())
        {
            EscapeCommFunction(hCom, SETDTR);
            Delay(0x0FFF);
            EscapeCommFunction(hCom, CLRDTR);
            Delay(0x0FFF);
            EscapeCommFunction(hCom, SETDTR);
            Delay(0x0FFF);
            EscapeCommFunction(hCom, CLRDTR);
            Delay(0x0FFF);
        }
    }
     
     
    if(hCom)
        CloseHandle(hCom);
 
    return 0;
}
 
 
//检测 DSR 信号跳变的线程
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
    // COM4 接收 DSR 的消息
    hCom = CreateFile("COM4", GENERIC_READ|GENERIC_WRITE, 0,
        NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
     
    if(INVALID_HANDLE_VALUE==hCom)
    {
        MessageBox(NULL, "COM4 Open Failed!", "", MB_OK);
        return -1;
    }
     
    HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
     
    SetCommMask(hCom, EV_DSR);
 
    while(true)
    {
        WaitCommEvent(hEvent, &dwEventMask, &os);
        if((dwEventMask & EV_DSR)==EV_DSR)
        {
            ResetEvent(hEvent);
            //DSR 跳变了!!
            MessageBox(NULL, TEXT("DSR 跳变了!"), TEXT("哈哈!"), MB_OK);
        }
    }    
    if(hCom)
        CloseHandle(hCom);
    return 0;
}

我在同一台机器上的,有两个串口,COM3  和 COM4, 我将 COM3 的 DTR 转接了一下 COM4 的 DSR
这个程序 测试,没有检测到 信号的跳变呀,怎么回事呢?小弟不懂,求指教

#16


你这代码有点不对的地方:

 代码中 CreateEvent 创建的事件对象是手动置信号的,初始为无信号,而在二级线程里有 ResetEvent,但是,没有看到哪里有 SetEvent。这肯定不对。