搜索
bottom↓
回复: 6

读写CDC类虚拟串口(VCP)跟真实串口有什么不同点么?

[复制链接]

出130入129汤圆

发表于 昨天 18:36 | 显示全部楼层 |阅读模式
WIN11, VC2008,多年以来读写串口用一个古董类CSerialPort,不过一直也只是跟原生串口或者USB转串口通信,一直都挺正常的。

改了个上位机要跟STM32的虚拟串口通信,发现不能正常工作,只在打开串口后,才能发送一次数据。要想再次发送,就必须关闭再打开串口。
如果换成USB转的串口,这个上位机是可以正常通信的。
用一些串口调试助手打开这个CDC类虚拟串口,是可以多次发送数据的。

所以问题就是读写这些CDC类虚拟串口,是有什么地方不同,自己没了解到导致的。



  1. #include "stdafx.h"
  2. #include "SerialPort.h"

  3. #include <assert.h>
  4. //
  5. // Constructor
  6. //
  7. CSerialPort::CSerialPort()
  8. {
  9.     m_hComm = NULL;
  10.     // initialize overlapped structure members to zero
  11.     m_ov.Offset = 0;
  12.     m_ov.OffsetHigh = 0;

  13.     // create events
  14.     m_ov.hEvent = NULL;
  15.     m_hWriteEvent = NULL;
  16.     m_hShutdownEvent = NULL;

  17.     m_szWriteBuffer = NULL;
  18.     m_nWriteSize = 1;

  19.     m_bThreadAlive = FALSE;

  20.     memset(m_RxRingBuffer.buffer, 0, sizeof(m_RxRingBuffer.buffer));
  21.     m_RxRingBuffer.in = 0;
  22.     m_RxRingBuffer.out = 0;
  23. }

  24. //
  25. // Delete dynamic memory
  26. //
  27. CSerialPort::~CSerialPort()
  28. {
  29.     do
  30.     {
  31.         SetEvent(m_hShutdownEvent);
  32.     }
  33.     while(m_bThreadAlive);


  34.     // if the port is still opened: close it
  35.     if(m_hComm != NULL)
  36.     {
  37.         CloseHandle(m_hComm);
  38.         m_hComm = NULL;
  39.     }

  40.     // Close Handles
  41.     if(m_hShutdownEvent != NULL)
  42.         CloseHandle(m_hShutdownEvent);

  43.     if(m_ov.hEvent != NULL)
  44.         CloseHandle(m_ov.hEvent);

  45.     if(m_hWriteEvent != NULL)
  46.         CloseHandle(m_hWriteEvent);

  47.     TRACE("Thread ended\n");
  48.     delete [] m_szWriteBuffer;
  49. }

  50. //
  51. // Initialize the port. This can be port 1 to 4.
  52. //
  53. BOOL CSerialPort::InitPort(CWnd* pPortOwner,    // the owner (CWnd) of the port (receives message)
  54.                            UINT  portnr,        // portnumber (1..4)
  55.                            UINT  baud,          // baudrate
  56.                            char  parity,        // parity
  57.                            UINT  databits,      // databits
  58.                            UINT  stopbits,      // stopbits
  59.                            DWORD dwCommEvents,  // EV_RXCHAR, EV_CTS etc
  60.                            UINT  writebuffersize)   // size to the writebuffer
  61. {
  62.     assert(portnr > 0 && portnr < 255);
  63.     assert(pPortOwner != NULL);

  64.     // if the thread is alive: Kill
  65.     if(m_bThreadAlive)
  66.     {
  67.         do
  68.         {
  69.             SetEvent(m_hShutdownEvent);
  70.         }
  71.         while(m_bThreadAlive);

  72.         TRACE("Thread ended\n");
  73.     }

  74.     // create events
  75.     if(m_ov.hEvent != NULL)
  76.         ResetEvent(m_ov.hEvent);
  77.     else
  78.         m_ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

  79.     if(m_hWriteEvent != NULL)
  80.         ResetEvent(m_hWriteEvent);
  81.     else
  82.         m_hWriteEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

  83.     if(m_hShutdownEvent != NULL)
  84.         ResetEvent(m_hShutdownEvent);
  85.     else
  86.         m_hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

  87.     // initialize the event objects
  88.     m_hEventArray[0] = m_hShutdownEvent;    // highest priority
  89.     m_hEventArray[1] = m_ov.hEvent;
  90.     m_hEventArray[2] = m_hWriteEvent;

  91.     // initialize critical section
  92.     InitializeCriticalSection(&m_csCommunicationSync);

  93.     // set buffersize for writing and save the owner
  94.     m_pOwner = pPortOwner;

  95.     if(m_szWriteBuffer != NULL)
  96.         delete [] m_szWriteBuffer;

  97.     m_szWriteBuffer = new char[writebuffersize];

  98.     m_nPortNr = portnr;

  99.     m_nWriteBufferSize = writebuffersize;
  100.     m_dwCommEvents = dwCommEvents;

  101.     BOOL bResult = FALSE;
  102.     char *szPort = new char[50];
  103.     char *szBaud = new char[50];

  104.     // now it critical!
  105.     EnterCriticalSection(&m_csCommunicationSync);

  106.     // if the port is already opened: close it
  107.     if(m_hComm != NULL)
  108.     {
  109.         CloseHandle(m_hComm);
  110.         m_hComm = NULL;
  111.     }

  112.     // prepare port strings
  113.     sprintf(szPort, "\\\\.\\COM%d", portnr);
  114.     sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d", baud, parity, databits, stopbits);

  115.     // get a handle to the port
  116.     m_hComm = CreateFile(szPort,                        // communication port string (COMX)
  117.                          GENERIC_READ | GENERIC_WRITE,  // read/write types
  118.                          0,                             // comm devices must be opened with exclusive access
  119.                          NULL,                          // no security attributes
  120.                          OPEN_EXISTING,                 // comm devices must use OPEN_EXISTING
  121.                          FILE_FLAG_OVERLAPPED,          // Async I/O
  122.                          0);                            // template must be 0 for comm devices

  123.     if(m_hComm == INVALID_HANDLE_VALUE)
  124.     {
  125.         // port not found
  126.         delete [] szPort;
  127.         delete [] szBaud;

  128.         return FALSE;
  129.     }

  130.     // set the timeout values
  131.     m_CommTimeouts.ReadIntervalTimeout = 1000;
  132.     m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000;
  133.     m_CommTimeouts.ReadTotalTimeoutConstant = 1000;
  134.     m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000;
  135.     m_CommTimeouts.WriteTotalTimeoutConstant = 1000;

  136.     // configure
  137.     if(SetCommTimeouts(m_hComm, &m_CommTimeouts))
  138.     {
  139.         if(SetCommMask(m_hComm, dwCommEvents))
  140.         {
  141.             if(GetCommState(m_hComm, &m_dcb))
  142.             {
  143.                 m_dcb.EvtChar = 'q';
  144.                 m_dcb.fRtsControl = RTS_CONTROL_ENABLE;     // set RTS bit high!

  145.                 if(BuildCommDCB(szBaud, &m_dcb))
  146.                 {
  147.                     if(SetCommState(m_hComm, &m_dcb))
  148.                         ; // normal operation... continue
  149.                     else
  150.                         ProcessErrorMessage("SetCommState()");
  151.                 }
  152.                 else
  153.                     ProcessErrorMessage("BuildCommDCB()");
  154.             }
  155.             else
  156.                 ProcessErrorMessage("GetCommState()");
  157.         }
  158.         else
  159.             ProcessErrorMessage("SetCommMask()");
  160.     }
  161.     else
  162.         ProcessErrorMessage("SetCommTimeouts()");

  163.     ////设置超大接收缓冲区
  164.     //SetupComm(m_hComm, 200000, 1024);

  165.     delete [] szPort;
  166.     delete [] szBaud;

  167.     // flush the port
  168.     PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

  169.     // release critical section
  170.     LeaveCriticalSection(&m_csCommunicationSync);

  171.     TRACE("Initialisation for communicationport %d completed.\nUse Startmonitor to communicate.\n", portnr);

  172.     return TRUE;
  173. }

  174. //
  175. //  The CommThread Function.
  176. //
  177. UINT CSerialPort::CommThread(LPVOID pParam)
  178. {
  179.     // Cast the void pointer passed to the thread back to
  180.     // a pointer of CSerialPort class
  181.     CSerialPort *port = (CSerialPort*)pParam;

  182.     // Set the status variable in the dialog class to
  183.     // TRUE to indicate the thread is running.
  184.     port->m_bThreadAlive = TRUE;

  185.     // Misc. variables
  186.     DWORD BytesTransfered = 0;
  187.     DWORD Event = 0;
  188.     DWORD CommEvent = 0;
  189.     DWORD dwError = 0;
  190.     COMSTAT comstat;
  191.     BOOL  bResult = TRUE;

  192.     // Clear comm buffers at startup
  193.     if(port->m_hComm)       // check if the port is opened
  194.         PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

  195.     // Initialize comstat
  196.     ClearCommError(port->m_hComm, &dwError, &comstat);

  197.     // begin forever loop.  This loop will run as long as the thread is alive.
  198.     for(;;)
  199.     {

  200.         // Make a call to WaitCommEvent().  This call will return immediatly
  201.         // because our port was created as an async port (FILE_FLAG_OVERLAPPED
  202.         // and an m_OverlappedStructerlapped structure specified).  This call will cause the
  203.         // m_OverlappedStructerlapped element m_OverlappedStruct.hEvent, which is part of the m_hEventArray to
  204.         // be placed in a non-signeled state if there are no bytes available to be read,
  205.         // or to a signeled state if there are bytes available.  If this event handle
  206.         // is set to the non-signeled state, it will be set to signeled when a
  207.         // character arrives at the port.

  208.         // we do this for each port!

  209.         bResult = WaitCommEvent(port->m_hComm, &Event, &port->m_ov);

  210.         if(!bResult)
  211.         {
  212.             // If WaitCommEvent() returns FALSE, process the last error to determin
  213.             // the reason..
  214.             switch(dwError = GetLastError())
  215.             {
  216.             case ERROR_IO_PENDING:
  217.             {
  218.                 // This is a normal return value if there are no bytes
  219.                 // to read at the port.
  220.                 // Do nothing and continue
  221.                 break;
  222.             }

  223.             case 87:
  224.             {
  225.                 // Under Windows NT, this value is returned for some reason.
  226.                 // I have not investigated why, but it is also a valid reply
  227.                 // Also do nothing and continue.
  228.                 break;
  229.             }

  230.             default:
  231.             {
  232.                 // All other error codes indicate a serious error has
  233.                 // occured.  Process this error.
  234.                 port->ProcessErrorMessage("WaitCommEvent()");
  235.                 break;
  236.             }
  237.             }
  238.         }
  239.         else
  240.         {
  241.             // If WaitCommEvent() returns TRUE, check to be sure there are
  242.             // actually bytes in the buffer to read.
  243.             //
  244.             // If you are reading more than one byte at a time from the buffer
  245.             // (which this program does not do) you will have the situation occur
  246.             // where the first byte to arrive will cause the WaitForMultipleObjects()
  247.             // function to stop waiting.  The WaitForMultipleObjects() function
  248.             // resets the event handle in m_OverlappedStruct.hEvent to the non-signelead state
  249.             // as it returns.
  250.             //
  251.             // If in the time between the reset of this event and the call to
  252.             // ReadFile() more bytes arrive, the m_OverlappedStruct.hEvent handle will be set again
  253.             // to the signeled state. When the call to ReadFile() occurs, it will
  254.             // read all of the bytes from the buffer, and the program will
  255.             // loop back around to WaitCommEvent().
  256.             //
  257.             // At this point you will be in the situation where m_OverlappedStruct.hEvent is set,
  258.             // but there are no bytes available to read.  If you proceed and call
  259.             // ReadFile(), it will return immediatly due to the async port setup, but
  260.             // GetOverlappedResults() will not return until the next character arrives.
  261.             //
  262.             // It is not desirable for the GetOverlappedResults() function to be in
  263.             // this state.  The thread shutdown event (event 0) and the WriteFile()
  264.             // event (Event2) will not work if the thread is blocked by GetOverlappedResults().
  265.             //
  266.             // The solution to this is to check the buffer with a call to ClearCommError().
  267.             // This call will reset the event handle, and if there are no bytes to read
  268.             // we can loop back through WaitCommEvent() again, then proceed.
  269.             // If there are really bytes to read, do nothing and proceed.

  270.             bResult = ClearCommError(port->m_hComm, &dwError, &comstat);

  271.             if(comstat.cbInQue == 0)
  272.                 continue;
  273.         }   // end if bResult

  274.         // Main wait function.  This function will normally block the thread
  275.         // until one of nine events occur that require action.
  276.         Event = WaitForMultipleObjects(3, port->m_hEventArray, FALSE, INFINITE);

  277.         switch(Event)
  278.         {
  279.         case 0:
  280.         {
  281.             // Shutdown event.  This is event zero so it will be
  282.             // the higest priority and be serviced first.
  283.             CloseHandle(port->m_hComm);
  284.             port->m_hComm = NULL;
  285.             port->m_bThreadAlive = FALSE;

  286.             // Kill this thread.  break is not needed, but makes me feel better.
  287.             AfxEndThread(100);

  288.             break;
  289.         }

  290.         case 1: // read event
  291.         {
  292.             GetCommMask(port->m_hComm, &CommEvent);

  293.             if(CommEvent & EV_RXCHAR)
  294.                 // Receive character event from port.
  295.                 ReceiveChar(port, comstat);

  296.             if(CommEvent & EV_CTS)
  297.                 ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_CTS_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);

  298.             if(CommEvent & EV_BREAK)
  299.                 ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_BREAK_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);

  300.             if(CommEvent & EV_ERR)
  301.                 ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_ERR_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);

  302.             if(CommEvent & EV_RING)
  303.                 ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_RING_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);

  304.             if(CommEvent & EV_RXFLAG)
  305.                 ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_RXFLAG_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);

  306.             break;
  307.         }

  308.         case 2: // write event
  309.         {
  310.             // Write character event from port
  311.             WriteChar(port);
  312.             break;
  313.         }

  314.         } // end switch

  315.     } // close forever loop

  316.     return 0;
  317. }

  318. //
  319. // start comm watching
  320. //
  321. BOOL CSerialPort::StartMonitoring()
  322. {
  323.     if(!(m_Thread = AfxBeginThread(CommThread, this)))
  324.         return FALSE;

  325.     TRACE("Thread started\n");
  326.     return TRUE;
  327. }

  328. //
  329. // Restart the comm thread
  330. //
  331. BOOL CSerialPort::RestartMonitoring()
  332. {
  333.     TRACE("Thread resumed\n");
  334.     m_Thread->ResumeThread();
  335.     return TRUE;
  336. }


  337. //
  338. // Suspend the comm thread
  339. //
  340. BOOL CSerialPort::StopMonitoring()
  341. {
  342.     TRACE("Thread suspended\n");
  343.     m_Thread->SuspendThread();
  344.     return TRUE;
  345. }


  346. //
  347. // If there is a error, give the right message
  348. //
  349. void CSerialPort::ProcessErrorMessage(char* ErrorText)
  350. {
  351.     char *Temp = new char[200];

  352.     LPVOID lpMsgBuf;

  353.     FormatMessage(
  354.         FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  355.         NULL,
  356.         GetLastError(),
  357.         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  358.         (LPTSTR) &lpMsgBuf,
  359.         0,
  360.         NULL
  361.     );

  362.     sprintf(Temp, "WARNING:  %s Failed with the following error: \n%s\nPort: %d\n", (char*)ErrorText, lpMsgBuf, m_nPortNr);
  363.     MessageBox(NULL, Temp, "Application Error", MB_ICONSTOP);

  364.     LocalFree(lpMsgBuf);
  365.     delete [] Temp;
  366. }

  367. //
  368. // Write a character.
  369. //
  370. void CSerialPort::WriteChar(CSerialPort* port)
  371. {
  372.     BOOL bWrite = TRUE;
  373.     BOOL bResult = TRUE;

  374.     DWORD BytesSent = 0;

  375.     ResetEvent(port->m_hWriteEvent);

  376.     // Gain ownership of the critical section
  377.     EnterCriticalSection(&port->m_csCommunicationSync);

  378.     if(bWrite)
  379.     {
  380.         // Initailize variables
  381.         port->m_ov.Offset = 0;
  382.         port->m_ov.OffsetHigh = 0;

  383.         // Clear buffer
  384.         PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

  385.         bResult = WriteFile(port->m_hComm,                          // Handle to COMM Port
  386.                             port->m_szWriteBuffer,                  // Pointer to message buffer in calling finction
  387. //                          strlen((char*)port->m_szWriteBuffer),   // Length of message to send
  388.                             port->m_nWriteSize, // Length of message to send
  389.                             &BytesSent,                             // Where to store the number of bytes sent
  390.                             &port->m_ov);                           // Overlapped structure

  391.         // deal with any error codes
  392.         if(!bResult)
  393.         {
  394.             DWORD dwError = GetLastError();

  395.             switch(dwError)
  396.             {
  397.             case ERROR_IO_PENDING:
  398.             {
  399.                 // continue to GetOverlappedResults()
  400.                 BytesSent = 0;
  401.                 bWrite = FALSE;
  402.                 break;
  403.             }

  404.             default:
  405.             {
  406.                 // all other error codes
  407.                 port->ProcessErrorMessage("WriteFile()");
  408.             }
  409.             }
  410.         }
  411.         else
  412.         {
  413.             LeaveCriticalSection(&port->m_csCommunicationSync);
  414.         }
  415.     } // end if(bWrite)

  416.     if(!bWrite)
  417.     {
  418.         bWrite = TRUE;

  419.         bResult = GetOverlappedResult(port->m_hComm,    // Handle to COMM port
  420.                                       &port->m_ov,      // Overlapped structure
  421.                                       &BytesSent,       // Stores number of bytes sent
  422.                                       TRUE);            // Wait flag

  423.         LeaveCriticalSection(&port->m_csCommunicationSync);

  424.         // deal with the error code
  425. //      if (!bResult)
  426.         {
  427. //          port->ProcessErrorMessage("GetOverlappedResults() in WriteFile()");
  428.         }
  429.     } // end if (!bWrite)

  430.     //Verify that the data size send equals what we tried to send
  431.     if(BytesSent != port->m_nWriteSize)     // Length of message to send)
  432.     {
  433.         TRACE("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)port->m_szWriteBuffer));
  434.     }

  435. //  ::SendMessage((port->m_pOwner)->m_hWnd, WM_COMM_TXEMPTY_DETECTED, (WPARAM) RXBuff, (LPARAM) port->m_nPortNr);
  436. //  ::SendMessage((port->m_pOwner)->m_hWnd, WM_COMM_TXEMPTY_DETECTED,0,(LPARAM) port->m_nPortNr);
  437. }

  438. //
  439. // Character received. Inform the owner
  440. void CSerialPort::ReceiveChar(CSerialPort * port, COMSTAT comstat)
  441. {
  442.     BOOL  bRead = TRUE;
  443.     BOOL  bResult = TRUE;
  444.     DWORD dwError = 0;
  445.     DWORD BytesRead = 0;
  446.     const int bufferSize = 1024; // 定义缓冲区大小
  447.     unsigned char RXBuff[bufferSize]; // 定义缓冲区

  448.     for(;;)
  449.     {
  450.         EnterCriticalSection(&port->m_csCommunicationSync);
  451.         bResult = ClearCommError(port->m_hComm, &dwError, &comstat);
  452.         LeaveCriticalSection(&port->m_csCommunicationSync);

  453.         if(comstat.cbInQue == 0)
  454.         {
  455.             break;
  456.         }

  457.         EnterCriticalSection(&port->m_csCommunicationSync);

  458.         if(bRead)
  459.         {
  460.             bResult = ReadFile(port->m_hComm,       // Handle to COMM port
  461.                                RXBuff,              // RX Buffer Pointer
  462.                                bufferSize,          // Read bufferSize bytes
  463.                                &BytesRead,          // Stores number of bytes read
  464.                                &port->m_ov);        // pointer to the m_ov structure
  465.             if(!bResult)
  466.             {
  467.                 switch(dwError = GetLastError())
  468.                 {
  469.                 case ERROR_IO_PENDING:
  470.                     bRead = FALSE;
  471.                     break;

  472.                 default:
  473.                     port->ProcessErrorMessage("ReadFile()");
  474.                     break;
  475.                 }
  476.             }
  477.             else
  478.             {
  479.                 bRead = TRUE;
  480.             }
  481.         }

  482.         if(!bRead)
  483.         {
  484.             bRead = TRUE;
  485.             bResult = GetOverlappedResult(port->m_hComm,    // Handle to COMM port
  486.                                           &port->m_ov,      // Overlapped structure
  487.                                           &BytesRead,       // Stores number of bytes read
  488.                                           TRUE);            // Wait flag
  489.             if(!bResult)
  490.             {
  491.                 port->ProcessErrorMessage("GetOverlappedResults() in ReadFile()");
  492.             }
  493.         }

  494.         LeaveCriticalSection(&port->m_csCommunicationSync);

  495.         for(DWORD i = 0; i < BytesRead; ++i)
  496.         {
  497.             port->m_RxRingBuffer.buffer[port->m_RxRingBuffer.in++] = RXBuff[i];

  498.             if(port->m_RxRingBuffer.in >= MAX_RING_LEN)
  499.             {
  500.                 port->m_RxRingBuffer.in = 0;
  501.             }
  502.         } // end forever loop

  503.                 ::PostMessage((port->m_pOwner)->m_hWnd, WM_COMM_RXCHAR, 1, (LPARAM) port->m_nPortNr);
  504.     }
  505. }
  506. //
  507. // Write a string to the port
  508. //
  509. void CSerialPort::WriteToPort(char * string)
  510. {
  511.     assert(m_hComm != 0);

  512.     memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
  513.     strcpy(m_szWriteBuffer, string);
  514.     m_nWriteSize = strlen(string);

  515.     // set event for write
  516.     SetEvent(m_hWriteEvent);
  517. }


  518. void CSerialPort::WriteToPort(char * string, int n)
  519. {
  520.     assert(m_hComm != 0);

  521.     memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
  522. //  memset(m_szWriteBuffer, 0, n);
  523. //  strncpy(m_szWriteBuffer, string, n);
  524.     memcpy(m_szWriteBuffer, string, n);
  525.     m_nWriteSize = n;

  526.     // set event for write
  527.     SetEvent(m_hWriteEvent);
  528. }

  529. void CSerialPort::WriteToPort(LPCTSTR string)
  530. {
  531.     assert(m_hComm != 0);

  532.     memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
  533.     strcpy(m_szWriteBuffer, string);
  534.     m_nWriteSize = strlen(string);

  535.     // set event for write
  536.     SetEvent(m_hWriteEvent);
  537. }

  538. void CSerialPort::WriteToPort(LPCTSTR string, int n)
  539. {
  540.     assert(m_hComm != 0);

  541.     memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
  542. //  strncpy(m_szWriteBuffer, string, n);
  543.     memcpy(m_szWriteBuffer, string, n);
  544.     m_nWriteSize = n;
  545.     // set event for write
  546.     SetEvent(m_hWriteEvent);
  547. }

  548. //
  549. // Return the device control block
  550. //
  551. DCB CSerialPort::GetDCB()
  552. {
  553.     return m_dcb;
  554. }

  555. //
  556. // Return the communication event masks
  557. //
  558. DWORD CSerialPort::GetCommEvents()
  559. {
  560.     return m_dwCommEvents;
  561. }

  562. //
  563. // Return the output buffer size
  564. //
  565. DWORD CSerialPort::GetWriteBufferSize()
  566. {
  567.     return m_nWriteBufferSize;
  568. }


  569. void CSerialPort::ClosePort()
  570. {
  571.     SetEvent(m_hShutdownEvent);
  572. }

  573. void CSerialPort::ProcessData(void)
  574. {

  575. }
  576. /*
  577. void CSerialPort::ClosePort()
  578. {
  579.     do
  580.     {
  581.         SetEvent(m_hShutdownEvent);
  582.     } while (m_bThreadAlive);


  583.     // if the port is still opened: close it
  584.     if (m_hComm != NULL)
  585.     {
  586.         CloseHandle(m_hComm);
  587.         m_hComm = NULL;
  588.     }
  589.     // Close Handles
  590.     if(m_hShutdownEvent!=NULL)
  591.         CloseHandle( m_hShutdownEvent);
  592.     if(m_ov.hEvent!=NULL)
  593.         CloseHandle( m_ov.hEvent );
  594.     if(m_hWriteEvent!=NULL)
  595.         CloseHandle( m_hWriteEvent );

  596.     TRACE("Thread ended\n");
  597.     delete [] m_szWriteBuffer;
  598. }

  599. */
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出130入129汤圆

 楼主| 发表于 昨天 19:04 | 显示全部楼层
估计代码不够严谨,问了下人工智能助手Copilot,
帮我改了发送函数,这下发送正常了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出200入2554汤圆

发表于 昨天 20:50 来自手机 | 显示全部楼层
bushound 试试看哪里卡住了?

CDC 本来就是标准的抽象设备,不该跑不通

出0入0汤圆

发表于 昨天 21:19 | 显示全部楼层
震惊到了
Copilot都能改代码了?
而且这个代码不是玩具。
那么,问题来了
你是怎么问的Copilot呢?

出130入129汤圆

 楼主| 发表于 昨天 21:51 | 显示全部楼层
t3486784401 发表于 2024-7-26 20:50
bushound 试试看哪里卡住了?

CDC 本来就是标准的抽象设备,不该跑不通
(引用自3楼)

我软件调试能力不行啊,看原先代码也是调用WriteChar的,里面也是异步方式。
Copilot给我改的代码只是一个函数完成了发送,跟通过事件然后调用WriteChar区别好像也不大。
我也试着将WriteChar里面代码改成跟Copilot的一样方式,能在Serial Port Monitor看到有往下位机发送的字符,但是实际 下位机并没有收到。
所以我也判断不出什么问题了。
我随时切换串口助手,发送一个字符到下位机,下位机是随时能响应的,所以下位机是没什么问题的,这个发送的字符就是有时监控软件看着发下来了,实际没有收到。

出130入129汤圆

 楼主| 发表于 昨天 21:54 | 显示全部楼层
tuy0326 发表于 2024-7-26 21:19
震惊到了
Copilot都能改代码了?
而且这个代码不是玩具。
(引用自4楼)

我就把函数发给Copilot,告诉他这函数有时无法发送成功,他自己就懂事去修改了
真不是玩具,完全就是生产力工具

出200入2554汤圆

发表于 昨天 22:17 | 显示全部楼层
68336016 发表于 2024-7-26 21:51
我软件调试能力不行啊,看原先代码也是调用WriteChar的,里面也是异步方式。
Copilot给我改的代码只是一 ...
(引用自5楼)

win32 下边是以文件的方式访问 CDC 串口的,楼主位这个串口类不知是否也用到了这一层 API:

::CreateFile 就是打开串口, ::CloseFile 就是关闭串口;
::WriteFile 就是发送,::ReadFile 对应接收。

以前最早做串口的时候,用的是 mscomm32;后来这控件又是限制数目又是新系统不兼容的,索性全换了 Win32-API 方式。
然后就舒坦了,从 XP 一直到 win10 都兼容,而且不需额外安装插件
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-27 20:20

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表