Search by Tags

How to use UART on Windows Compact Embedded

 
Applicable for

Article updated at 30 Jul 2020
Compare with Revision




UART (Universal Asynchronous Receiver/Transmitter) is an individual (or part of an) integrated circuit used for serial communications over a computer or peripheral device serial port. It is commonly used in conjunction with communication standards such as RS-232, RS-422 or RS-485.

Use Cases:

  • RF transceiver
  • Thermal printer
  • GSM modem
  • Biometric reader
  • GSM module
  • and many more..

For more information on Serial Communications on WinCE platform, click here.

Hardware setup

On Evaluation Board v3.1A: Connect one end of the null modem cable to the serial port of the PC and the other end to upper RS232 port on connector X25.

On Iris Carrier board V1.1A: Connect one end of the null modem cable to the serial port of the PC and the other end of null modem cable to connector X14.

Use a terminal application, such as Tera Term to open a terminal connection on the PC with these settings: 9600 Baud/8 Data Bits/No parity/1 Stop Bit.

Note: This article refers to general purpose UART usage, not Full Feature UART configured to access the bootloader.

Demo application in C (polling mode)

This application demonstrates how data can be read and written from the COM port. Follow this tutorial up to step 9 to create a new VC++ project. Right click on Source Files > Add > New Item...


Click on C++ file (.cpp) and name it uart.c


Copy and paste this code in uart.c

#include <windows.h>
 
/// Switch cases.
#define READ            1
#define WRITE           2
#define EXIT            3
 
#define BUFFER_SIZE	  32
 
