0
\$\begingroup\$

I'm having trouble performing basic communication between two IC's. and AT89S52 and an AT89C4051. Both are connected using 6 GPIO pins of which 4 of them on each microcontroller are high nibbles of port pins. I also share the same 4 nibble pins on the AT89S52 with an HM628128 RAM IC.

The PCB trace length from pin to pin is less than 30mm. (I try to keep them as short as possible). and the clearance and trace width are 11 mils each, so I don't think that could cause the problem.

I did however look at an answer to one other question I posted here (Maximum reliable speed of GPIO pin given only capacitance and no resistance), and someone mentioned that by connecting parts to the GPIO line, the capacitance increases and that can increase the time required to make the input value of a GPIO line at a stable state which is why I deliberately sprinkled in a few NOPS into my code in hopes that I satisfied the timing requirements, but perhaps I didn't?

Initially I was going to post this on stackoverflow.com but for some reason I feel the problem has to do with poor timing with the hardware rather than software bugs. I did document it so everyone knows exactly what I'm trying to achieve. As you can see in code, I tried using synchronization but when it comes to receiving data, my code on the client stalls.

Each microcontroller uses the same clock speed of 22.1184Mhz with 33pF pull-down ceramic capacitors attached to it.

This is my code:

  ; ****************************************************
  ; Client: AT89S52
  ; ****************************************************

  setmyID:
  ;send SETIDL command, #6, SETIDH, and #1 in that order to adapter
  mov A,#61h
  mov R5,A
  mov R6,#SETIDL
  swap A
  lcall cmd
  mov R6,#SETIDH
  mov A,R5
  lcall cmd
  ret

  cmd:
  ;reset triggers
  setb CLK
  setb RESULT

  ;only feed high nibble to adapter
  anl A,#0F0h
  mov R7,A
  nop ;trying to sync with adapter but failed?

  ;set high nibble of port to my command and leave low nibble alone
  mov A,D
  anl A,#0Fh
  orl A,R6
  mov D,A

  clr CLK ;lower clock line to tell adapter we have data
  nop
  jb RESULT,$ ;wait till adapter acknowledges it
  nop

  ;set high nibble of port to my data and leave low nibble alone
  mov A,D
  anl A,#0Fh
  orl A,R7
  mov D,A

  setb CLK ;raise clock line to tell adapter we have data
  nop
  jnb RESULT,$ ;wait till adapter acknowledges it

  ;Make high nibble of port value high so it accepts input
  nop
  mov A,D
  orl A,#0F0h
  mov D,A

  clr RESULT ;tell adapter were ready
  nop
  jb CLK,$ ;wait until adapter sends data

  ;grab the data (to accumulator)
  nop
  mov A,D
  anl A,#0F0h

  setb RESULT ;tell adapter we got the data
  nop
  jnb CLK,$ ;wait until adapter acknowledges this

  ;PROBLEM: code never reaches here :(
  ret


  ; ****************************************************
  ; Adapter: AT89C4051
  ; ****************************************************

  ;endless main loop in adapter. Ports are all setup to accept data at this point

  main:

;set lines high to accept input from client
setb RESULT
setb CLK

jb RESULT,noout
    ;when client lowers RESULT line, its ready to receive data

    ;Load result (LASTR) onto the data line. LASTR only has data in high nibble.
    nop
    mov A,D
    anl A,#0Fh
    orl A,LASTR
    mov D,A

    clr CLK ;let client know we sent data

    nop
    jnb RESULT,$ ;wait until client is ready to continue

    ;Allow incoming data into high nibble
    nop
    mov A,D
    orl A,#0F0h
    mov D,A
    ;and we're done
    ajmp main
noout:

jb CLK,main
    ;here, client wants to send data to us CLK is now low.

    ;First incoming nibble is command number
    nop
    mov A,D
    anl A,#0F0h
    mov R4,A

    clr RESULT ;tell client we got the command
    nop
    jnb CLK,$ ;wait until client sends data
    nop
    mov A,D
    anl A,#0F0h
    ; function processing here (works) then restart loop
  ajmp main

UPDATE

Correct me if my theory is wrong, but I was thinking my only two options are to either lower the crystal speed and/or use external pull-up resistors on the shared GPIO lines.

I'm thinking if I use external resistors, things might work because then the waiting time to turn the output of a pin into a stable state is low. For example, if I use 4.7K pull-up for every pin and each pin on each device has about a 10pF capacitance, then worst case scenario (seeing that resistors are then in parallel):

 4700 * 0.000000000030 = 0.141uS

But without the pull-up, I'd have to factor the resistance of each device and calculate the three in parallel. I'm gonna say 20K best case. so:

 20000 * 0.000000000030 = 0.6uS

With a 22.1184Mhz clock, its about 0.53uS per instruction execution which is under 0.6uS. This is why I was thinking of including pull-ups.

I'd rather not lower the clock speed but if its my only option then I will.

Am I right with my theories or is there another solution?

\$\endgroup\$
  • 3
    \$\begingroup\$ I already mentioned this to you in an earlier Q of yours: the same clock speed does NOT mean they are the exact same clock. They can drift relative to each other. And different processors may even have slightly different setup and hold times relative to the clock phases, besides. You need to account for this in ANY robust communications scheme. (I even wrote a white paper on this about 15 years ago.) \$\endgroup\$ – jonk Oct 23 '17 at 18:47
  • \$\begingroup\$ Only reliable way to do a communication bus with GPIO is with interruptions (i.e. detecting rising edge), as jonk said you cannot count on the process clock speeds to be the same. \$\endgroup\$ – lucas92 Oct 23 '17 at 19:06
  • \$\begingroup\$ @jonk Thats why I made my code in both the adapter and client as shown so it waits until the other micro has finished. In the past I didn't give the other micro a chance to send out an acknowledgement. \$\endgroup\$ – user152879 Oct 23 '17 at 20:06
  • \$\begingroup\$ @Mike Are you using a master-slave clocking arrangement? Or is this a peer-relationship between devices where either may acquire a master position? \$\endgroup\$ – jonk Oct 23 '17 at 20:20
  • \$\begingroup\$ The at89S52 (client) is the master initiating almost everything, and the at89c4051 (adapter) is the slave, however the adapter can do other work if the client doesn't make any request. \$\endgroup\$ – user152879 Oct 23 '17 at 20:25
1
\$\begingroup\$

Most PCB layouts will be fine under 40Mhz. The fastest thing you could do for a GPIO is turn it on and off at the clock speed, depending on the way your I/O and CPU architecture is this would usually happen at 1/2 of the CPU clock speed or 11Mhz. Most digital chip fanouts would support 2 devices on the GPIO. The best thing to do here is get a scope or logic analyzer on the pin and see if the square wave is rounded of (below is an extreme example) then you have not enough drive or too much load.

enter image description here

\$\endgroup\$
  • \$\begingroup\$ Only testing tools I have is a basic digital multimeter and LEDs, and I don't think they're much help. The only things connected on the nibble data line are the two micros and the RAM address line. The ram though works fine (I tested it on the same board). For the clock and result line, they are managed only by the 2 micros. \$\endgroup\$ – user152879 Oct 23 '17 at 20:13
  • \$\begingroup\$ If your time is worth any kind of money, then invest in a cheap bench scope or logic analyzer. \$\endgroup\$ – laptop2d Oct 23 '17 at 23:33
  • \$\begingroup\$ What other things can I try until I get one of those tools? \$\endgroup\$ – user152879 Oct 23 '17 at 23:39
  • \$\begingroup\$ Other than endless iterations of trial and error, I'm not sure. \$\endgroup\$ – laptop2d Oct 23 '17 at 23:42
  • \$\begingroup\$ Turns out such tools in person are expensive and ordering online takes awhile but what I will do since there is a store nearby is order 11.0592Mhz crystals and use that to give the pin logic values more time to settle and hopefully theres communication. \$\endgroup\$ – user152879 Oct 24 '17 at 2:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy