Más rápido 8051 no toma correctamente el estado del pin 8051 más lento

0

Estoy tratando de hacer una transacción de datos bastante simple entre dos microcontroladores 8051 usando una variante del protocolo SPI. El grande es un esclavo y el pequeño es un maestro.

La documentación del esclavo (micro más grande) indica que la velocidad de salida del reloj es 6 veces más lenta en comparación con la velocidad del cristal externo. Debido a esto, el maestro también se ejecuta 6 veces más lento. Agregué un montón de comandos nops (sin operación) en mi código para el esclavo.

En cuanto al hardware, el circuito está en una PCB y la pista que va hacia el reloj tiene aproximadamente 40 millas de ancho y las otras pistas tienen 12 millas de ancho. Sus longitudes son de menos de una pulgada y el espacio libre para todas las pistas es de al menos 12 millas.

Después de varias pruebas, la línea SSEL (también conocida como "selección de esclavos") baja cuando el maestro la establece baja, pero el esclavo no hace que la línea SPICLK (también conocida como "reloj SPI") sea alta. haciendo.

¿Qué estoy haciendo mal?

;Big micro (slave) code

SPICLK bit P3.6
DIN bit P2.5
DOUT bit P2.6
SSEL bit P2.7

org 0h
setb DIN
setb SSEL
clr SPICLK
debug:
    acall SPISS ;stall until remote does valid cmd
    jc debug ;carry = remote didn't set low yet
    jz debug ;zero = invalid command
    ;process code based on accumulator value
ret

;SPI slave routine
SPISS:
    setb SSEL ;Set high so master can set it low
    nop     ;wait 6 cycles because master is 6x slower
    nop
    nop
    nop
    nop
    nop
    jnb SSEL,nospiop ;if line isn't taken low
    setb C     ;then set carry
    ret        ;and return. This always happens which is a problem!
    nospiop:
    mov R7,#8h     ;Setup 8 bits
    s:
    setb SPICLK    ;tell other micro we are ready
    nop         ;let it catch up
    nop
    nop
    nop
    nop
    nop
    clr HWLED   ;turn our light on
    jb SPICLK,$ ;wait until master lowers clock line
    clr SPICLK  ;we keep it low to make master wait
    mov C,DIN   ;get bit
    setb HWLED  ;turn off light
    rrc A   ;shift into the byte
    mov DOUT,C  ;and take other bit as output
    djnz R7,s   ;continue for remaining 7 bits
    setb SPICLK ;tell micro we are ready again
    nop
    nop
    nop
    nop
    nop
    nop
    clr HWLED   ;turn on light
    jnb SSEL,$  ;wait until master turns slave select to high
    clr SPICLK  ;tell micro we are always busy
    setb DOUT   ;reset other values
    setb DIN
    setb HWLED
    clr C       ;C=0 for normal completion
ret








;Little master micro code


DOUT bit P1.1
DIN bit P1.2
SSEL bit P1.3
SPICLK bit P3.2

org 0h
mov A,#COMMAND ;Some value irrelevant to the problem
acall docpucmd
sjmp $

docpucmd:
    acall SPISM ;Send command out but we don't care what comes back
    clr A         ;Make command as zero..
    acall SPISM ;because now we want the result to the last command
    clr C
ret

;Master SPI routine
SPISM:
  setb SPICLK   ;Make clock line so slave can pull it low
  setb DIN  ;Make input high so slave can set it
  clr SSEL  ;Lower slave select to start transaction
  mov R7,#8h    ;8 bits to transfer
  m:
      nop       ;wait until remote RAISES clock line to indicate 
          ;slave is ready but slave likes to keep line low always
      jnb SPICLK,m
      mov C,DIN     ;Get bit
      rrc A ;Shift it in and shift old bit out
      mov DOUT,C    ;Send out old bit
      clr SPICLK    ;lower clock line to tell slave we have data
      nop       ;add small delay. this is executed on slow micro
      setb SPICLK   ;raise clock line
  djnz R7,m ;repeat for remaining bits
  jnb SPICLK,$  ;wait until remote is ready
  mov C,DIN     ;get official last bit
  rrc A     ;and make byte correct
  setb SSEL ;and reset lines
  setb DOUT
  setb DIN
ret

    
pregunta Mike

0 respuestas

Lea otras preguntas en las etiquetas