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

📄 serialcom.c

📁 在VC6.0上编译通过的蓝牙通信演示程序, COM1口控制.
💻 C
📖 第 1 页 / 共 2 页
字号:
					default:
					{
						/*	error occured	*/
						errorHandler(__LINE__, __FILE__, "Default called");
						break;
					}
				}
			} while (startRead && (event != CLOSE_DOWN_EVENT));

			if (event == CLOSE_DOWN_EVENT)
			{
				break;
			}
		}
	}	/*	end while	*/

	CloseHandle(osRead.hEvent);

	SetEvent(rxDownEvent);

	ExitThread(0);
}

void clearBuffer(void)
{
	/* flush the port for any operations waiting and any data	*/
	PurgeComm(comHandle, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT);

	/*	the internal queue pointers	*/
	txSize = 0;
	rxSize = 0;
	rxIn = 0;
	rxOut = 0;
	txIn = 0;
	txOut = 0;
}

static bool_t init(void)
{
	char configurationString[128];

	clearBuffer();

	/*	mutex for sync of write and read	*/
	InitializeCriticalSection(&rxMutex);
	InitializeCriticalSection(&txMutex);

	/*	event for internal communication	*/
	newTxDataEvent	= CreateEvent(NULL, TRUE, FALSE, NULL);
	txCloseDownEvent	= CreateEvent(NULL, TRUE, FALSE, NULL);
	txDownEvent	= CreateEvent(NULL, TRUE, FALSE, NULL);
	rxCloseDownEvent	= CreateEvent(NULL, TRUE, FALSE, NULL);
	rxDownEvent	= CreateEvent(NULL, TRUE, FALSE, NULL);
	dataReadEvent	= CreateEvent(NULL, TRUE, FALSE, NULL);
	if (newTxDataEvent == NULL || txCloseDownEvent == NULL || rxCloseDownEvent == NULL || txDownEvent == NULL || rxDownEvent == NULL || dataReadEvent == NULL)
	{
		errorHandler(__LINE__, __FILE__,"Create event failure in init");
		return FALSE;
	}

	/*	create the file handle	*/
	comHandle = CreateFile(comPortString, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
	if (comHandle == INVALID_HANDLE_VALUE)
	{
		errorHandler(__LINE__, __FILE__, "Create file handle failed");
		return FALSE;	
	}

	//sprintf(configurationString, "baud=%lu parity=E data=8 stop=1", baudRate);
	sprintf(configurationString, "baud=%lu parity=N data=8 stop=1", baudRate);
	if (!setComDefault(configurationString))
	{
		return FALSE;
	}

	return TRUE;
}


/*----------------------------------------------------------------------------*
* NAME
*     UartDrv_Configure
* 
* DESCRIPTION
*
*   This function can be used to configure the UART driver.
*
*	If this function is not called, the UART may be started with the default
*	configuration.
*	If this function is called, it should be called before Uartdrv_Start is 
*	called to initialise the driver.
*
* RETURNS
*	TRUE if the configuration was successful.
*
*/
void UartDrv_Configure(unsigned long theBaudRate, char * theComPortString)
{
	baudRate = theBaudRate;
	strcpy(comPortString, theComPortString);
}


/*----------------------------------------------------------------------------*
* NAME
*     UartDrv_Start
* 
* DESCRIPTION
*
*   This function is called to start the UART driver.
*
* RETURNS
*	TRUE: the UART was successfully started, otherwise FALSE
*
*******************************************************************************/
bool_t UartDrv_Start(void)
{
	DWORD	threadId;

	if (!init())
	{
		return FALSE;
	}

	/*	tx and rx threads		*/
	txThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) txThreadFunc, NULL, 0, &threadId);
	if(txThread == INVALID_HANDLE_VALUE) 
	{
		errorHandler(__LINE__, __FILE__, "Thread create failure");
		return(FALSE);
	}
	rxThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) rxThreadFunc, NULL, 0, &threadId);
	if(rxThread == INVALID_HANDLE_VALUE) 
	{
		errorHandler(__LINE__, __FILE__, "Thread create failure");
		return(FALSE);
	}

	return TRUE;
}

