I know this is old but might be helpful incase anyone stumbles apon it like I did.
I was having issues with overrun errors in my PIC18F452 communicating to a beaglebone black over USART. With quite a busy program going on in both the beagle and the PIC, there was lots of data being sent between the two constantly. After some amount of time after using the instrument the PIC stopped receiving all messages.
After being stuck and baffled by this for more than 3 weeks, I found this:
http://www.piclist.com/techref/postbot.asp?by=thread&id=%5BPIC%5D+PIC18+UART+stops+receiving&w=body&tgt=post
which described PIC code to handle and clear Overrun Errors:
if(OERR)
{
do
{
temp = RCREG;
temp = RCREG;
temp = RCREG;
CREN = 0;
CREN = 1;
} while(OERR);
}
if(FERR)
{
temp = RCREG;
TXEN = 0;
TXEN = 1;
}
Running this snippet every now and then in the PIC program allowed me to recover from occasional overrun errors without restarting the PIC.
Hope that helps anyone with similar issues
You need to write a simple transfer protocol.
Basically you need to come up with a way of one PIC saying to the other: "This is the start of the data, here is the data, and this is the end of the data". That could be as simple as starting and ending your data stream with characters that are identifiable, ideally characters that aren't ever going to be in your data stream, or more complex whereby you have a header describing the data that's about to arrive, and a checksum to ensure that the data was received correctly.
The most understandable (to us) method is to send the data as pure ASCII text, maybe in the form of a hexadecimal string. So for 4 ports you would send 8 characters 0-9A-F followed by a carriage return to mark the end of the data, say a stream like:
017F36AB<cr>
017F36AB<cr>
017F26AB<cr>
017F26AB<cr>
017FA6AB<cr>
etc.
Then it is up to your receiving PIC to decode each character into a 4-bit value, and join together character pairs into a single 8 bit value.
The simplest reception method would be to define an array that is big enough to receive all the characters (8 bytes in this case). As characters arrive, you look to see if it's a character. If it is, then you decode the characters in your array. If it's 0-9 or A-F, then you slide the characters in your array down one space (losing the oldest), then adding the new character in to the top of your array. This is called a sliding window where you have an 8-byte "window" on the data stream that is arriving, and the data "slides" past the window.
A more complex arrangement would be like I wrote for my ICSC Library for Arduino which defines a sending and receiving station (to allow communication between lots of chips), a command, a variable length block of data, and a final checksum. The packet format I came up with is:
(All values are 8-bit and symbolic names are ASCII standard values.)
Preamble:
76543210
+--------+
| SOH |
+--------+
| SOH |
+--------+
| SOH |
+--------+
| SOH |
+--------+
Packet:
76543210
+--------+
| SOH |
+--------+
| DestID |
+--------+
| OrigID |
+--------+
| Cmd |
+--------+
| DatLen |
+--------+
| STX |
+--------+
| Data 0 |
| Data 1 |
| ... |
| Data N |
+--------+
| ETX |
+--------+
| Cksum |
+--------+
| EOT |
+--------+
Checksum is sum of all bytes between (but not including) SOH and ETX, modulus 256.
Special destination address 0x00 is the broadcast. All stations will receive and
act upon messages sent to this address.
Addresses that equate to the ASCII symbols SOH etc should be avoided.
Packet reception and identification is through a 6-byte sliding window identifying
the header of a packet. As bytes arrive they enter the top of the window and
they work their way down to the bottom as more bytes arrive. When the first
byte of the window is SOH, the last byte is STX, and the Dest ID is either 0x00
or the ID of the receiving station, it is assumed a valid packet is arriving.
From this point on DatLen bytes are then read into the data buffer.
If the next three bytes do not equal ETX, the valid checksum, and EOT, then the
packet is rejected. Otherwise the function associated with Command is executed.
Best Answer
You already are sending integer values over the UART with the code you show. Your problem is apparently sending integers that are more than 8 bits wide.
The UART inherently only sends 8 bit bytes (in the most common configuration) at a time. If you want to send a wider integer, you have to send more than one byte to represent that integer. For example, you might decide that all multi-byte integers are to be sent in least to most significant byte order. If you have a 16 bit integer to send, then you send the low 8 bits first, then the high 8 bits. The receiving PIC does the reverse. It receives the low 8 bits first, then the high 8 bits, and writes those consecutively in memory so that the rest of the system can access the value as a 16 bit integer.
24 bit integers, for example, are sent the same way except that 3 bytes are needed instead of 2. 32 bit integers require sending 4 bytes.
Note that none of this has anything to do with sending numeric values to show up on a terminal emulator. Terminals display characters. Each possible character has a pre-determined binary code. You send the byte containing the code for a character, and that character shows up on the terminal. For example, the code for the letter "A" is 65. If you send the byte 65, then a terminal will show "A". Likewise, sending 48 causes the terminal to show "0". Look up something called ASCII code. That will tell you what the byte values are for each of the characters the terminal can show.
Here is a example to illustrate all of the above. Suppose you wanted to send the 16 bit integer value 9525. Let's convert that to HEX so we can see the individual bytes easily: 2535h. You have previously decided to send multi-byte values in low to high byte order. The two bytes you will send are therefore 35h and 25h in that order. These have the decimal values 53 and 37. You send these bytes, and the other PIC receives 53 and 37. Note that (37 * 256) + 53 = 9525, which is the value you are transmitting.
If these bytes were to be intercepted by a terminal, then you'd get whatever characters map to 53 and 37, which happen to be "5" and "%". So the terminal will display "5%" when you send 9525. If you wanted the terminal to display "9525" you'd have to send the byte values for the characters "9", "5", "2", and "5". Those happen to be 57, 53, 50, and 53. That is a lot more complicated since the PIC has to figure out the decimal digits of the binary integer it has, convert them to the character codes for those digits, then send those.
Generally it's a lot easier to do any kind of user interface conversion on the PC and let the PIC send and receive native binary. Converting the binary integer 9525 to the characters "9525" is trivial for the PC, but can require substantial code space and cycles on a small PIC.