⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serialcomm.cpp

📁 一个通过USB->UART读取C8051F060的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		{
				#ifdef	_USEMSCOMM
					m_Comm.SetOutBufferCount(0);
				#else
					::FlushOutQ(m_nPortNo);
				#endif
		}
		g_critSec.Unlock();	
}

//从COM口接收字符串转换成结构体输出
int  CSerialComm::RecvBytes(char *&szBuff, int nLen)
{
		int  nRetVal = 0;
		g_critSec.Lock(2000);
		//::AfxIsValidString(szBuff);
		
		#ifdef	_USEMSCOMM
			this->RecieveStr((void *&)szBuff);
		#else
			nRetVal = ::ComRd(m_nPortNo, szBuff, nLen);
		#endif
		g_critSec.Unlock();	

		return  nRetVal;
}

//从COM口接收字符串转换成结构体输出
void  CSerialComm::RecieveStr(void *&pData)
{
		int nBuffLen = 0;
		g_critSec.Lock(2000);
		if (m_bPortUsed == TRUE)
		{
				#ifdef	_USEMSCOMM
						nBuffLen = m_Comm.GetInBufferCount();
						m_Comm.SetInputLen(nBuffLen);
						m_vResponse=m_Comm.GetInput();				
						//转换字符串
						pData=m_vResponse.parray->pvData;
				#else
						//::ComRd(m_nPortNo, char buf[], int maxCnt);
				#endif

				this->ClearBuff();
		}
		g_critSec.Unlock();	
}

//返回接收字节数
int  CSerialComm::ReadNumBytes()
{
		int nBuffLen  = 0;

		g_critSec.Lock(2000);
		if (m_bPortUsed == TRUE)
		{		
				#ifdef	_USEMSCOMM
					nBuffLen = m_Comm.GetInBufferCount();
				#else
					nBuffLen = ::GetInQLen(m_nPortNo);
				#endif
		}
		g_critSec.Unlock();
		
		return  nBuffLen;
}














////////////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////////////
BOOL   CBaseCommIntf::m_bPortUsed   = FALSE;
BOOL   CBaseCommIntf::m_bRealUpload = TRUE;
BOOL   CBaseCommIntf::m_bInitThread = FALSE;
CCriticalSection  CBaseCommIntf::g_critSec;
//接受数据显示对象
void   CBaseCommIntf::AcceptConsumer(CDataReaderImpl *pReader)
{
		m_pReader  = pReader;
}

CDataReaderImpl* CBaseCommIntf::GetConsumer()
{
		return  m_pReader;
}

BOOL   CBaseCommIntf::IsOpen()
{
		return  m_bPortUsed == TRUE;
}

void   CBaseCommIntf::InitThread()
{		
		//g_critSec.Lock(2000);
		if (m_bPortUsed && !m_bInitThread)
		{
			m_bInitThread = TRUE;
			g_arrRunThreads[FETCHSERIALPORTTHREADID] = ::AfxBeginThread(RUNTIME_CLASS(CReadSrlDataThread), 
													   THREAD_PRIORITY_NORMAL, 10000, CREATE_SUSPENDED);
		}
		//g_critSec.Unlock();
}

//开始通信,从缓存取(Resume)
BOOL   CBaseCommIntf::StartComm()
{
		//g_critSec.Lock(2000);
		if (!g_bThread1)
		{
				g_arrRunThreads[FETCHSERIALPORTTHREADID]->ResumeThread();
				g_bThread1 = TRUE;
		}
		//g_critSec.Unlock();
		
		return  TRUE;
}

///////////////////////////////////////////////////////////////////////////////
//停止串口通信,从缓存取(Pause)
//注意:在接收线程中的RUN函数使用了g_critSec和RecieveStr(), 正在独占g_critSec同步对象,
//所以, StopComm函数不能再使用同一个g_critSec, 避免等待。
BOOL   CBaseCommIntf::StopComm(BOOL bCleanup)
{
		if (g_bThread1)
		{
				g_arrRunThreads[FETCHSERIALPORTTHREADID]->SuspendThread();
				g_bThread1 = FALSE;
		}
		return  TRUE;
}








#ifdef __USEUSBXPRESS
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
CUART2USBComm::CUART2USBComm():m_cyHandle(NULL)
{
	
}
CUART2USBComm::~CUART2USBComm()
{
		//退出线程
		if (g_bThread1)
			g_arrRunThreads[FETCHSERIALPORTTHREADID]->ExitInstance();

		if (m_cyHandle != NULL)
		{
				::SI_Close(m_cyHandle);
		}
}

