Electronic – PIC to PIC serial communication

communicationmicrocontrollerpicserial

I need to send all port info from one pic to another using serial port..

currently using 9600bps baud rate. on pic18f4550 running at 20mhz clock.

i have used this code to send and receive data of a single port.

send:

while(1)
{
    TXREG=PORTB;
    while(PIR1.TXIF==0);
    delay_ms(100);
} 

and receive:

while(1) 
{
       while(PIR1.RCIF==0); 
       PORTB=RCREG;
}

on tx part PORTB is set as input and at RX PORTB is set as output.

I need to send/receive all ports info.. How can it be done?

Best Answer

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.