PIC32MX: RS232

From Mech
Jump to navigationJump to search

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

Usb-rs232-cable.jpg

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). Notice how this code has to wait until a character is read. The next example uses interrupts to detect when a key is pressed.

/*********************************************************************
 *
 *                  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.