PIC32MX: RS232
RS232 is a method of real time communication between two devices such as PIC to PIC or PIC to PC.
More information about RS232 can be found here.
The PIC32 has 2 sets of pins UART1 and UART2. The pins are:
- UxCTS - clear to send (input to PIC)
- UxRTS - ready to send (output from PIC)
- UxRX - PIC receive
- UxTX - PIC transmit
This code has been tested with the Xbees also.
PIC to PC
To communicate PIC to PC, you need to have a COMM port or a USB to RS232 converter. You can read about the TTL-232R cable (USB to RS232 converter) here.
The TTL-232R cable has six wires, color coded and in this sequence on the SIP connector:
BLACK GROUND Connect to PIC ground. BROWN CTS# Unused. "Clear to send" (flow control). RED Vcc +5V from PC. !! DO NOT CONNECT TO PIC +5 !! ORANGE Tx "PC Transmit." Data from PC, to PIC Rx (pin 26). YELLOW Rx "PC Receive." Data from PIC Tx (pin 25), to PC. GREEN RTS# Unused. "Request to send" (flow control).
Note that the TTL-232R cable gives you access to the PC's +5 supply (Red wire), which is limited in current (probably to 500mA) by the USB port which is designed to protect from short circuits. If you wish, you can probably power your PIC from the PC, using USB as a power source. If you do that, get rid of any other +5 source. Don't connect two +5 sources at once. In contrast, be sure that you do connect the PIC's ground to the PC's ground (Black wire).
Make the following connections for PIC to PC communication (not using CTS or RTS):
- PC Transmit -- PIC Receive
- PC Receive -- PIC Transmit
The code demonstrated below can also be used for Xbee communication. Simply put an xbee connected to the PIC with the RX, TX, GND and 5V and then connect the other xbee to the TTL-232R cable.
Basic Sample Code
This code details how to echo typing in a terminal such as Hyper Terminal. The PIC reads the pressed key from the PC and then transmits the key back to the PC via the TTL-232R cable. The key will be displayed on the terminal. If the key 'c' is pressed, LED1 will turn on (turns off LED2 if on). If a different key is pressed, LED2 will turn on (turns off LED1 if on).
/********************************************************************* * * UART Basic Example * **********************************************************************/ /* This code uses RS232 to communicate with a PC. It waits until you push a key on the keyboard and then sends it back. If the letter is a 'c', LED1 will turn on and LED2 will be off, otherwise LED1 will be off and LED2 will be on. */ #include "HardwareProfile.h" #define DESIRED_BAUDRATE (9600) // The desired BaudRate int main(void) { int pbClk; unsigned char data; // Configure the system performance pbClk = SYSTEMConfigPerformance(SYS_FREQ); mInitAllLEDs(); // define setup Configuration 1 for OpenUARTx // Module Enable // Work in IDLE mode // Communication through usual pins // Disable wake-up // Loop back disabled // Input to Capture module from ICx pin // no parity 8 bit // 1 stop bit // IRDA encoder and decoder disabled // CTS and RTS pins are disabled // UxRX idle state is '1' // 16x baud clock - normal speed #define config1 UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD | UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN // define setup Configuration 2 for OpenUARTx // IrDA encoded UxTX idle state is '0' // Enable UxRX pin // Enable UxTX pin // Interrupt on transfer of every character to TSR // Interrupt on every char received // Disable 9-bit address detect // Rx Buffer Over run status bit clear #define config2 UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS | UART_RX_OVERRUN_CLEAR // Open UART2 with config1 and config2 OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1); // calculate actual BAUD generate value. //OpenUART2( UART_EN | UART_NO_PAR_8BIT | UART_1STOPBIT, UART_RX_ENABLE | UART_TX_ENABLE, (pbClk/16/DESIRED_BAUDRATE) - 1); putsUART2("*** UART Simple Application Example ***\r\n"); putsUART2("*** Type some characters and observe echo and LED flashes***\r\n"); while(1) { while(!DataRdyUART2()); /* Wait for data in the UARTRx. */ data = (char)ReadUART2(); /* Read data from Rx. */ while(BusyUART2()); /* Wait till the UART transmitter is free. */ putcUART2(data); /* Write data into Tx. */ if(data == 'c') { mLED_1_On(); mLED_2_Off(); } else { mLED_2_On(); mLED_1_Off(); } }; return 0; }
Compile and Program this Hex file to the PIC. Open Hyperterminal with the following information:
- Bits per second: 9600
- Data bits: 8
- Parity: None
- Stop bits: 1
- Flow Control: Hardware
If you press reset on the PIC32 board, you should see the start up message.
Interrupt Example Code
This code details how to echo typing in a terminal such as Hyper Terminal. This code uses an interrupt to communicate via RS232. The above code waits in a while loop until the PIC receives a character. The code below does not have to sit and wait. An interrupt is called when it receives a character to trigger RS232 communication. The PIC reads the pressed key from the PC and then transmits the key back to the PC via the TTL-232R cable. The key will be displayed on the terminal. If the key 'c' is pressed, LED2 will turn on (turns off LED3 if on). If a different key is pressed, LED3 will turn on (turns off LED2 if on). LED1 toggles when there is RS232 activity.
Include the standard header files
#include "Compiler.h" #include <plib.h> #include "HardwareProfile.h"
Define the system frequency and the desired baudrate.
#define SYS_FREQ (80000000L) #define DESIRED_BAUDRATE (9600) // The desired BaudRate
Define a global variable for the data
volatile unsigned char data;
Start Main function
int main(void) {
Define local variables for the peripheral bus clock and data.
int pbClk;
Configure the system - this function returns the peripheral bus clock
pbClk = SYSTEMConfigPerformance(SYS_FREQ);
Initialize LEDs
mInitAllLEDs();
Setup Configuration 1 for OpenUARTx (most of these are default and not needed). Other constants can be found in uart.h in the peripheral include of C32.
- Module Enable
- Work in IDLE mode
- Communication through usual pins
- Disable wake-up
- Loop back disabled
- Input to Capture module from ICx pin
- No parity 8 bit
- 1 stop bit
- IRDA encoder and decoder disabled
- CTS and RTS pins are disabled
- UxRX idle state is '1'
- 16x baud clock - normal speed
#define config1 UART_EN | UART_IDLE_CON | UART_RX_TX | UART_DIS_WAKE | UART_DIS_LOOPBACK | UART_DIS_ABAUD | UART_NO_PAR_8BIT | UART_1STOPBIT | UART_IRDA_DIS | UART_DIS_BCLK_CTS_RTS| UART_NORMAL_RX | UART_BRGH_SIXTEEN
Setup Configuration 2 for OpenUARTx
- IrDA encoded UxTX idle state is '0'
- Enable UxRX pin
- Enable UxTX pin
- Interrupt on transfer of every character to TSR
- Interrupt on every char received
- Disable 9-bit address detect
- Rx Buffer Over run status bit clear
#define config2 UART_TX_PIN_LOW | UART_RX_ENABLE | UART_TX_ENABLE | UART_INT_TX | UART_INT_RX_CHAR | UART_ADR_DETECT_DIS | UART_RX_OVERRUN_CLEAR
Open UART2 with config1 and config2. The third input is the value to get the generated BAUD value (not exact to the desired).
OpenUART2( config1, config2, pbClk/16/DESIRED_BAUDRATE-1); // calculate actual BAUD generate value.
Configure UART2 RX Interrupt with priority 2
ConfigIntUART2(UART_INT_PR2 | UART_RX_INT_EN);
Must enable glocal interrupts - in this case, we are using multi-vector mode
INTEnableSystemMultiVectoredInt();
Display start up information. The function putsUARTx is used to display strings.
putsUART2("*** UART Interrupt-driven Application Example ***\r\n"); putsUART2("*** Type some characters and observe echo and LED1 toggle ***\r\n");
Enter while loop
while(1) //let interrupt handle the UART { }; return 0; } // end main function
UART 2 interrupt handler with priority level set at 2
void __ISR(_UART2_VECTOR, ipl2) IntUart2Handler(void) { //Is this an RX interrupt? if(mU2RXGetIntFlag()) { // Clear the RX interrupt Flag mU2RXClearIntFlag(); //Read the data data = (char) ReadUART2(); // Echo what we just received. putcUART2(data); // Toggle LED to indicate UART activity mLED_1_Toggle(); if(data == 'c') { mLED_2_On(); mLED_3_Off(); } else { mLED_3_On(); mLED_2_Off(); } } // We don't care about TX interrupt if ( mU2TXGetIntFlag() ) { mU2TXClearIntFlag(); } } // end ISR
Compile and Program this Hex file to the PIC.
Open Hyperterminal with the following information:
- Bits per second: 9600
- Data bits: 8
- Parity: None
- Stop bits: 1
- Flow Control: Hardware
If you press reset on the PIC32 board, you should see the start up message.