Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Hardware USART PIC18F4550 Read and Write Question

Status
Not open for further replies.

Micro9900

New Member
Hey guys, I am having a bit of trouble getting USART to work. I am using two PIC18F4550 and two XBEE wireless modules for commication between PICs. I believe I have the XBEE set up correctly and would like to make sure that I have both of the microcontorller's code properly written before I proceed to troubleshoot further. I am using MPLAB v8.8 with C18 LITE. Additionally, I am using Microchips library for hardware USART (packaged with C18) as shown below.

Here are the code snipets for both the transmitting and receiving microcontroller:

Transmitting Microcontroller:
Code:
#include <p18f4550.h> // Uses Microchip's predefined library for 18F4550
#include <delays.h>	  // Uses Microchip's predefined library for delay methods
#include <usart.h>    // Uses Microchip's predefined library for hardware USART
...
		while(1)
		{
                 ...

                 // --Setup/initialize USART using predefined functions from Microchip's hardware USART library
			OpenUSART(  
			      USART_TX_INT_OFF &   			 // disables transmission interrupt     
			      USART_RX_INT_OFF &  			 // disables reception interrupt 							
    		              USART_ASYNCH_MODE & 			 // sets USART to asynchronous mode  
    		              USART_EIGHT_BIT& 				 // sets USART to use 8-bit data mode 
    		              USART_CONT_RX &  				 // sets the port in continues receive mode 
    		              USART_BRGH_LOW,  				 // uses the low speed Baud rate formula 
			       12					// sets Baud to 9600 BPS using 8MHz in calculation (actual baud rate is 9600.614)
     		              );  
	
			while (BusyUSART()); // Makes sure the serial port isn’t busy
	                sendUARTbyte1=(char)(tempReadIn1&0xFF00);	// Get MSB byte for sensor T1
			sendUARTbyte2=(char)(tempReadIn1&0x00FF);	// Get LSB byte for sensor T1
			WriteUSART(sendUARTbyte1);			// Send MSB byte for sensor T1
			WriteUSART(sendUARTbyte2);			// Send LSB byte for sensor T1

			sendUARTbyte1=tempReadIn1&0xFF00;	// Get MSB byte for sensor T2
			sendUARTbyte2=tempReadIn1&0x00FF;	// Get LSB byte for sensor T2
			WriteUSART(sendUARTbyte1);			// Send MSB byte for sensor T2
			WriteUSART(sendUARTbyte2);			// Send LSB byte for sensor T2

			CloseUSART();

...
}

Receiving Microcontroller:
Code:
#include <p18f4550.h> // Uses Microchip's predefined library for 18F4550
#include <delays.h>	  // Uses Microchip's predefined library for delay methods
#include <usart.h>    // Uses Microchip's predefined library for hardware USART
...
		while(1)
		{
                    ...

// --Setup/initialize USART using predefined functions from Microchip's hardware USART library
	       OpenUSART(  
			USART_TX_INT_OFF &   			 // disables transmission interrupt     
			USART_RX_INT_OFF &  			 // disables reception interrupt 							
    		        USART_ASYNCH_MODE & 			 // sets USART to asynchronous mode  
    		        USART_EIGHT_BIT& 				 // sets USART to use 8-bit data mode 
    		        USART_CONT_RX &  				 // sets the port in continues receive mode 
    		        USART_BRGH_LOW,  				 // uses the low speed Baud rate formula 
			12					// sets Baud to 9600 BPS using 8MHz in calculation (actual baud rate is 9600.614)
     		    );  
	
			while (BusyUSART()); // Makes sure the serial port isn’t busy
			readUARTbyte1=ReadUSART();			// Get MSB (byte) for sensor T1
			readUARTbyte2=ReadUSART();			// Get LSB (byte) for sensor T1
			tempReadIn1 = readUARTbyte1;		// Set MSB (byte) for sensor T1
			tempReadIn1 = tempReadIn1 << 8;		// Shift byte
			tempReadIn1 += readUARTbyte2;		// Set LSB (byte) for sensor T1

			readUARTbyte1=ReadUSART();			// Get MSB (byte) for sensor T2
			readUARTbyte2=ReadUSART();			// Get LSB (byte) for sensor T2
			tempReadIn2 = readUARTbyte1;		// Set MSB (byte) for sensor T2
			tempReadIn2 = tempReadIn2 << 8;		// Shift byte
			tempReadIn2 += readUARTbyte2;		// Set LSB (byte) for sensor T2
			
			CloseUSART();
			tempReadTotal1 = tempReadIn1;
			tempReadTotal2 = tempReadIn2;

...
}

I have both microcontrollers oscillating at 8MHz. I have calculated the Buard rate to 9600 using the second formula:

SPBRG = (Fosc/(64 x Baud rate)) - 1, BRGH=0

SPBRG = (8MHz/(64 x 9600)) - 1 => 12.02, so I used 12

And, from the code above, I believe both microcontrollers are set to work using asynchronous communication

My question are as follows:
1. Is it okay to have the openUART() function within the main while loop
2. Do I need the closeUART() function when I am done reading?
3. Is there something I am missing that I am not configuring?

Any additional information or foresight as to what I may be doing wrong is much appreciated. Thank you.
 
Last edited:
You should init the usart once.

If your code is in a multi thread environment.. you need to close the port.. but if there is only this program happening then no you don't need to.