/*默认配置串口*/
BOOL   CUART2USBComm::ConfigPort(short nPort, int nBaudRate)
{	
		DWORD dwNumDevices;
		if (m_cyHandle != NULL)
		{
				::SI_Close(m_cyHandle);
				return FALSE;		
		}

		SI_STATUS st = ::SI_GetNumDevices(&dwNumDevices);
		if (st != SI_SUCCESS)
		{
				::AfxMessageBox("初始化\"热电池自旋测试系统\"USB通信口失败!");
				return FALSE;
		}
		if (dwNumDevices < 1)
		{
				::AfxMessageBox("初始化USB口失败!");
				return FALSE;
		}
		
		char  szDeviceDesc[256];
		::SI_GetProductString(0/*取第一个*/, szDeviceDesc, SI_RETURN_SERIAL_NUMBER);
		TRACE1("当前设备的串口号:%s.", szDeviceDesc);
		
		TRY
		{
				//打开通信口
				st = ::SI_Open(0/*取第一个*/, &m_cyHandle);
				if (st != SI_SUCCESS)
				{
						::AfxMessageBox("打开USB口失败,检查USB线连接情况!");
						return FALSE;
				}
				//
				st = ::SI_SetBaudRate(m_cyHandle, nBaudRate);
				st = ::SI_SetLineControl(m_cyHandle, 32768/*8数据位,无校验位,1停止位*/);
				st = ::SI_SetTimeouts(5*1000/*ms*/, 5*1000/*ms*/);
		}
		END_TRY

		return   TRUE;
}

void CUART2USBComm::ClearOutBuff()
{
		if (m_cyHandle != NULL)
		{
				::SI_FlushBuffers(m_cyHandle, 10, 0);
		}
}

void   CUART2USBComm::ClearBuff()
{
		g_critSec.Lock(2000);
		if (m_cyHandle != NULL)
		{
				::SI_FlushBuffers(m_cyHandle, 0, 10);
		}
		g_critSec.Unlock();	
}



/************************************************************************/
/* 定义界面上下放命令部分                                               */
/************************************************************************/
BOOL  CUART2USBComm::SendUiCmd(void *pArg, BOOL bImmd)
{		
		g_critSec.Lock(4000);
		if (m_bPortUsed != TRUE)
		{
				g_critSec.Unlock();	
				return FALSE;
		}
		BOOL   bRet = FALSE;
		TRY
		{	
				this->ClearBuff();
				this->ClearOutBuff();

				//先转换成字符串
				LPCalSpeed_ArgCmdToCom  pDataStr = (LPCalSpeed_ArgCmdToCom)pArg;		
				//发送命令字符串
				if (pDataStr != NULL)
						bRet = this->SendStr((LPCTSTR)pDataStr->szCmdBuff, pDataStr->nActualLen);									
		}
		END_TRY
		g_critSec.Unlock();	

		return  bRet;
}

//向COM口发送字节
void  CUART2USBComm::SendBytes(char szBuffer[], int nLen)
{}

//向COM口发送字符串
BOOL CUART2USBComm::SendStr(const char *pSendBuff, int nBufSize)
{
		g_critSec.Lock(2000);		
		ASSERT(nBufSize>0);
		ASSERT(AfxIsValidString(pSendBuff, nBufSize));
		if (nBufSize > 4096)
		{
				::AfxMessageBox("超出4096字节,无法进行发送操作;建议限制在4096范围内");
				return FALSE;
		}
		

		DWORD  dwActualBytesWrite = 0;
		if (m_cyHandle != NULL)
		{
				::SI_Write(m_cyHandle, (void *)pSendBuff, nBufSize, &dwActualBytesWrite);
		}
		g_critSec.Unlock();

		return  dwActualBytesWrite == (DWORD)nBufSize;
}



/************************************************************************/
/*从COM口接收字符串直接转通知显示和数据存储,							*/
/*...此处搜寻出上报数据,写入数据池.										*/
/************************************************************************/
void CUART2USBComm::RecieveStr()	
{
		if (m_cyHandle == NULL)
			return ;

		//////////////////////////////////////////////////////////////////
		//判断缓存大小
		int nBuffLen = this->ReadNumBytes();
		if (nBuffLen <= 0)
		{
				g_critSec.Unlock();
				return ;
		}

		//取出数据
		int nActualBytes = this->RecvBytes((char *&)g_arrBuffer, min(MAXFETCHBYTESNUM, nBuffLen));	
		if (nActualBytes < 1)
		{
				g_critSec.Unlock();
				return ;
		}		
		
		//有效数据则压入数据池
		if (m_pReader != NULL)
			m_pReader->NotifyData(g_arrBuffer, min(MAXFETCHBYTESNUM, nBuffLen));							
}

//从COM口接收字符串转换成结构体输出
int  CUART2USBComm::RecvBytes(char *&szBuff, int nLen)
{
		g_critSec.Lock(2000);
		::AfxIsValidString(szBuff);
		DWORD  dwReadByteNum = 0;
		if (m_cyHandle != NULL)
		{
			::SI_Read(m_cyHandle, szBuff, nLen, &dwReadByteNum);	
		}
		g_critSec.Unlock();	

		return  dwReadByteNum;
}

//从COM口接收字符串转换成结构体输出
void  CUART2USBComm::RecieveStr(void *&pData)
{}

//返回接收字节数
int  CUART2USBComm::ReadNumBytes()
{
		DWORD dwNumBytesInQueue;
		DWORD dwQueueStatus;

		g_critSec.Lock(2000);
		if (m_cyHandle != NULL)
		{				
				SI_STATUS  st = ::SI_CheckRXQueue(m_cyHandle, &dwNumBytesInQueue, &dwQueueStatus);			
		}
		g_critSec.Unlock();
		
		return  dwNumBytesInQueue;
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -