¿Este código de máquina no es suficiente para la sincronización del chip?

0

Tengo problemas para realizar una comunicación básica entre dos circuitos integrados. y AT89S52 y un AT89C4051. Ambos están conectados mediante 6 pines GPIO, de los cuales 4 de ellos en cada microcontrolador son nibbles altos de pines de puerto. También comparto los mismos 4 nibble pins en el AT89S52 con un HM628128 RAM IC.

La longitud del trazo de PCB de pin a pin es inferior a 30 mm. (Intento mantenerlos lo más cortos posible). y el espacio libre y el ancho del trazado son de 11 milésimas de pulgada cada uno, por lo que no creo que eso pueda causar el problema.

Sin embargo, sí miré la respuesta a otra pregunta que publiqué aquí ( Velocidad máxima confiable del pin GPIO dado solo capacitancia y sin resistencia ), y alguien mencionó que al conectar partes a la línea GPIO, la capacitancia aumenta y eso puede aumentar la el tiempo requerido para hacer que el valor de entrada de una línea GPIO esté en un estado estable, es por eso que rocié deliberadamente algunos NOPS en mi código con la esperanza de que cumpliera con los requisitos de tiempo, pero tal vez no?

Inicialmente iba a publicar esto en stackoverflow.com, pero por alguna razón, siento que el problema tiene que ver con una mala sincronización con el hardware en lugar de errores de software. Lo documenté para que todos sepan exactamente lo que estoy tratando de lograr. Como puede ver en el código, intenté usar la sincronización, pero cuando se trata de recibir datos, mi código en el cliente se detiene.

Cada microcontrolador utiliza la misma velocidad de reloj de 22.1184 MHz con los condensadores cerámicos desplegables de 33pF conectados.

Este es mi código:

  ; ****************************************************
  ; 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

ACTUALIZAR

Corríjame si mi teoría es errónea, pero estaba pensando que mis dos únicas opciones son bajar la velocidad del cristal y / o usar resistencias de pull-up externas en las líneas GPIO compartidas.

Estoy pensando que si uso resistores externos, las cosas podrían funcionar porque entonces el tiempo de espera para convertir la salida de un pin en un estado estable es bajo. Por ejemplo, si utilizo 4.7K pull-up para cada pin y cada pin en cada dispositivo tiene aproximadamente una capacitancia de 10pF, en el peor de los casos (viendo que las resistencias están en paralelo):

 4700 * 0.000000000030 = 0.141uS

Pero sin el pull-up, tendría que factorizar la resistencia de cada dispositivo y calcular los tres en paralelo. Voy a decir 20K mejor de los casos. entonces:

 20000 * 0.000000000030 = 0.6uS

Con un reloj de 22.1184Mhz, su ejecución de aproximadamente 0.53uS es inferior a 0.6uS. Por eso estaba pensando en incluir pull-ups.

Prefiero no bajar la velocidad del reloj, pero si es mi única opción, lo haré.

¿Estoy en lo cierto con mis teorías o hay otra solución?

    
pregunta

1 respuesta

1

La mayoría de los diseños de PCB estarán bien a menos de 40Mhz. Lo más rápido que podría hacer por un GPIO es encenderlo y apagarlo a la velocidad del reloj, dependiendo de la forma en que su arquitectura de E / S y CPU sea esto, generalmente sucedería a la mitad de la velocidad del reloj de la CPU o 11Mhz. La mayoría de los fanouts de chips digitales admitirían 2 dispositivos en el GPIO. Lo mejor que puede hacer aquí es obtener un analizador de alcance o lógico en el pin y ver si la onda cuadrada está redondeada (a continuación se muestra un ejemplo extremo), entonces no tiene suficiente unidad o demasiada carga.

    
respondido por el laptop2d

Lea otras preguntas en las etiquetas