串口调试_串口调试助手 - CSDN
精华内容
参与话题
  • 常用串口调试工具比较(详细)

    万次阅读 2018-03-30 08:55:43
    目前有许多免费的串口调试工具,比较常用的有:1、友善串口调试助手(v2.6.5)优点: 1)使用方便,不丢包; 2)串口自动识别,支持COM9以上串口; 3)支持多串口调试; 4)支持历史发送记录; 5)广泛支持各种...

    目前有许多免费的串口调试工具,比较常用的有:

    1、友善串口调试助手(v2.6.5)

    优点: 
    1)使用方便,不丢包; 
    2)串口自动识别,支持COM9以上串口; 
    3)支持多串口调试; 
    4)支持历史发送记录; 
    5)广泛支持各种波特率,高达10 Mbps以上波特率,具体和电脑硬件有关。 

    下载地址:http://rj.baidu.com/soft/detail/27520.html?ald

    缺点:会丢失数据,刷屏显示不流畅,不适合稳定性测试。

    2、串口调试助手(V2.2) 
    优点: 
    使用方便,用户群最多,有书介绍及免费源代码。 
    缺点: 
    1)因采用多线程接收技术,接收有时丢数,特别在高波特率或使用USB转串口时丢数较多。 
    2)最大只支持115.2K波特率。 
    3)只能选COM1~COM2,使用USB转串口时,要重新映射串口。

    3、SSCOM3.2 
    优点: 
    支持自动识别已连接串口设备,使用方便,接收不丢数。 稳定性效果好。界面简洁,用户体验很好。
    缺点: 

    连接状态插拔串口程序会崩溃,导致电脑蓝屏。高波特率只有115.2K、128K、256K,没有230.4K。

    作为控制台,不支持回显。win10下不支持保存显示数据。

    个人比较推荐,用了很多年。后面的新版都没这个版本好用,虽然新版增加了很多功能。

    4、PCOMAPR1.5(pcomtest) 
    优点: 
    波特率高,最高达921.6K,接收不丢数。 
    缺点: 
    只有COM1~COM4可选,使用USB转串口时,要重新映射串口。

    5、Accesport1.33 
    优点: 
    功能强,配置参数多,接收不丢数。 
    缺点: 

    波特率较高时(如230.4K),如果接收数据量大(比量接收),则无法发送数据。

    展开全文
  • 串口调试助手V2.2;串口调试软件sscom32;GSM串口调试助手;GPS多功能调试助手;网络调试助手NetAssist; USB转串口线驱动;汉字和Unicode互换小工具;中英文字符编码查询。
  • 最全的串口调试工具

    2018-09-26 15:44:05
    最全的串口调试工具,总有一款适合。 1)使用方便,不丢包; 2)串口自动识别; 3)支持多串口调试; 4)支持历史发送记录; 5)广泛支持各种波特率。
  • 串口调试助手源码(绝对正版)

    千次下载 热门讨论 2008-03-29 19:35:16
    自己买的一本串口编程的书上代的源码,感觉相当不错,简直可以卖钱了,分享给大家。自己买的一本串口编程的书上代的源码,感觉相当不错,简直可以卖钱了,分享给大家。自己买的一本串口编程的书上代的源码,感觉相当...
  • 串口调试工具

    2019-02-19 08:51:38
    一款串口调试工具,适用上位机,下位机的软件开发和调试工作。
  • MFC串口调试工具教程

    千次阅读 2016-05-18 15:00:41
    MFC串口调试软件教程 一、测试环境:Windows XP,VC++6.0 二、步骤 Step1:打开VC++6.0集成开发环境,新建基于对话框(Dialog based)的MFCAppWizard(exe)应用程序。其它设置默认即可。 Step2:在主对话框中添加需要...

    MFC串口调试软件教程

    一、测试环境:Windows XP,VC++6.0

    二、步骤

    Step1:打开VC++6.0集成开发环境,新建基于对话框(Dialog based)的MFCAppWizard(exe)应用程序。其它设置默认即可。


    Step2:在主对话框中添加需要的控件。如图1,在箭头所指窗口(控件)拖动空间到主对话框。这里串口调试软件只需要红框内所示的控件即可,其他可以根据需要自行添加。右键点击控件 ->选择属性可以自行设置控件显示的文本,例如图1中的“打开”按钮、“端口号”静态文本等。另外,为了增强变量的可读性,建议将每个控件的ID改成有意义的名字。例如,将发送按钮的控件ID改为“IDC_BUTTON_SEND”。



    Step3:接下来需要为个别控件添加变量,以便于在程序中读取控件状态或者获得对控件的控制。例如,对“端口号”右边的组合下拉框(Combo)添加变量。右键点击组合框(Combo) ->选择建立类向导,则会出现如图2所示界面。按照图2中1->2->3步骤操作。点击确定出现图3界面。按照图3中1->2步骤操作,确定则成功添加control类型的变量m_ctrlComboComPort。



    接下来,依次为接收数据和发送数据旁的编辑框添加Cstring类型的变量m_strEditReceiveMsg和m_strEditSendMsg

    Step4:为了将CserialPort类添加到工程中,需要添加“SerialPort.h”和”SerialPort.cpp”文件。将文件添加到工程所在的文件夹中,然后,点击菜单栏上的工程 ->添加到工程 ->文件,选择这两个文件。添加结果如图4所示。

     

    Step5:在对话框头文件(这里是“RBT_GZZDlg.h”)添加头文件声明(#include “CserialPort.h”)和类对象声明(CserialPort m_SerialPort)以及变量名声明(BOOLm_bSSerialPortOpened串口打开标志位)。如图5所示。


     Step6:在对话框头文件(本工程是“RBT_GZZDlg.h”)添加串口字符接受消息(WM_COM_RXCHAR)的响应函数声明afx_msg LONG OnCom(WPARAM ch, LPARAM port),并在对话框CPP(本工程是“RBT_GZZDlg.cpp”)文件中进行WM_COM_RXCHAR消息映射和函数的实现代码。如图6所示。


    Step7:接下来对“打开”按钮、“关闭”按钮和“发送“按钮添加响应函数。双击”打开“按钮,出现生成函数提示框,点击确定进入函数(本工程是void CRBT_GZZDlg::OnButtonOpen())。该函数主要是实现获取串口号、设置串口通信的参数功能。

    类似操作添加void CRBT_GZZDlg::OnButtonClose()和voidCRBT_GZZDlg::OnButtonSend()函数。关闭函数主要就是关闭串口;发送函数先获取编辑框内的数据,然后以字符串或者十六进制格式发送数据,具体由编程决定。本工程发送十六进制,所以添加了Str2Hex函数和HexChar函数对数据进行处理。

    如图7、8所示为本工程添加的函数。



    需要注意的是”打开“按钮响应函数中从组合框获取串口号(intnPort=m_ctrlComboComPort.GetCurel()+1),所以需要在对话框CPP文件中的初始化函数(BOOL CEx2Dlg::OnInitDialog())中添加如图9所示初始化函数。


    Step8:编译 -> 执行。如图10所示,开始执行后,点击”打开“按钮,串口开始接收数据。

     

    三、常见问题

    1.无法添加控件(cannot add new member)

       解决方法:先把工程关闭,然后删除*.clw文件,重新打开工程,打开ClassWizard(CTRL+W可以打开),输入先前删除的文件的文件名(*.clw)。点击添加按钮(ADD),然后确定。这样便可以添加控件了。

    (参考网址:http://m.2cto.com/kf/201212/173233.html)

    2.编译没有问题,无法执行(Could not execute:Bad executable format(Win32 error 193))。如图11所示。


    解决方法:这个是VC++经常出现的问题。Error193是操作系统错误,通常是生成的exe文件损坏或者格式错误。网上的解答最多的是”在工程设置里将Link选项设置正确就行了“,但是,这个方法并不是万能的。

    我发现的一种出现这种错误的原因是向工程添加的文件的日期与系统日期不一致,通常是在”未来时“,所以可以先检查所添加的文件的日期。如果是该错误,则在工程中打开该文件,然后,修改一下重新保存即可。最后,点击Clean –> Rebuild ->执行。错误消失。

    如果上述方法仍不奏效的话,则点击Clean,然后直接点击执行(即那个红色的感叹号),不要点击Build或者Rebuild。错误消失。

    四、相关文件(来自书本《串口通信编程实践》电子工业出版社,请勿用于商业用途)

    1.”SerialPort.h”

    /*
    **	FILENAME			CSerialPort.h
    **
    **	PURPOSE				This class can read, write and watch one serial port.
    **						It sends messages to its owner when something happends on the port
    **						The class creates a thread for reading and writing so the main
    **						program is not blocked.
    **
    **	CREATION DATE		15-09-1997
    **	LAST MODIFICATION	12-11-1997
    **
    **	AUTHOR				Remon Spekreijse
    **
    **
    */
    
    #ifndef __SERIALPORT_H__
    #define __SERIALPORT_H__
    
    #define WM_COMM_BREAK_DETECTED		WM_USER+1	// A break was detected on input.
    #define WM_COMM_CTS_DETECTED		WM_USER+2	// The CTS (clear-to-send) signal changed state. 
    #define WM_COMM_DSR_DETECTED		WM_USER+3	// The DSR (data-set-ready) signal changed state. 
    #define WM_COMM_ERR_DETECTED		WM_USER+4	// A line-status error occurred. Line-status errors are CE_FRAME, CE_OVERRUN, and CE_RXPARITY. 
    #define WM_COMM_RING_DETECTED		WM_USER+5	// A ring indicator was detected. 
    #define WM_COMM_RLSD_DETECTED		WM_USER+6	// The RLSD (receive-line-signal-detect) signal changed state. 
    #define WM_COMM_RXCHAR				WM_USER+7	// A character was received and placed in the input buffer. 
    #define WM_COMM_RXFLAG_DETECTED		WM_USER+8	// The event character was received and placed in the input buffer.  
    #define WM_COMM_TXEMPTY_DETECTED	WM_USER+9	// The last character in the output buffer was sent.  
    
    class CSerialPort
    {														 
    public:
    	// contruction and destruction
    	CSerialPort();
    	virtual		~CSerialPort();
    
    	// port initialisation											
    	BOOL		InitPort(CWnd* pPortOwner, UINT portnr = 1, UINT baud = 19200, char parity = 'N', UINT databits = 8, UINT stopsbits = 1, DWORD dwCommEvents = EV_RXCHAR | EV_CTS, UINT nBufferSize = 512);
    
    	// start/stop comm watching
    	BOOL		StartMonitoring();
    	BOOL		RestartMonitoring();
    	BOOL		StopMonitoring();
     
    	DWORD		GetWriteBufferSize();
    	DWORD		GetCommEvents();
    	DCB			GetDCB();
    	int			m_nWriteSize;
    	void		WriteToPort(char* string);
    	void		WriteToPort(char* string, int n);
    	void		WriteToPort(LPCTSTR string);
    	void		WriteToPort(LPCTSTR string, int n);
    protected:
    	// protected memberfunctions
    	void		ProcessErrorMessage(char* ErrorText);
    	static UINT	CommThread(LPVOID pParam);
    	static void	ReceiveChar(CSerialPort* port, COMSTAT comstat);
    	static void	WriteChar(CSerialPort* port);
    
    	// thread
    	CWinThread*			m_Thread;
    
    	// synchronisation objects
    	CRITICAL_SECTION	m_csCommunicationSync;
    	BOOL				m_bThreadAlive;
    
    	// handles
    	HANDLE				m_hShutdownEvent;
    	HANDLE				m_hComm;
    	HANDLE				m_hWriteEvent;
    
    	// Event array. 
    	// One element is used for each event. There are two event handles for each port.
    	// A Write event and a receive character event which is located in the overlapped structure (m_ov.hEvent).
    	// There is a general shutdown when the port is closed. 
    	HANDLE				m_hEventArray[3];
    
    	// structures
    	OVERLAPPED			m_ov;
    	COMMTIMEOUTS		m_CommTimeouts;
    	DCB					m_dcb;
    
    	// owner window
    	CWnd*				m_pOwner;
    
    	// misc
    	UINT				m_nPortNr;
    	char*				m_szWriteBuffer;
    	DWORD				m_dwCommEvents;
    	DWORD				m_nWriteBufferSize;
    };
    
    #endif __SERIALPORT_H__
    

    2.”SerialPort.cpp”

    /*
    **	FILENAME			CSerialPort.cpp
    **
    **	PURPOSE				This class can read, write and watch one serial port.
    **						It sends messages to its owner when something happends on the port
    **						The class creates a thread for reading and writing so the main
    **						program is not blocked.
    **
    **	CREATION DATE		15-09-1997
    **	LAST MODIFICATION	12-11-1997
    **
    **	AUTHOR				Remon Spekreijse
    **
    **
    */
    
    #include "stdafx.h"
    #include "SerialPort.h"
    
    #include <assert.h>
     
    //
    // Constructor
    //
    CSerialPort::CSerialPort()
    {
    	m_hComm = NULL;
    
    	// initialize overlapped structure members to zero
    	m_ov.Offset = 0;
    	m_ov.OffsetHigh = 0;
    
    	// create events
    	m_ov.hEvent = NULL;
    	m_hWriteEvent = NULL;
    	m_hShutdownEvent = NULL;
    
    	m_szWriteBuffer = NULL;
    
    	m_bThreadAlive = FALSE;
    }
    
    //
    // Delete dynamic memory
    //
    CSerialPort::~CSerialPort()
    {
    	do
    	{
    		SetEvent(m_hShutdownEvent);
    	} while (m_bThreadAlive);
    
    	TRACE("Thread ended\n");
    
    	delete [] m_szWriteBuffer;
    }
    
    //
    // Initialize the port. This can be port 1 to 4.
    //
    BOOL CSerialPort::InitPort(CWnd* pPortOwner,	// the owner (CWnd) of the port (receives message)
    						   UINT  portnr,		// portnumber (1..4)
    						   UINT  baud,			// baudrate
    						   char  parity,		// parity 
    						   UINT  databits,		// databits 
    						   UINT  stopbits,		// stopbits 
    						   DWORD dwCommEvents,	// EV_RXCHAR, EV_CTS etc
    						   UINT  writebuffersize)	// size to the writebuffer
    {
    	//assert(portnr > 0 && portnr < 5);
    	assert(pPortOwner != NULL);
    
    	// if the thread is alive: Kill
    	if (m_bThreadAlive)
    	{
    		do
    		{
    			SetEvent(m_hShutdownEvent);
    		} while (m_bThreadAlive);
    		TRACE("Thread ended\n");
    	}
    
    	// create events
    	if (m_ov.hEvent != NULL)
    		ResetEvent(m_ov.hEvent);
    	m_ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    
    	if (m_hWriteEvent != NULL)
    		ResetEvent(m_hWriteEvent);
    	m_hWriteEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    	
    	if (m_hShutdownEvent != NULL)
    		ResetEvent(m_hShutdownEvent);
    	m_hShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    
    	// initialize the event objects
    	m_hEventArray[0] = m_hShutdownEvent;	// highest priority
    	m_hEventArray[1] = m_ov.hEvent;
    	m_hEventArray[2] = m_hWriteEvent;
    
    	// initialize critical section
    	InitializeCriticalSection(&m_csCommunicationSync);
    	
    	// set buffersize for writing and save the owner
    	m_pOwner = pPortOwner;
    
    	if (m_szWriteBuffer != NULL)
    		delete [] m_szWriteBuffer;
    	m_szWriteBuffer = new char[writebuffersize];
    
    	m_nPortNr = portnr;
    
    	m_nWriteBufferSize = writebuffersize;
    	m_dwCommEvents = dwCommEvents;
    
    	BOOL bResult = FALSE;
    	char *szPort = new char[50];
    	char *szBaud = new char[50];
    
    	// now it critical!
    	EnterCriticalSection(&m_csCommunicationSync);
    
    	// if the port is already opened: close it
    	if (m_hComm != NULL)
    	{
    		CloseHandle(m_hComm);
    		m_hComm = NULL;
    	}
    
    	// prepare port strings
    	sprintf(szPort, "COM%d", portnr);
    	sprintf(szBaud, "baud=%d parity=%c data=%d stop=%d", baud, parity, databits, stopbits);
    
    	// get a handle to the port
    	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)
    	{
    		// port not found
    		delete [] szPort;
    		delete [] szBaud;
    
    		return FALSE;
    	}
    
    	// set the timeout values
    	m_CommTimeouts.ReadIntervalTimeout = 1000;
    	m_CommTimeouts.ReadTotalTimeoutMultiplier = 1000;
    	m_CommTimeouts.ReadTotalTimeoutConstant = 1000;
    	m_CommTimeouts.WriteTotalTimeoutMultiplier = 1000;
    	m_CommTimeouts.WriteTotalTimeoutConstant = 1000;
    
    	// configure
    	if (SetCommTimeouts(m_hComm, &m_CommTimeouts))
    	{						   
    		if (SetCommMask(m_hComm, dwCommEvents))
    		{
    			if (GetCommState(m_hComm, &m_dcb))
    			{
    				m_dcb.fRtsControl = RTS_CONTROL_ENABLE;		// set RTS bit high!
    				if (BuildCommDCB(szBaud, &m_dcb))
    				{
    					if (SetCommState(m_hComm, &m_dcb))
    						; // normal operation... continue
    					else
    						ProcessErrorMessage("SetCommState()");
    				}
    				else
    					ProcessErrorMessage("BuildCommDCB()");
    			}
    			else
    				ProcessErrorMessage("GetCommState()");
    		}
    		else
    			ProcessErrorMessage("SetCommMask()");
    	}
    	else
    		ProcessErrorMessage("SetCommTimeouts()");
    
    	delete [] szPort;
    	delete [] szBaud;
    
    	// flush the port
    	PurgeComm(m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
    
    	// release critical section
    	LeaveCriticalSection(&m_csCommunicationSync);
    
    	TRACE("Initialisation for communicationport %d completed.\nUse Startmonitor to communicate.\n", portnr);
    
    	return TRUE;
    }
    
    //
    //  The CommThread Function.
    //
    UINT CSerialPort::CommThread(LPVOID pParam)
    {
    	// Cast the void pointer passed to the thread back to
    	// a pointer of CSerialPort class
    	CSerialPort *port = (CSerialPort*)pParam;
    	
    	// Set the status variable in the dialog class to
    	// TRUE to indicate the thread is running.
    	port->m_bThreadAlive = TRUE;	
    		
    	// Misc. variables
    	DWORD BytesTransfered = 0; 
    	DWORD Event = 0;
    	DWORD CommEvent = 0;
    	DWORD dwError = 0;
    	COMSTAT comstat;
    	BOOL  bResult = TRUE;
    		
    	// Clear comm buffers at startup
    	if (port->m_hComm)		// check if the port is opened
    		PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
    
    	// begin forever loop.  This loop will run as long as the thread is alive.
    	for (;;) 
    	{ 
    
    		// Make a call to WaitCommEvent().  This call will return immediatly
    		// because our port was created as an async port (FILE_FLAG_OVERLAPPED
    		// and an m_OverlappedStructerlapped structure specified).  This call will cause the 
    		// m_OverlappedStructerlapped element m_OverlappedStruct.hEvent, which is part of the m_hEventArray to 
    		// be placed in a non-signeled state if there are no bytes available to be read,
    		// or to a signeled state if there are bytes available.  If this event handle 
    		// is set to the non-signeled state, it will be set to signeled when a 
    		// character arrives at the port.
    
    		// we do this for each port!
    
    		bResult = WaitCommEvent(port->m_hComm, &Event, &port->m_ov);
    
    		if (!bResult)  
    		{ 
    			// If WaitCommEvent() returns FALSE, process the last error to determin
    			// the reason..
    			switch (dwError = GetLastError()) 
    			{ 
    			case ERROR_IO_PENDING: 	
    				{ 
    					// This is a normal return value if there are no bytes
    					// to read at the port.
    					// Do nothing and continue
    					break;
    				}
    			case 87:
    				{
    					// Under Windows NT, this value is returned for some reason.
    					// I have not investigated why, but it is also a valid reply
    					// Also do nothing and continue.
    					break;
    				}
    			default:
    				{
    					// All other error codes indicate a serious error has
    					// occured.  Process this error.
    					port->ProcessErrorMessage("WaitCommEvent()");
    					break;
    				}
    			}
    		}
    		else
    		{
    			// If WaitCommEvent() returns TRUE, check to be sure there are
    			// actually bytes in the buffer to read.  
    			//
    			// If you are reading more than one byte at a time from the buffer 
    			// (which this program does not do) you will have the situation occur 
    			// where the first byte to arrive will cause the WaitForMultipleObjects() 
    			// function to stop waiting.  The WaitForMultipleObjects() function 
    			// resets the event handle in m_OverlappedStruct.hEvent to the non-signelead state
    			// as it returns.  
    			//
    			// If in the time between the reset of this event and the call to 
    			// ReadFile() more bytes arrive, the m_OverlappedStruct.hEvent handle will be set again
    			// to the signeled state. When the call to ReadFile() occurs, it will 
    			// read all of the bytes from the buffer, and the program will
    			// loop back around to WaitCommEvent().
    			// 
    			// At this point you will be in the situation where m_OverlappedStruct.hEvent is set,
    			// but there are no bytes available to read.  If you proceed and call
    			// ReadFile(), it will return immediatly due to the async port setup, but
    			// GetOverlappedResults() will not return until the next character arrives.
    			//
    			// It is not desirable for the GetOverlappedResults() function to be in 
    			// this state.  The thread shutdown event (event 0) and the WriteFile()
    			// event (Event2) will not work if the thread is blocked by GetOverlappedResults().
    			//
    			// The solution to this is to check the buffer with a call to ClearCommError().
    			// This call will reset the event handle, and if there are no bytes to read
    			// we can loop back through WaitCommEvent() again, then proceed.
    			// If there are really bytes to read, do nothing and proceed.
    		
    			bResult = ClearCommError(port->m_hComm, &dwError, &comstat);
    
    			if (comstat.cbInQue == 0)
    				continue;
    		}	// end if bResult
    
    		// Main wait function.  This function will normally block the thread
    		// until one of nine events occur that require action.
    		Event = WaitForMultipleObjects(3, port->m_hEventArray, FALSE, INFINITE);
    
    		switch (Event)
    		{
    		case 0:
    			{
    				// Shutdown event.  This is event zero so it will be
    				// the higest priority and be serviced first.
    
    			 	port->m_bThreadAlive = FALSE;
    				
    				// Kill this thread.  break is not needed, but makes me feel better.
    				AfxEndThread(100);
    				break;
    			}
    		case 1:	// read event
    			{
    				GetCommMask(port->m_hComm, &CommEvent);
    				if (CommEvent & EV_CTS)
    					::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_CTS_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
    				if (CommEvent & EV_RXFLAG)
    					::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_RXFLAG_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
    				if (CommEvent & EV_BREAK)
    					::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_BREAK_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
    				if (CommEvent & EV_ERR)
    					::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_ERR_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
    				if (CommEvent & EV_RING)
    					::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_RING_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr);
    				
    				if (CommEvent & EV_RXCHAR)
    					// Receive character event from port.
    					ReceiveChar(port, comstat);
    					
    				break;
    			}  
    		case 2: // write event
    			{
    				// Write character event from port
    				WriteChar(port);
    				break;
    			}
    
    		} // end switch
    
    	} // close forever loop
    
    	return 0;
    }
    
    //
    // start comm watching
    //
    BOOL CSerialPort::StartMonitoring()
    {
    	if (!(m_Thread = AfxBeginThread(CommThread, this)))
    		return FALSE;
    	TRACE("Thread started\n");
    	return TRUE;	
    }
    
    //
    // Restart the comm thread
    //
    BOOL CSerialPort::RestartMonitoring()
    {
    	TRACE("Thread resumed\n");
    	m_Thread->ResumeThread();
    	return TRUE;	
    }
    
    
    //
    // Suspend the comm thread
    //
    BOOL CSerialPort::StopMonitoring()
    {
    	TRACE("Thread suspended\n");
    	m_Thread->SuspendThread(); 
    	return TRUE;	
    }
    
    
    //
    // If there is a error, give the right message
    //
    void CSerialPort::ProcessErrorMessage(char* ErrorText)
    {
    	char *Temp = new char[200];
    	
    	LPVOID lpMsgBuf;
    
    	FormatMessage( 
    		FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
    		NULL,
    		GetLastError(),
    		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
    		(LPTSTR) &lpMsgBuf,
    		0,
    		NULL 
    	);
    
    	sprintf(Temp, "WARNING:  %s Failed with the following error: \n%s\nPort: %d\n", (char*)ErrorText, lpMsgBuf, m_nPortNr); 
    	MessageBox(NULL, Temp, "Application Error", MB_ICONSTOP);
    
    	LocalFree(lpMsgBuf);
    	delete[] Temp;
    }
    
    //
    // Write a character.
    //
    void CSerialPort::WriteChar(CSerialPort* port)
    {
    	BOOL bWrite = TRUE;
    	BOOL bResult = TRUE;
    
    	DWORD BytesSent = 0;
    
    	ResetEvent(port->m_hWriteEvent);
    
    	// Gain ownership of the critical section
    	EnterCriticalSection(&port->m_csCommunicationSync);
    
    	if (bWrite)
    	{
    		// Initailize variables
    		port->m_ov.Offset = 0;
    		port->m_ov.OffsetHigh = 0;
    
    		// Clear buffer
    		PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);
    
    		bResult = WriteFile(port->m_hComm,							// Handle to COMM Port
    							port->m_szWriteBuffer,					// Pointer to message buffer in calling finction
    							port->m_nWriteSize,	// Length of message to send//strlen((char*)port->m_szWriteBuffer)
    							&BytesSent,								// Where to store the number of bytes sent
    							&port->m_ov);							// Overlapped structure
    
    		// deal with any error codes
    		if (!bResult)  
    		{
    			DWORD dwError = GetLastError();
    			switch (dwError)
    			{
    				case ERROR_IO_PENDING:
    					{
    						// continue to GetOverlappedResults()
    						BytesSent = 0;
    						bWrite = FALSE;
    						break;
    					}
    				default:
    					{
    						// all other error codes
    						port->ProcessErrorMessage("WriteFile()");
    					}
    			}
    		} 
    		else
    		{
    			LeaveCriticalSection(&port->m_csCommunicationSync);
    		}
    	} // end if(bWrite)
    
    	if (!bWrite)
    	{
    		bWrite = TRUE;
    	
    		bResult = GetOverlappedResult(port->m_hComm,	// Handle to COMM port 
    									  &port->m_ov,		// Overlapped structure
    									  &BytesSent,		// Stores number of bytes sent
    									  TRUE); 			// Wait flag
    
    		LeaveCriticalSection(&port->m_csCommunicationSync);
    
    		// deal with the error code 
    		if (!bResult)  
    		{
    			port->ProcessErrorMessage("GetOverlappedResults() in WriteFile()");
    		}	
    	} // end if (!bWrite)
    
    	// Verify that the data size send equals what we tried to send
    	//if (BytesSent != strlen((char*)port->m_szWriteBuffer))
    	if (BytesSent != port->m_nWriteSize)
    	{
    		TRACE("WARNING: WriteFile() error.. Bytes Sent: %d; Message Length: %d\n", BytesSent, strlen((char*)port->m_szWriteBuffer));
    	}
    }
    
    //
    // Character received. Inform the owner
    //
    void CSerialPort::ReceiveChar(CSerialPort* port, COMSTAT comstat)
    {
    	BOOL  bRead = TRUE; 
    	BOOL  bResult = TRUE;
    	DWORD dwError = 0;
    	DWORD BytesRead = 0;
    	unsigned char RXBuff;
    
    	for (;;) 
    	{ 
    		// Gain ownership of the comm port critical section.
    		// This process guarantees no other part of this program 
    		// is using the port object. 
    		
    		EnterCriticalSection(&port->m_csCommunicationSync);
    
    		// ClearCommError() will update the COMSTAT structure and
    		// clear any other errors.
    		
    		bResult = ClearCommError(port->m_hComm, &dwError, &comstat);
    
    		LeaveCriticalSection(&port->m_csCommunicationSync);
    
    		// start forever loop.  I use this type of loop because I
    		// do not know at runtime how many loops this will have to
    		// run. My solution is to start a forever loop and to
    		// break out of it when I have processed all of the
    		// data available.  Be careful with this approach and
    		// be sure your loop will exit.
    		// My reasons for this are not as clear in this sample 
    		// as it is in my production code, but I have found this 
    		// solutiion to be the most efficient way to do this.
    		
    		if (comstat.cbInQue == 0)
    		{
    			// break out when all bytes have been read
    			break;
    		}
    						
    		EnterCriticalSection(&port->m_csCommunicationSync);
    
    		if (bRead)
    		{
    			bResult = ReadFile(port->m_hComm,		// Handle to COMM port 
    							   &RXBuff,				// RX Buffer Pointer
    							   1,					// Read one byte
    							   &BytesRead,			// Stores number of bytes read
    							   &port->m_ov);		// pointer to the m_ov structure
    			// deal with the error code 
    			if (!bResult)  
    			{ 
    				switch (dwError = GetLastError()) 
    				{ 
    					case ERROR_IO_PENDING: 	
    						{ 
    							// asynchronous i/o is still in progress 
    							// Proceed on to GetOverlappedResults();
    							bRead = FALSE;
    							break;
    						}
    					default:
    						{
    							// Another error has occured.  Process this error.
    							port->ProcessErrorMessage("ReadFile()");
    							break;
    						} 
    				}
    			}
    			else
    			{
    				// ReadFile() returned complete. It is not necessary to call GetOverlappedResults()
    				bRead = TRUE;
    			}
    		}  // close if (bRead)
    
    		if (!bRead)
    		{
    			bRead = TRUE;
    			bResult = GetOverlappedResult(port->m_hComm,	// Handle to COMM port 
    										  &port->m_ov,		// Overlapped structure
    										  &BytesRead,		// Stores number of bytes read
    										  TRUE); 			// Wait flag
    
    			// deal with the error code 
    			if (!bResult)  
    			{
    				port->ProcessErrorMessage("GetOverlappedResults() in ReadFile()");
    			}	
    		}  // close if (!bRead)
    				
    		LeaveCriticalSection(&port->m_csCommunicationSync);
    
    		// notify parent that a byte was received
    		::SendMessage((port->m_pOwner)->m_hWnd, WM_COMM_RXCHAR, (WPARAM) RXBuff, (LPARAM) port->m_nPortNr);
    	} // end forever loop
    
    }
    
    //
    // Write a string to the port
    //
    void CSerialPort::WriteToPort(char* string)
    {		
    	assert(m_hComm != 0);
    
    	memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
    	strcpy(m_szWriteBuffer, string);
    	m_nWriteSize=strlen(string);
    	// set event for write
    	SetEvent(m_hWriteEvent);
    }
    
    void CSerialPort::WriteToPort(char* string, int n)
    {		
    	assert(m_hComm != 0);
    
    	memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
    	memcpy(m_szWriteBuffer, string, n);
    	m_nWriteSize=n;
    
    	// set event for write
    	SetEvent(m_hWriteEvent);
    }
    
    void CSerialPort::WriteToPort(LPCTSTR string)
    {		
    	assert(m_hComm != 0);
    
    	memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
    	strcpy(m_szWriteBuffer, string);
    	m_nWriteSize=strlen(string);
    	// set event for write
    	SetEvent(m_hWriteEvent);
    }
    
    void CSerialPort::WriteToPort(LPCTSTR string, int n)
    {		
    	assert(m_hComm != 0);
    
    	memset(m_szWriteBuffer, 0, sizeof(m_szWriteBuffer));
    	memcpy(m_szWriteBuffer, string, n);
    	m_nWriteSize=n; 
    
    	// set event for write
    	SetEvent(m_hWriteEvent);
    }
    //
    // Return the device control block
    //
    DCB CSerialPort::GetDCB()
    {
    	return m_dcb;
    }
    
    //
    // Return the communication event masks
    //
    DWORD CSerialPort::GetCommEvents()
    {
    	return m_dwCommEvents;
    }
    
    //
    // Return the output buffer size
    //
    DWORD CSerialPort::GetWriteBufferSize()
    {
    	return m_nWriteBufferSize;
    }
    

    展开全文
  • 本人用过的最好串口调试软件,介绍给大家

    千次下载 热门讨论 2010-01-24 17:00:15
    串口监控器是一个免费的多功能串口通讯监控软件,它能够多种方式显示,接收,分析通讯数据;能够以多种灵活方式发送数据;功能强大,操作简便,在串口通讯监控,设备通讯测试中,能够有效提高工作效率。 主要功能...
  • 串口调试工具 历经半个月的时间,在安卓端的串口调试工具终于让我搞出来了,在之前已经有很多同道中人开发过相似的应用,但我认为还有很多功能没有挖掘出来,所以我决定开发一个更方便,更实用的串口调试工具。接...

    串口调试工具

        历经半个月的时间,在安卓端的串口调试工具终于让我搞出来了,在之前已经有很多同道中人开发过相似的应用,但我认为还有很多功能没有挖掘出来,所以我决定开发一个更方便,更实用的串口调试工具。接下来介绍这个 串口调试工具 的使用方法。并在后半部分通过“HC05蓝牙模块的配置过程”为例演示其强大的功能。

    需要的设备:

    用到的设备

        左图为OTG转接线,可以将安卓设备的充电接口转接为USB插口,告诉你一个秘密:此时如果你将鼠标插到OTG线的插口上,手机屏幕上就会出现一个鼠标箭头。正是因为安卓设备通过OTG线支持USB Host模式,才使手机的串口通信得以实现。

        右图为USB转串口模块,除了CH340外,我还添加了对PL2303 CP2102等USB转串口芯片的支持。同时支持一些常见的Arduino板。基本市面上所有的USB转串口模块都是支持的。

    收发模式:

        备齐了上述两个法宝之后,就可以进行串口调试了。将上述的两个设备连接到手机上,然后点开应用“串口调试工具”,就可进入下方画面:

     

    USB授权对话框

        点击确定,稍等几秒钟,设备就可以连接成功了,此时界面上方的状态栏会显示插入设备的名称,并在右边出现一个小开关用来控制设备开启与关闭。

     

    收发界面

        应用在收发模式的界面中,如上图,你可以在下面的输入框中输入要发送的数据,然后点击输入框右边的箭头按钮发送。另外应用支持HEX数据的输入,你可以输入诸如“FF AA 11 22”这种格式的数据,直接传递十六进制的字节码。应用支持定时发送数据,可自定义重发间隔,最高重发速率是20次每秒,即50~10000毫秒的设定范围。在上方的空白区域会显示历史收发数据的记录,点击右下方的“X”按钮可将区域清空。点击向下的箭头将焦点转移到最新的数据行。

    按钮模式:

    按钮功能

        除了收发模式外,应用还支持按钮形式的快捷发送,预留了12个可自定义的按钮,每次按下按钮,应用就会通过串口发送数据。长按可编辑按钮的发送内容、按钮显示名称等。在按钮设置的对话框中,可以设置按钮的显示名称和按钮按下时发送的数据,每次你编辑要发送的数据时,都可以在“字节数据预览”中看到你编辑的文本的字节码,这样可以用于单片机中的判断,更加方便。

    串口参数设置:

     

        最后是应用的串口参数设置界面,你可以在参数设置界面中设置串口模块的工作模式,比如波特率、数据位等,波特率最高可达921600。此外还可以在每次发送数据时在数据后面追加换行符,实现自动换行,这个功能对蓝牙模块参数配置等情况非常有帮助。最后是编码格式选择,当要收发含有中文的串口文本数据时,一定要确定收发双方的文本编码格式相同,如果不同则很可能出现乱码的情况。(如果你是使用KEIL,请在 edit->Configuration->Editor->Encoding中确认文本的编码格式)

    示例——HC-05蓝牙模块配置:

        最近使用蓝牙串口模块,手头有一个HC-05的蓝牙串口模块,但是不知道它的串口波特率,而且我想将其设成115200波特率,一般来说都是用电脑连接USB转串口模块进行配置,但是电脑上的友善串口助手试用期过了,这个时候,我就可以使用这个应用来做。

    首先将手机和蓝牙串口模块连接

     

    请原谅我手机的垃圾像素

        关于HC-05型的蓝牙串口模块的配置教程,网上有一大堆,这里就不赘述了。流程是:先按住蓝牙模块的按钮,然后对其上电,上电后松开按钮,此时会使模块进入AT模式,进入AT模式后才能通过串口设置参数。一般HC-05模块在AT模式下的波特率是38400,因此需要在应用的设置界面修改参数。此外,还需要加入 0D 0A的换行符。整体的设置如下图:

     

    设置完成后,就可以向蓝牙模块发送AT指令了,在收发界面发送命令“AT+UART?”,读取一下蓝牙模块的串口波特率,可以发现蓝牙模块成功返回了信息。然后发送命令“AT+UART=115200,0,0”可以看到设置成功了。此外还可以修改一些参数,比如配对密码等参数。这里我修改了一下,也是完全可以的。

    这就是我这个应用“串口调试助手” 的所有介绍了,如果觉得这东西有点意思的话,可以在下面通过二维码安装

    如果你也想开发同样的应用,你可以在https://github.com/mik3y/usb-serial-for-android处找到开源的USB串口库。

    展开全文
  • 虚拟串口软件和串口调试助手的简单使用

    万次阅读 多人点赞 2015-11-14 20:24:36
    为解决计算机的物理串口个数的限制,在进行串口调试实验时,应尽可能采用虚拟串口软件。VSPD(Virtual Serial Ports Driver)虚拟串口软件是由Eltima软件公司设计的虚拟串口软件,使用方便且稳定。同时,使用虚拟...

    为解决计算机的物理串口个数的限制,在进行串口调试实验时,应尽可能采用虚拟串口软件。VSPD(Virtual Serial Ports Driver)虚拟串口软件是由Eltima软件公司设计的虚拟串口软件,使用方便且稳定。同时,使用虚拟串口也是规避风险的好办法,尤其对新手而言,应该现在虚拟串口环境下调试自己的代码,成功之后再连接物理串口,链接物理串口之前一定要检查连线是否正确,并用万能表检测是否有短路断路情况发生,否则极易烧毁串口。

    本例使用的串口调试工具下载地址为:http://www.darkwood.me/serialport/download/

    虚拟串口软件可以在Eltima官方网站下载试用版。

    先安装上述两款软件,其方法和一般Windows软件一样。

    安装完成后先打开虚拟串口软件VSPD,如下图所示:


    VSPD会自动识别出本台计算上有几个物理串口,例如本机只有一个物理串口COM1。在右侧端口管理的分页中,添加虚拟端口。虚拟端口一定是成对出现的,如CMO2和COM3,其编号由VSPD自动检测本地物理串口资源后,自动为虚拟串口排号。单击“Add pair”按钮为计算机添加虚拟串口,如下图所示:


    可以在VSPD右侧看见已经成功添加的虚拟串口,然后打开串口调试窗口将窗口号改为COM2,如下图所示,


    再打开一个串口调试窗口(可以同时打开多个串口调试窗口),将端口号改为COM3,如下图所示:


    两个串口调试窗口的串口设置保持默认的设置,接受设置和发送设置选择以ASCII码形式发送和接受,此时两个串口处于关闭状态,点击右侧的“打开”按钮,打开COM2和COM3串口,开始通信。

    在COM2口的发送栏里输入“123456789A”并回车,然后点击发送,在COM3口的接收区域内就能成功接收有COM2口发来的数据,如下图所示:


    同理,也可以由COM3发送COM2接收,如下图所示:


    测试结束后停止发送关闭串口,养成良好习惯。COM2和COM3口如果都能实现数据的收发,说明整个实验环境安装正确,即可进入更高级别的实验。

    展开全文
  • 常用的串口调试指令

    2019-08-10 08:09:21
    常用的串口调试指令 1.筛选指定日志信息 logcat | grep xxx 2.抓取log信息并保存在指定文件 logcat -f xxx(文件名) logcat -c;logcat -s “TAG” //打印指定信息 3.关闭kernel打印信息 记得用切换用户权限:su 切换...
  • 常用的串口调试命令

    千次阅读 2019-05-30 17:59:16
    如何查看打印信息 至于要查看打印信息的内容这个要熟悉代码,其实如果插拔电源有内容输出就表示上电了,其他判断程序跑到哪里都是代码中放入的日志判断的,这个各个平台都...一些好用的命令串口中输入 reboot re...
  • 友善串口调试助手是一个很好而小巧的串口调试助手,完美支持Win7等Windows操作系统。友善串口调试助手支持常用的50-256000bps波特率,能设置校验、数据位和停止位,能以ASCII码或十六进制接收或发送任何数据或字符...
  • 串口调试助手V2.2源代码

    千次下载 热门讨论 2011-02-22 19:30:17
    龚建伟编写的软件串口调试助手V2.2的开源源代码
  • Android 蓝牙串口调试助手源码(保证正确)

    千次下载 热门讨论 2012-11-19 09:35:30
    买别人的代码,这里分享。已经编译生成apk。可以改源码供自己需要。
  • Android安卓手机串口调试助手,工程师的好帮手。该软件支持Prolific、FTDI、Silicon Labs、沁恒等市场主流品牌的USB转串口芯片,如PL2303、FT232、CP2102、CH340等。当手机接上这些USB转串口模块后,工程师便可轻松...
  • C#串口调试助手

    千次阅读 2017-10-27 13:14:57
    C#编写一个简易的串口调试助手 串口调试助手简介: 串口调试助手是串口调试相关工具,有多个版本。如:友善串口调试助手,支持9600,19200等常用各种波特率及自定义波特率,可以自动识别串口,能设置校验、数据...
  • 安卓串口调试工具.apk

    2018-11-19 17:47:03
    串口测试工具2018 适用于安卓平板、主板、盒子、手机、x86等安卓设备,进行串口测试。 串口设备包括:串口打印机、电子秤、投影机、矩阵、摄像机、等离子、单片机等等。 ...支持USB转串口调试
  • 支持CRC16计算的串口调试助手

    千次下载 热门讨论 2011-05-14 23:06:38
    超级好用的串口调试助手 这个工具集成了市面上的所有同类软件的优点。具有不可见字符显示、显示发送内容开关 ModBus CRC校验工具、16位和计算工具、字符十六位格式转换、字符个数统计、十六进制字节数 统计、自动...
  • 串口调试助手Delphi版 v1.0

    热门讨论 2006-01-13 09:51:35
    串口调试助手 v1.0 使用说明本程序完全参照龚建伟《串口调试助手V2.2》制作而成,原软件是用VC编写的,我将它改用Delphi编写,作为我学习串口编程的一个例子与工具使用。其中用到串口控件为ComPort,该控件为开源...
  • Linux 串口调试工具汇总

    万次阅读 2017-04-15 15:06:28
    在 linux 系统下进行串口调试或者开发时配合简单易用的串口调试工具那是必不可少。这篇博客对当前用的较多的,且我自己经常用的一些串口工具做一下汇总,大家可以参考一下。 实验环境: OS: Ubuntu16.04 Kernel: ...
1 2 3 4 5 ... 20
收藏数 56,500
精华内容 22,600
关键字:

串口调试