Fr. Tom McGahee says
Yes, you can transfer data using a single pin. If you only need one-way communication, then you wire one PIC as the transmitter, and the other PIC as the receiver. You can do this with ANY microcontroller.The next level of complexity allows a single i/o pin on each PIC to allow TWO-WAY communications between the PICs. This trick can only be done by microcntrollers that have programmable i/o pins.
Here's the basic method:
A single wire connects both PICs (ya gotta have a common ground, of course!) BOTH PICs initially have their i/o pin connected to this line programmed as an INPUT. A 10k pullup resistor connected to +5 ensures that this line will be pulled high whenever both PICs are listening.OK, eventually one of the PICs has something to say. It first ensures that the other PIC is not talking. Once it is assured of this, it programs its i/o line as an output and sends out a low. The PIC that is still listening will detect this high-to-low- transition (perhaps via an interrupt), and will see it as the beginning of a Start Bit. If you are using standard UART techniques, then the Start Bit will be followed by the usual 8 data bits and a minimum of one stop bit (I prefer two stop bits)..
The receiving PIC places the received data into a register and terminates the interrupt. The receiving PIC can then move, process, or otherwise handle the received byte. It should then set the original receiving register to 0x00. Thus the receiving byte can be tested. If it is 0x00 it means there is no byte received. If there is anything *else* there, then it is valid data, ready to be processed. If 0x00 is not a good value for you to use as an empty marker, then choose some other value, *or* set a software flag to indicate that data is ready, and clear the flag once the data has been moved.
To determine if it is OK to talk it is best to make sure that
(a) the shared line is high, and
(b) that the shared line has *been* high for at least the time it would take to output a complete byte.I usually accomplish (b) by maintaining a "sticky" counter. At the END of a reception this counter is set to 1 or some other number. Periodically in the program I increment this counter *if* the shared line is still high. Once it rolls over back to 0x00 I *leave* it there. If the PIC wants to send data it checks the value of the counter. If it is not 0x00, then it increments the counter, does a wait for some tens of microseconds, and then loops around and checks the counter again. Eventually the counter will reach 0x00, and the PIC can commence transmission. (note that the interrupt receive routine will pre-set this counter if a reception occurs, so there is no need to check the line itself in the counter wait loop)
The inital number stuffed into the counter at the end of the reception routine should be chosen so that the minimum time before rollover of the counter to 0x00 is greater than the time needed to send a complete byte. You can give one of the PICs a lower priority for transmissions by giving it a longer count interval than the other PIC has.
If you are the adventurous type, then you might decide to make the max wait delay equal to the time it takes to send only a single BIT. I prefer safety to speed most of the time.