Also this needs shifting or the MSB will not be correct.
Code:
   sendUARTbyte1=(char)(tempReadIn1&0xFF00);	// Get MSB byte for sensor T1
   sendUARTbyte2=(char)(tempReadIn1&0x00FF);	// Get LSB byte for sensor T1
   ...
   sendUARTbyte1=tempReadIn1&0xFF00;   // Get MSB byte for sensor T2
   sendUARTbyte2=tempReadIn1&0x00FF;   // Get LSB byte for sensor T2
like this
Code:
   sendUARTbyte1=(char)((tempReadIn1&0xFF00) >> 8);	// Get MSB byte for sensor T1
   sendUARTbyte2=(char)(tempReadIn1&0x00FF);	    // Get LSB byte for sensor T1
   ....
   sendUARTbyte1=(tempReadIn1&0xFF00) >> 8 ;	// Get MSB byte for sensor T2
   sendUARTbyte2=tempReadIn1&0x00FF;	   // Get LSB byte for sensor T2
 
Thank you so much for the reply. I just have a few more questions if you be willing to assist me a bit further.
__________________

1. Do I need to configure pin RC7 (RX) as an input or by initializing the UART? Are the the pin configurations already set up (RC7 (Rx) input RC6 (Tx) output)?

2. Are the start and stop bits (for each frame) for asynchronous communication taken in to account within the read and write functions?

3. I have the read and writes in a loop (microcontroller is at 8MHz) is there any extra timing I should be concerned with? Do I need to match up the timings in terms of when I read on one microcontroller and when I write on another microcontroller? Or is this handled by the baud rate and due to the fact that I am using asynchronous communication?
__________________

Any further insight into the matter is greatly appreciated. Thank you.
 
Last edited:
1. They should both be set to input.
2. Yes.
3. It is a good idea to have a small delay on the transmit side in case the receive code is slower.

I can't comment on your code as I don't use the microchip libraries.

Mike.
 
Just to clarify a bit. The Rx pin should be set to an input (RC7, so TRISC = 0x80). I am only using one way communication (using only Tx on one microcontroller and Rx on another) as shown below.

**broken link removed**

So, Rx (RC7) = input and Tx (RC6) = output correct?

The result should be TRISC = 0x80 on the microcontroller that is receiving and TRISC = 0x00 on the one that is transmitting, correct? Additionally, do I need a pull down resistor (maybe 10K) to keep Rx from floating (as with a push button)?

Sorry for the multitude of questions, I just want to be a bit more confident on a few things before I proceed to troubleshoot.

EDIT:

Is it also possible to troubleshoot the UART communication by directly connecting the TX pin from one microcontroller to Rx pin of the other microcontroller?
 
Last edited:
Nope, both must be set to input. A quick check of the data sheet can often answer these questions.

rs232-png.59032


Mike.
 

Attachments

  • rs232.png
    rs232.png
    22.6 KB · Views: 2,689
Last edited:
Wow, thanks for clearing that up. That would have definitely caused some major headaches. Thanks so much for the help guys! I am going to begin troubleshooting. I plan to try to directly connect the TX pin of transmitting microcontroller to the RX pin of the other microcontroller to see if I can bypass having to go through XBEE, so I can eliminate any variables that would cause even more issues.

EDIT:
____________________
I changed the pin configurations on both microcontrollers to the following

TRISC = 0xC0;
RCSTAbits.SPEN=1;

EDIT2:
____________________
Figured out that you need:

while (!DataRdyUSART());

on the receiving microcontroller before reading. This function checks to see if the register is ready to be read.

EDIT 3:
____________________
I successfully communicated a single byte to the other microcontroller, but I still have to work out a few things.

EDIT 4:
____________________
I found out that you need to reset SPEN=1 since the functions (read and write) manipulate that bit. Before it would only read the byte once and stop the operation.

So, if I am not mistaken you need:

Code:
while(1)
{
     if(DataRdyUSART())
     {
       	   readUARTbyteH=ReadUSART();			// Get byte from UART
           RCSTAbits.SPEN=1;
     }
}
 
Last edited:
Update: I got it to work, but I see fluctuations with the data I am displaying to the character LCD I am using. For the most part I see the desired output, but then I see random numbers outputted to the display. I tried detecting the error using the following:

Code:
   if(DataRdyUSART())
     {
         readUARTbyteH=ReadUSART();			// Get byte from UART
      
         if(USART_Status.FRAME_ERROR == 0 & USART_Status.OVERRUN_ERROR == 0)
         {
          tempReadIn1 = readUARTbyteH;		// Set MSB (byte) for sensor T1
	  tempReadIn1 = tempReadIn1 << 4;		// Shift bits for reading value to LCD       	  
 
          }
          else
	{
		RCSTAbits.SPEN=0;
		RCSTAbits.CREN=1;
		RCSTAbits.SPEN=1;
	}
     }

Is the baud rate inadequate? I looked in the table and it says I should expect a .16% error. I also have a delay of 1ms before writing out of the transmitting microcontroller's UART. I'm not sure what the cause of this fluctuation could be... Am I not setting the delay appropriately on the transmitting end?
(sorry for double post)

EDIT2: I managed to get the XBEE working, it seems more stable. So, there is a bit more to it if you want to directly connect one uC to another in terms of stability. So, the XBEE seems to be handling it better. I'm going to test it out a bit more later. I need to take a break heh.

Also note that if you are going to directly connect both microcontrollers directly make sure you wire both the Tx and Rx pins and not just what you are planning to use. Otherwise it may not work properly. This goes for connecting it to the XBEE as well.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top