void UartDrv_Stop(void)
{
	DWORD threadExitCode;

	SetEvent(txCloseDownEvent);
	SetEvent(rxCloseDownEvent);

	while (WaitForSingleObject(txDownEvent, INFINITE) != WAIT_OBJECT_0)
	{
		printf("WaitForSingleObject(txDownEvent, INFINITE) NOT SIGNALED????\n");
	}
	do
	{
		if (!GetExitCodeThread(txThread, &threadExitCode))
		{
			printf("GetExitCodeThread failed!\n");
			break;
		}
		else
		{
			if (threadExitCode == STILL_ACTIVE)
			{
				Sleep(0);
			}
		}
	} while (threadExitCode == STILL_ACTIVE);
	CloseHandle(newTxDataEvent);
	CloseHandle(txCloseDownEvent);
	CloseHandle(txDownEvent);
	CloseHandle(txThread);

	while (WaitForSingleObject(rxDownEvent, INFINITE) != WAIT_OBJECT_0)
	{
		printf("WaitForSingleObject(rxDownEvent, INFINITE) NOT SIGNALED????\n");
	}
	do
	{
		if (!GetExitCodeThread(rxThread, &threadExitCode))
		{
			printf("GetExitCodeThread failed!\n");
			break;
		}
		else
		{
			if (threadExitCode == STILL_ACTIVE)
			{
				Sleep(0);
			}
		}
	} while (threadExitCode == STILL_ACTIVE);
	CloseHandle(rxCloseDownEvent);
	CloseHandle(rxDownEvent);
	CloseHandle(dataReadEvent);
	CloseHandle(rxThread);

	CloseHandle(comHandle);
	
	DeleteCriticalSection(&rxMutex);
	DeleteCriticalSection(&txMutex);
}


/***********************************************************************
*  RETURN
*	Return FALSE if Tx buffer overflow (and *num_send = 0).
*
*/
bool_t UartDrv_Tx(uint8_t *theData, unsigned len, uint16_t *numSend)
{
	uint16_t	size;

#ifdef	DEBUG_ENABLE
	{
	int i;
	printf("TX[%02d]: ", len);
	for (i=0;i<(int)len;i++)
	{
		printf("%02x ", theData[i]);
	}
	printf("\n");
	}
#endif	

	*numSend = 0;
	EnterCriticalSection(&txMutex);
	size = txSize;
	LeaveCriticalSection(&txMutex);

	/* check if enough space in buffer for new data - if not return FALSE */
	if (len + size > TX_BUF_MAX_SIZE)
	{
		errorHandler(__LINE__, __FILE__, "buffer full in uart tx");
		return FALSE;
	}

	if (txIn + len > TX_BUF_MAX_SIZE)
	{
		uint16_t remainingLength;

		memcpy(&txBuf[txIn], theData, TX_BUF_MAX_SIZE - txIn);
		remainingLength = len - (TX_BUF_MAX_SIZE - txIn);
		memcpy(txBuf, &theData[TX_BUF_MAX_SIZE - txIn], remainingLength);
		txIn = remainingLength;
	}
	else
	{
		memcpy(&txBuf[txIn], theData, len);
		if (txIn + len == TX_BUF_MAX_SIZE)
		{
			txIn = 0;
		}
		else
		{
			txIn += (uint16_t) len;
		}
	}
	*numSend = len;

	EnterCriticalSection(&txMutex);
	txSize = txSize + (*numSend);
	LeaveCriticalSection(&txMutex);

	/*	signal tx thread that new data has arrived	*/
	SetEvent(newTxDataEvent);
	return TRUE;
}


/*----------------------------------------------------------------------------*
* NAME
*     UartDrv_GetTxSpace
* 
* DESCRIPTION
*	Obtain amount of space available in UART.  Should be able to write at
*	least this number of chars in a call to UartDrv_Tx().
* 
* RETURNS
*	The number of characters that can be written to the UART.
*
*/
uint16_t UartDrv_GetTxSpace(void)
{
	uint16_t	size;

	EnterCriticalSection(&txMutex);
	size = TX_BUF_MAX_SIZE - txSize;
	LeaveCriticalSection(&txMutex);

	return size;
}


