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. Download the driver software.
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). Notice how this code has to wait until a character is read. The next example uses interrupts to detect when a key is pressed. This code shows many different constants for the 2 configuration variables (config1 and config2). Most of these are default constants. To see other options inspect uart.h in C:\Program Files\Microchip\MPLAB C32\pic32mx\include\peripheral.
/********************************************************************* * * 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.
/********************************************************************* * * UART Interrupt Example * ********************************************************************* **********************************************************************/ #include "HardwareProfile.h" #define DESIRED_BAUDRATE (9600) // The desired BaudRate volatile unsigned char data; int main(void) { int pbClk; // 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. // 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(); putsUART2("*** UART Interrupt-driven Application Example ***\r\n"); putsUART2("*** Type some characters and observe echo and LED flashes ***\r\n"); while(1) //let interrupt handle the UART { } return 0; }
// UART 2 interrupt handler // it is set at priority level 2 void __ISR(_UART2_VECTOR, ipl2) IntUart2Handler(void) { // Is this an RX interrupt? if(mU2RXGetIntFlag()) { // Clear the RX interrupt Flag mU2RXClearIntFlag(); 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(); } }
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.