//******************************************************************************
/// Configures COM port for specified baudrate.
/// @param[in]    port         COM port
/// @param[in]    baudRate     Baudrate for communication
/// @retval       TRUE         Success
///               FALSE        Failure
BOOL PortOpen(HANDLE *port, DWORD baudRate)
{
    DCB portDCB;                                              ///< COM port configuration structure.
    BOOL returnValue = FALSE;
    COMMTIMEOUTS comTimeOut;
    /// Opens interface to reader.
    *port = CreateFile(TEXT("COM2:"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL);
    if (*port == INVALID_HANDLE_VALUE)
    {
        printf("Error Opening COM Port\n");
        return FALSE;
    }
 
    /// COM Port Configuration.
    portDCB.DCBlength = sizeof (DCB);                         ///< Initialize the DCBlength member.
    GetCommState (*port, &portDCB);                           ///< Get the default port setting information.
    /// Changes the DCB structure settings.
    portDCB.BaudRate = baudRate;                              ///< Current baud. 
    portDCB.fBinary = TRUE;                                   ///< Binary mode; no EOF check. 
    portDCB.fParity = FALSE;                                  ///< Disable parity checking. 
    portDCB.fOutxCtsFlow = FALSE;                             ///< No CTS output flow control. 
    portDCB.fOutxDsrFlow = FALSE;                             ///< No DSR output flow control. 
    portDCB.fDtrControl = DTR_CONTROL_DISABLE;                ///< Disable DTR flow control type. 
    portDCB.fDsrSensitivity = FALSE;                          ///< DSR sensitivity. 
    portDCB.fTXContinueOnXoff = TRUE;                         ///< XOFF continues Tx. 
    portDCB.fOutX = FALSE;                                    ///< No XON/XOFF out flow control. 
    portDCB.fInX = FALSE;                                     ///< No XON/XOFF in flow control. 
    portDCB.fErrorChar = FALSE;                               ///< Disable error replacement. 
    portDCB.fNull = FALSE;                                    ///< Disable null stripping. 
    portDCB.fRtsControl = RTS_CONTROL_DISABLE;                ///< Disable RTS flow control. 
    portDCB.fAbortOnError = FALSE;                            ///< Do not abort reads/writes on error.
    portDCB.ByteSize = 8;                                     ///< Number of bits/byte, 4-8 
    portDCB.Parity = NOPARITY;                                ///< 0-4 = no, odd, even, mark, space. 
    portDCB.StopBits = ONESTOPBIT;                            ///< 0, 1, 2 = 1, 1.5, 2 
 
    /// Configures the port according to the specifications of the DCB structure.
    if (!SetCommState (*port, &portDCB))
    {
      printf("Error Configuring COM Port\n");                 ///< Could not configure the serial port.      
      return FALSE;
    }
 
    /// Gets communication time out values.
    returnValue = GetCommTimeouts(*port, &comTimeOut);
    comTimeOut.ReadIntervalTimeout = 10;
    comTimeOut.ReadTotalTimeoutMultiplier = 1;
    comTimeOut.ReadTotalTimeoutConstant = 1;
    /// Sets communication time out values.
    returnValue = SetCommTimeouts(*port, &comTimeOut);
 
    return TRUE;
}
 
//******************************************************************************
/// Closes UART port.
/// @param[in]    port     COM port
/// @retval       TRUE     Success
///               FALSE    Failure
BOOL PortClose(HANDLE *port)
{
    if (*port == NULL)
    {
        return FALSE;
    }
    CloseHandle(*port);
    *port = NULL;
    return TRUE;
}
 
//******************************************************************************
int wmain(void)
{
    HANDLE portHandle;
    DWORD noOfBytesRead = 0;
    DWORD bytesTransmitted = 0;   
    DWORD firstChoice = 0;
	BOOL retVal = FALSE;
    char transmitBuffer[BUFFER_SIZE] = "Hello, this is UART test code\n";
    char receiveBuffer[BUFFER_SIZE] = {0};
 
    retVal = PortOpen(&portHandle, 9600);
    if (!retVal)
    {
        printf("Could not open COM port");
		getchar();
		return FALSE;
    }   
    else
    {
        retVal = FALSE;
        while (TRUE)
        {
			memset(receiveBuffer, 0, BUFFER_SIZE);
            printf("\n\n\n*****************************************\n");
            printf("Toradex AG\n");         
            printf("*****************************************\n");
            printf("[1] Read\n");                   
            printf("[2] Write\n");                  
            printf("[3] Exit\n");
            printf("Enter your choice:\t");
            scanf_s("%d", &firstChoice);
 
			switch(firstChoice)
            {
                case READ:
                    ReadFile(portHandle, receiveBuffer, BUFFER_SIZE - 1, &noOfBytesRead, NULL);
                    printf_s("%s\n", receiveBuffer);
					PurgeComm(portHandle, PURGE_RXCLEAR);        ///< Clears receive buffer.
                    break;
                case WRITE:                 
                    WriteFile(portHandle, transmitBuffer, strlen(transmitBuffer), &bytesTransmitted, NULL);
                    break;              
                case EXIT:
                    return TRUE;
                    break;
				default:
					printf("Please enter your choice between 1-3..\n");
                    break;
            }           
        }
		/// Closes the serial port.
		PortClose(&portHandle);
    }
}
 

After deploying the program to Toradex module, open the Remote Display program. Go to My Device > Program Files > (project_name). Double click on the (project_name).exe to run the application. Open a Tera Term window and start a new Serial connection with these settings: 9600 Baud/8 Data Bits/No parity/1 Stop Bit.

For option 1 (READ), open the Tera Term window. Any character which is typed in this window will be displayed in the application window on Remote Display.

For option 2 (WRITE), open the Tera Term window. The string "Hello,this is UART test code" will be displayed on the Tera Term window.

Option 3 (EXIT) will close the program and exit.

Download project

You can download project source code from here.

Demo application in C (event mode)

This application demonstrates how data can be read and written from the COM port using Communication Events. Click here for more details.

Data read event code snippet:

DWORD ReceiverThread(HANDLE portHandle)
{
	DWORD eventMask = 0;
	DWORD noOfBytesRead = 0;
	char receiveBuffer[BUFFER_SIZE] = {0};
	BOOL retVal = FALSE;
 
	while (TRUE)
	{
		memset(receiveBuffer, 0, BUFFER_SIZE);
		/// Waits for an event to occur for the port.
		retVal = WaitCommEvent(portHandle, &eventMask, NULL);
		if ((eventMask & EV_RXCHAR) == EV_RXCHAR)
		{
			retVal = ReadFile(portHandle, receiveBuffer, BUFFER_SIZE, &noOfBytesRead, NULL);
			if (retVal == TRUE)
			{
				if (noOfBytesRead != 0)
				{
					printf_s("\nData received (%u bytes): %s", noOfBytesRead, receiveBuffer);
				}
			}
			else
			{
				printf_s("\nComm port Read failure.");
				break;
			}
		}
		else
		{
			break;
		}
	}
	return TRUE;
}

In comparison to 1st demo application above, here you no need to press option 1 (READ) for reading the serial port. Data received on serial port will be automatically displayed on the console window.

Download project

You can download project source code from here.