/***********************************************************************
* NAME
*     UartDrv_GetRxAvailable
* 
* DESCRIPTION
*	Obtain the number of received characters available in UART.  Should be
*   able to read at least this number of chars in a call to UartDrv_Rx().
*
*	NOTE:	if there is a 'wrap around' only the number of bytes up to the limit can
*			be read but the number of bytes available may be higher
* 
* RETURNS
*	The number of characters that can be read from the UART.
*
*/
uint16_t UartDrv_GetRxAvailable(void)
{
	uint16_t	theSize;

	EnterCriticalSection(&rxMutex);
	theSize = rxSize;
	LeaveCriticalSection(&rxMutex);

	return theSize;
}


/*----------------------------------------------------------------------------*
* NAME
*     UartDrv_Reset
* 
* DESCRIPTION
*
*   This function is called to reset the UART driver.  The transmit and
*   receive buffers are flushed.
*
*   NOTE: the UART configuration does NOT change.
*
* RETURNS
*   None
*
*/
void UartDrv_Reset(void)
{
	/*	clear any data in the in/out buffers	*/
	clearBuffer();
}

void UartDrv_Rx(uint8_t	*in_buf, int buf_len, int	*in_len)
{
	unsigned	bytesConsumed;
	uint16_t	noOfBytes;

	*in_len = 0;

	EnterCriticalSection(&rxMutex);
	noOfBytes = rxSize;
	LeaveCriticalSection(&rxMutex);

#ifdef MAX_BYTES_TO_ABCSP
	if (noOfBytes > MAX_BYTES_TO_ABCSP)
	{
		noOfBytes = MAX_BYTES_TO_ABCSP;
	}
#endif

	if (noOfBytes > (RX_BUF_MAX_SIZE - rxOut))
	{
		noOfBytes = (RX_BUF_MAX_SIZE - rxOut);
	}

#ifdef	DEBUG_ENABLE
	if (noOfBytes>0)
	{
	int i;
	printf("                 RX[%02d]: ", noOfBytes);
	for (i=0;i<(int)noOfBytes;i++)
	{
		printf("%02x ", rxBuf[rxOut+i]);
	}
	printf("\n");
	}
#endif	

	//Consume data here

	//Pls ensure the buffer size is enough to fix in data
	if (noOfBytes > (uint16_t)buf_len)
		noOfBytes = buf_len;
	memcpy((void *)in_buf, &rxBuf[rxOut], noOfBytes);
	*in_len = noOfBytes;
	bytesConsumed = noOfBytes;

	//Mark data was read, delete from queue
	rxOut = rxOut + bytesConsumed;

	if (rxOut >= RX_BUF_MAX_SIZE)
	{
		rxOut = 0x00; /* Buffer start from beginning*/
	}

	EnterCriticalSection(&rxMutex);
	rxSize = rxSize - bytesConsumed;
	LeaveCriticalSection(&rxMutex);

	if (bytesConsumed > 0)
	{
		SetEvent(dataReadEvent);
	}

	if (rxSize)
	{
		//still got data inside
	}
}

#if 0
int WriteBuffer(unsigned char *buffer,unsigned long numToWrite)
{
	OVERLAPPED wOverlap = gUUTCom.writeOverlap;

	unsigned long numOfWrite;
	int error;

//	ClearComBuffer();

	WaitForSingleObject(hMutex, INFINITE);

	if (WriteFile(commHandle,buffer,numToWrite,&numOfWrite,&wOverlap) == 0)
	{
         if (GetLastError() == ERROR_IO_PENDING)
         {
             while(!GetOverlappedResult( commHandle,
               &wOverlap, &numOfWrite, TRUE ))
            {
               error = GetLastError();
               if(error == ERROR_IO_INCOMPLETE)
                  // normal result if not finished
                  continue;
               else
               {
				   break;
               }

            }
		 }	
		 else
		 {
			printf("\n\n Write error!\n\n");
			return COM_FAILURE;
			
		 }
	}

	ReleaseMutex(hMutex);

	return COM_SUCCESS;
}
#endif

⌨️ 快捷键说明

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