I’ve modified the original UART example that comes with the Microchip C32 compiler to easily handle different UART’s along with adding a compare function that compares what is recieved over the UART to a pre-defined set of characters. See the description in the source below for more.
Download the source as a text file here: UART_Library_Interface_Example
/*********************************************************************
UART Library Interface Example
Summary:
This file contains the interface definition for the UART peripheral
library.
Description:
This library provides a low-level abstraction of the UART (Universal
Asynchronous Receiver/Transmtter) module on Microchip PIC32MX family
microcontrollers with a convenient C language interface. It can be
used to simplify low-level access to the module without the
necessity of interacting directly with the module's registers, thus
hiding differences from one microcontroller variant to another.
Modifications:
This version has been modified from the original by Trevor
(http://electronics.trev.id.au) to allow use of the functions with
multiple UART's. The three functions
* SendDataBuffer,
* GetMenuChoice,
* GetDataBuffer
now reqiure the UART id to be the first variable passed to
the function (eg: GetMenuChoice(UART1);)
Also added a buffer compare function to allow comparison of what is
recieved. Key point to note with the compare, the buffer is not
a \0 terminated string.
Testing modifications:
This has been tested on the chipKIT Max32 from Digilent using
UART1 -> FTDI chip -> PC. The source is compiled using
MPLAB X IDE v1.10 and programmed into the device using an MPLAB
ICD3. Compiler was the Microchip C32 v2.02.
**********************************************************************/
//DOM-IGNORE-BEGIN
/*********************************************************************
FileName: main.c
Dependencies: See includes
Processor: PIC32MX
Complier: Microchip MPLAB C32 v1.06 or higher
Company: Microchip Technology Inc.
Copyright © 2008-2009 released Microchip Technology Inc. All
rights reserved.
Modifications as described above are Copyright © 2012 released
by Trevor van der Linden. All rights reserved.
The modifications have the same license terms as the original
Microchip license, with the exception that where it states Microchip,
it should be read as Trevor van der Linden.
Microchip licenses to you the right to use, modify, copy and distribute
Software only when embedded on a Microchip microcontroller or digital
signal controller that is integrated into your product or third party
product (pursuant to the sublicense terms in the accompanying license
agreement).
You should refer to the license agreement accompanying this Software
for additional information regarding your rights and obligations.
SOFTWARE AND DOCUMENTATION ARE PROVIDED ?AS IS? WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION,
ANY WARRANTY OF MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS
FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROCHIP, TREVOR VAN DER
LINDEN, OR THEIR LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR
OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR
EXPENSES INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL,
INDIRECT, PUNITIVE OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST
DATA, COST OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES,
OR ANY CLAIMS BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY
DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
*********************************************************************/
//DOM-IGNORE-END
// ******************************************************************
// ******************************************************************
// Section: Includes
// ******************************************************************
// ******************************************************************
#include <GenericTypeDefs.h>
#include <plib.h>
// ******************************************************************
// ******************************************************************
// Section: Configuration bits
// ******************************************************************
// ******************************************************************
#pragma config FPLLODIV = DIV_1, FPLLMUL = MUL_20, FPLLIDIV = DIV_2,\
FWDTEN = OFF, FCKSM = CSECME, FPBDIV = DIV_1
#pragma config OSCIOFNC = ON, POSCMOD = XT, FSOSCEN = ON,\
FNOSC = PRIPLL
#pragma config CP = OFF, BWP = OFF, PWP = OFF
// ******************************************************************
// ******************************************************************
// Section: System Macros
// ******************************************************************
// ******************************************************************
#define GetSystemClock() (80000000ul)
#define GetPeripheralClock() (GetSystemClock()/(1 << OSCCONbits.PBDIV))
#define GetInstructionClock() (GetSystemClock())
// ******************************************************************
// ******************************************************************
// Section: Function Prototypes
// ******************************************************************
// ******************************************************************
BOOL BufferCompare(char *buffer, UINT32 size,\
const unsigned char *compareto,\
UINT32 expectedSize);
void SendDataBuffer(UART_MODULE id, const char *buffer, UINT32 size);
UINT32 GetMenuChoice(UART_MODULE id);
UINT32 GetDataBuffer(UART_MODULE id, char *buffer, UINT32 max_size);
// ******************************************************************
// ******************************************************************
// Section: Constant Data
// ******************************************************************
// ******************************************************************
const char mainMenu[] =
{
"Welcome to PIC32 UART Peripheral Library Demo! (Trevor's mods)\r\n"\
"Here are the main menu choices\r\n"\
"1. View Actual BAUD rate\r\n"\
"2. Use AUTOBAUD\r\n"\
"3. Set Line Control\r\n"\
"4. ECHO\r\n"
"\r\n\r\nPlease Choose a number\r\n"
};
const char lineMenu[] =
{
"Line Control Menu\r\n"\
"You may need to change the line control on the terminal to see data\r\n"\
"1. 8-N-1\r\n"\
"2. 8-E-1\r\n"\
"3. 8-O-1\r\n"\
"4. 8-N-2\r\n"\
"5. 8-E-2\r\n"\
"6. 8-O-2\r\n"\
"\r\n\r\nPlease Choose a number\r\n"
};
const UINT32 lineControl[] =
{
(UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_1),
(UART_DATA_SIZE_8_BITS | UART_PARITY_EVEN | UART_STOP_BITS_1),
(UART_DATA_SIZE_8_BITS | UART_PARITY_ODD | UART_STOP_BITS_1),
(UART_DATA_SIZE_8_BITS | UART_PARITY_NONE | UART_STOP_BITS_2),
(UART_DATA_SIZE_8_BITS | UART_PARITY_EVEN | UART_STOP_BITS_2),
(UART_DATA_SIZE_8_BITS | UART_PARITY_ODD | UART_STOP_BITS_2)
};
const unsigned char response[] = {"AOK"};
const UART_MODULE monitorUART = UART1;
const UART_MODULE WiFlyUART = UART2;
const UART_MODULE gpsUART = UART3;
// ******************************************************************
// Section: Code
// ******************************************************************
// ******************************************************************
// ******************************************************************
// int main(void)
// ******************************************************************
int main(void)
{
UINT32 menu_choice;
UINT8 buf[1024];
UARTConfigure(monitorUART, UART_ENABLE_PINS_TX_RX_ONLY);
UARTSetFifoMode(monitorUART, UART_INTERRUPT_ON_TX_NOT_FULL\
| UART_INTERRUPT_ON_RX_NOT_EMPTY);
UARTSetLineControl(monitorUART, UART_DATA_SIZE_8_BITS\
| UART_PARITY_NONE\
| UART_STOP_BITS_1);
UARTSetDataRate(monitorUART, GetPeripheralClock(), 115200);
UARTEnable(monitorUART, UART_ENABLE_FLAGS(UART_PERIPHERAL\
| UART_RX |\
UART_TX));
SendDataBuffer(monitorUART, mainMenu, sizeof(mainMenu));
while(1)
{
menu_choice = GetMenuChoice(monitorUART);
switch(menu_choice)
{
case 1:
sprintf(buf, "Actual Baud Rate: %ld\r\n\r\n",\
UARTGetDataRate(monitorUART, GetPeripheralClock()));
SendDataBuffer(monitorUART, buf, strlen(buf));
break;
case 2:
SendDataBuffer(monitorUART,\
"Press 'U' to allow AUTO BAUD to sync\r\n",\
strlen("Press 'U' to allow AUTO BAUD to sync\r\n"));
UARTStartAutoDataRateDetect(monitorUART);
while(!UARTDataRateDetected(monitorUART))
;
sprintf(buf, "Actual Baud Rate: %ld\r\n\r\n",\
UARTGetDataRate(monitorUART, GetPeripheralClock()));
SendDataBuffer(monitorUART, buf, strlen(buf));
break;
case 3:
SendDataBuffer(monitorUART, lineMenu, sizeof(lineMenu));
menu_choice = GetMenuChoice(monitorUART);
menu_choice--;
if(menu_choice >= 6)
{
SendDataBuffer(monitorUART, "Invalid Choice",\
sizeof("Invalid Choice"));
SendDataBuffer(monitorUART, mainMenu,\
sizeof(mainMenu));
break;
}
SendDataBuffer(monitorUART,\
"Press Any Character after re-configuring you terminal\r\n",\
strlen("Press Any Character after re-configuring you terminal\r\n"));
UARTSetLineControl(monitorUART, lineControl[menu_choice]);
menu_choice = GetMenuChoice(monitorUART);
SendDataBuffer(monitorUART, mainMenu, sizeof(mainMenu));
break;
case 4:
{
UINT32 rx_size;
unsigned char s[1024];
BOOL strcorrect;
SendDataBuffer(monitorUART,\
"Type a message (less than 100 characters) and press return\r\n",\
strlen("Type a message (less than 100 characters) and press return\r\n"));
rx_size = GetDataBuffer(monitorUART, buf, 1024);
strcorrect = BufferCompare(buf, rx_size,\
"AOK", sizeof("AOK") - 1); // dont count the \0
if(strcorrect == TRUE)
{
SendDataBuffer(monitorUART,\
"recieved expected response\r\n\r\n",\
strlen("recieved expected response\r\n\r\n"));
}
else
{
SendDataBuffer(monitorUART,\
"You Typed:\r\n\r\n",\
strlen("You Typed:\r\n\r\n"));
SendDataBuffer(monitorUART, buf, rx_size);
}
SendDataBuffer(monitorUART,\
"\r\n\r\nPress any key to continue\r\n\r\n",\
strlen("\r\n\r\nPress any key to continue\r\n\r\n"));
GetMenuChoice(monitorUART);
}
break;
default:
SendDataBuffer(monitorUART, mainMenu, sizeof(mainMenu));
}
}
return -1;
}
/********************************************************************
BOOL BufferCompare(\
char *buffer,UINT32 size,\
char *compareto,\
UINT32 expectedSize)
Inputs:
* buffer - the buffer containing the data returned from the UART
* size - the number of charachters that the UART returned in buffer
* compareto - char array of the characters to compare buffer to
* expected size - the number of characters in compareto excluding
any \0 chars
Returns:
* Boolean - True if the two are the same, otherwise false.
SPECIAL NOTE:
* The contents of the buffer coming from the UART is not a
traditional null terminated string (does not have a \0 as
a terminating char. For this reason you need to provide the
size and expectedSize variables so the function knows how
many characters from the start of buffer to compare.
********************************************************************/
BOOL BufferCompare(char *buffer,\
UINT32 size,\
const unsigned char *compareto,\
UINT32 expectedSize)
{
UINT8 i;
BOOL same;
same = FALSE; // 1st default to false
if(size == expectedSize) // check to see if the size is the same
{
same = TRUE; // default to true
for (i=0;i<=size-1;i++)
{
if(buffer[i] != compareto[i]) // compare
{
same = FALSE; // if not the same, set to false
}
}
}
return same; // return result.
}
// ******************************************************************
// void UARTTxBuffer(UART_MODULE id, char *buffer, UINT32 size)
// ******************************************************************
void SendDataBuffer(UART_MODULE id, const char *buffer, UINT32 size)
{
while(size)
{
while(!UARTTransmitterIsReady(id))
;
UARTSendDataByte(id, *buffer);
buffer++;
size--;
}
while(!UARTTransmissionHasCompleted(id))
;
}
// *******************************************************************
// UINT32 GetDataBuffer(UART_MODULE id, char *buffer, UINT32 max_size)
// *******************************************************************
UINT32 GetDataBuffer(UART_MODULE id, char *buffer, UINT32 max_size)
{
UINT32 num_char;
num_char = 0;
while(num_char < max_size)
{
UINT8 character;
while(!UARTReceivedDataIsAvailable(id))
;
character = UARTGetDataByte(id);
if(character == '\r')
break;
*buffer = character;
buffer++;
num_char++;
}
return num_char;
}
// *******************************************************************
// UINT32 GetMenuChoice(UART_MODULE id)
// *******************************************************************
UINT32 GetMenuChoice(UART_MODULE id)
{
UINT8 menu_item;
while(!UARTReceivedDataIsAvailable(id))
;
menu_item = UARTGetDataByte(id);
menu_item -= '0';
return (UINT32)menu_item;
}