• 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.

Interfacing between two microcontrollers over two wires.

Thread starter #1
This question is more of a generic question in which I'm seeking an optimized algorithm.

Basically I have two microcontrollers. One runs at a speed 6x slower than the other. Special feature pins of the micros are used up and all I have are two GPIO pins from each one for communication. One pin is the clock and one is data.

What I'm trying to do is have the slow micro request initial information from the faster micro. For example, I'm sending byte 5A to the faster micro and I expect it to return A5 but it does not.

Here's the code I tried:

For Slow micro that wants information
;request
set counter to 8
Start loop
rotate right LSB from accumulator to Carry
set GPIO pin to Carry value
lower clock
raise clock
decrement counter
restart loop if counter isn't 0.

;response
set counter to 8
Start loop
lower clock
raise clock
get Carry value from GPIO pin
rotate right Carry into MSB of accumulator
decrement counter
restart loop if counter isn't 0.
For Fast micro that has information
;get request
set counter to 8
Start loop
wait until clock is low
get Carry value from GPIO pin
rotate right Carry into MSB of accumulator
wait until clock is high
decrement counter
restart loop if counter isn't 0.
if accumulator is 5A then
set accumulator to A5
end if
;do response
set counter to 8
Start loop
wait until clock is low
rotate right LSB from accumulator to Carry
set GPIO pin to Carry value
wait until clock is high
decrement counter
restart loop if counter isn't 0.
What am I doing wrong?
 
#2
At work I do this all the time between a micro and a touch screen for industrial equip ... for all intentions, the touch screen is another micro.

These systems have to be spot on and not miss a beat in terms of communication. Handshaking is a must, as well as sending data in structured packets.

A typical packet might consist of 6 bytes .... [SYNC1][SYNC2][Address][Data][CRC][Seed]

1) SYNC1 and SYNC2 are always the same value where the receiver doesn't process any data until those two BYTES are received
2) The Address is a reserved block of memory on the receiver you want to write Data to.
3) Data is what you want to fill the Address with on the receiver
4) CRC is a simple XOR of all 6 BYTES including the Seed
5) The Seed is essentially a moving target ... it can be as simple as a counter that counts to 255 and recycles back to 0. The purpose of the Seed is to create change even if the data being sent is the same. There are deeper reasons for this, that I won't go to far into other than it adds a slight degree of robustness.

The key thing to consider is that BOTH the touch screen (micro) and the micro work the same way from an independent point of view. The Address location represents a reserved area of memory that exists on both micro's. Within each micro the functionality works based on what Data is in the memory Address rather than what is immediately streaming in serially. To prevent collisions, on either end, each micro cannot write to its own reserved memory block Address unless the Data is received serially. It can only read from it's own reserved memory block Address. It can however read and write to non reserved areas of memory just as you normally would.
 
Thread starter #5
These are the functions I have for the 8051 so far
but the problem is it won't work for two micros with speeds of a 6x difference from each other.
Code:
;called from mini uC (micro thats 6x slower)
docpucmd:
setb CLK
mov R7,#8h
b1:
jnb CLK,$
rlc A
mov DAT,C
clr CLK
nop
setb CLK
djnz R7,b1
setb DAT
mov R7,#8h
b2:
setb CLK
jb CLK,$
mov C,DAT
jnb CLK,$
clr CLK
rlc A
djnz R7,b2
setb CLK
ret

;incoming data (from slow uC to fast uC)
dgetcmd:
setb DAT
mov R7,#8h
gb2:
setb CLK
jb CLK,$
jnb CLK,$
clr CLK
mov C,DAT
rlc A
djnz R7,gb2
setb CLK
ret

;outgoing data (from fast uC to slow uC)
dputres:
setb CLK
mov R7,#8h
gb:
jnb CLK,$
rlc A
mov DAT,C
clr CLK
acall i2cdel
setb CLK
djnz R7,gb
ret

;delays
i2cdel:
nop
nop
nop
nop
ret
 

Pommie

Well-Known Member
Most Helpful Member
#6
Use I²C (IIC = inter integrated circuit) as it can run at any speed between 0 (DC) and about 400kHz. Google "bitbang I²C 8051" should get you working routines.

Mike.
 
Thread starter #7
Their routines I think would only work if both devices share the same clock speed or are very close to the same clock speed. I'm dealing with two micros in which the speed difference is 6x apart
 

Pommie

Well-Known Member
Most Helpful Member
#8
They will work at any clock speed that suits both processors. If the slower one needs more time it can use clock stretching to slow the transfer down. It is a protocol especially designed for such a situation.

Mike.
 

Mike - K8LH

Well-Known Member
#10
Just use an RS232 type serial protocol, speed of the processor makes no difference, as you adjust the timing routines accordingly - easily done using software serial.
It may be worth checking out the asynchronous 1-pin Icom CI-V protocol (reference info'). I was able to implement a single pin bit-banged interface on a PIC 12F683 to my Icom 756PRO-II transceiver at 9600 baud and it worked quite well.
 
#11
mik3ca,

Make your life easier and use the UART built into the 8051 the buffer is only like one or two BYTES so you will need to process the incoming data on your own. In my setup within the ISR I have a BYTE FIFO, and then apply the 6-BYTE packet format I described above. If the packet does not match then it does not get processed.
 

Latest threads

EE World Online Articles

Loading

 
Top