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?