Estoy tratando de encontrar el mejor enfoque para transferir datos de alta velocidad de una manera entre dos microcontroladores (con sus propios cristales de la misma velocidad) de la misma variedad (entre AT89C4051 y AT89S52) desde un punto de vista eléctrico.
Los tengo cableados de la siguiente manera:
AT89S52 P0 is connected to AT89C4051 P1
AT89S52 P1.1 is connected to AT89C4051 P3.7
El AT89C4051 tiene 6 bytes de datos que necesita el AT89S52, y el AT89S52 siempre inicia la descarga.
Mis opciones son las siguientes:
** OPCIÓN 1. Transferir todo el byte. **
El código en AT89C4051 (transmisor) será este:
mov R1,#DATALOCATION
jb P3.7,$ ;Wait for falling edge
mov P1,@R1 ;send out byte
inc R1 ;Increment pointer
jnb P3.7,$ ;Wait for rising edge
mov P1,@R1
inc R1
;and this code (minus first line) repeats twice for remaining bytes
Y el AT89S52 tendrá este código:
mov R0,#DATASPACE
mov P0,#0FFh ;Make ports accept data
clr P1.1 ;lower line to get first byte
mov @R0,P1 ;Load next byte in
inc R0 ;increment pointer
nop ;waste cycles to let AT89C4051
nop ;be ready for next byte. Is this wait time enough under worst
;case scenarios???
setb P1.1 ;raise line to get next byte
mov @R0,P1 ;Load next byte in
inc R0 ;increment pointer
nop ;waste cycles to let AT89C4051
nop ;be ready for next byte
;and this code (minus first line) repeats twice for remaining bytes
Ese es mi enfoque de 8 bits que parece rápido, pero no tenía suficientes pines libres para usar uno para un pin de reconocimiento ya que el resto se usa.
** OPCIÓN 2. Transferir todo el nibble **
El código en AT89C4051 (transmisor) será este:
mov R1,#DATALOCATION ;pointer = start of data
jb P3.7,$ ;Wait for falling edge (but this means stalls which I don't like)
mov A,@R1 ;get byte
orl A,#0F0h ;and accept lower nibble.
clr ACC.7 ;Make P1.7 our ack bit (ack=0)
mov P1,A ;return data in lower nibble with P1.7=0 as ack
jnb P3.7,$ ;Wait for rising edge
mov A,@R1 ;get byte
orl A,#0Fh ;and accept high nibble. (ack=1)
swap A ;and put it in our low nibble slot
mov P1,A ;return data in lower nibble with P1.7=1 as ack
inc R1
;and this code (minus first line) repeats 5x for remaining bytes
El código en AT89S52 (receptor) será así:
mov R0,#DATALOCATION ;pointer = start of data
mov A,@R0 ;Load byte
orl A,#0F0h ;set our nibble and make rest of lines high to receive ack
mov P1,A ;and show it
clr P1.1 ;lower clock
jb P1.7,$ ;wait till remote is ready
mov A,@R0 ;Load byte again
orl A,#0Fh ;set our nibble and make rest of lines high to receive ack
swap A ;swap nibbles so we get right nibble
mov P1,A ;show data
setb P1.1 ;raise clock
jnb P1.7,$ ;wait till remote is ready
inc R0
;and this code (minus first line) repeats 5x for remaining bytes
¿cuál es el mejor?
Pero la parte que me preocupa es el tiempo y el hardware.
Los micros están conectados a no más de 10 cm de distancia entre sí y todas las trazas de PCB tienen 12 milésimas de pulgada de ancho con 12 milésimas de espacio libre. Cuando ejecuto cualquier circuito de microcontrolador, si mi mano toca ambos cables del cristal, entonces la velocidad de operación parece variar (¿probablemente porque la resistencia humana afecta la frecuencia del cristal?)
Teniendo en cuenta todos los entornos a los que pueden estar expuestos los micros (excepto el agua), ¿cuál de mis dos ideas es la mejor para asegurarme de obtener datos a la mayor velocidad posible? y solo tengo 9 líneas de E/S para jugar aquí.
Entonces, ¿recurro al método nibble y espero los reconocimientos incluso si la respuesta tarda un tiempo? ¿O estoy seguro de usar el método de byte?
Recuerde, tenemos que asumir los peores escenarios. dedos tocando el área de cristal (como prueba), baterías débiles, etc. porque lo último que quiero que suceda es la pérdida de datos.
Para aclarar, cada cable de cristal está conectado a capacitores cerámicos de 33pF que también están conectados a tierra. (Estoy usando la configuración de cristal del microcontrolador estándar). y mis planos de tierra son grandes.
ACTUALIZAR
Como se solicitó, incluí las conexiones importantes. Ambos cristales son 22.1184Mhz. El condensador y la resistencia conectados al pin de reinicio son 47nF y 100K. Todos los demás condensadores son 33pF.
También incluí un diagrama de tiempo básico. Tuve que usar pintura para dibujar las líneas porque no tengo ningún programa en mi computadora para hacer diagramas profesionales.
En primer lugar, debe colocar su proyecto en un recinto que evite que los dedos humanos (o cualquier otra cosa) se acerquen tanto al cristal que tenga un efecto importante en la frecuencia.
Una vez que tenga los relojes bajo control, el primer método debería estar bien, suponiendo que haya tenido en cuenta los retrasos en el peor de los casos a través de los sincronizadores de E/S en ambos chips. Tenga en cuenta que aunque los dos procesadores tienen la misma frecuencia nominal, sus frecuencias reales variarán ligeramente y la relación de fase entre ellos puede ser cualquier cosa.
Probablemente necesitará algunas nop
instrucciones más en el lado maestro (el que genera el reloj). Además, esas nop
instrucciones deben ir antes de la instrucción que lee los datos; esto le da al procesador esclavo el tiempo que necesita para reconocer la transición del reloj y colocar los datos en el bus de 8 bits.
nop
s de la documentación de una sola vez.Bien, veamos si lo entendí bien. ¿Está tratando de lograr una transferencia de datos de alta velocidad y está golpeando bits? Además, literalmente está contando los tics de la CPU para cada operación, lo que significa que su MCU se ejecuta al 100% de carga continuamente.
Aquí sólo hay dos resultados posibles. O se queda sin RAM para los datos entrantes, o tiene que detenerse en algún lugar y procesarlos. Asumiré que es lo último, y el procesamiento lleva mucho más tiempo que la comunicación. Digamos al menos 5 veces más.
Ahora, lo divertido de las tasas de baudios es que el volumen de datos transferidos a 1 Mbps 1/6 del tiempo es exactamente el mismo que el volumen transferido a 170 kbps de forma continua. Parece entender esto, como en su comentario "línea serie a 56 kbps con un 8N1 típico".
Además, mediante el uso de comunicación de hardware, puede realizar la transferencia y el procesamiento de datos simultáneamente. Entonces, ¿por qué no usa hardware UART disponible en ambos MCU y perfectamente capaz de velocidades más altas que las que cita?
Ahora, en caso de que necesite esos UART para algún otro uso, eche un vistazo a la nota de aplicación 3524 de Microchip. Es una implementación de SPI que se supone que debe lograr una transmisión de 2 Mbps (a un reloj de 32 Mhz).
Otra opción que podría considerar es copiar la forma en que PonyLink hace su señalización de bajo nivel.
Este es un enlace en serie entre FPGA, pero puede implementarlo golpeando un microcontrolador. Funciona de una manera inteligente e inusual:
Teniendo en cuenta la tolerancia de los dos cristales de MCU, ¿cuál es el pulso más corto que el emisor puede generar que el receptor pueda detectar? Llamaremos a esto un bit. Si es un pulso alto, entonces diremos que es un solo bit 1, y si fue un pulso bajo, entonces diremos que fue un solo bit 0.
Ahora, ¿cuál es el siguiente pulso más largo que se garantiza que el receptor detectará como más largo que el pulso más corto? Consideraremos que esto son dos bits. Nuevamente, si es un pulso alto, entonces considérelo como dos bits 1 (11), y si fue un pulso bajo, entonces considérelo como dos bits 0 (00).
Y así procedemos. Pulsos cada vez más largos utilizados para representar cadenas de bits más largas.
PonyLink también utiliza la codificación 10b8b . De esta manera puede garantizar que nunca haya una cadena de más de 5 bits del mismo valor, por lo que el receptor puede ver con frecuencia un borde para resincronizar.
No necesita implementar toda la complejidad del protocolo PonyLink completo, pero la señalización de bajo nivel que describí es muy interesante y podría ayudarlo aquí. Lea la sección "Señalización de bajo nivel" del documento protocol.txt .
Incluso hay un script de Python que puedes usar. Dígale las dos velocidades de reloj y su tolerancia, y calculará las longitudes de pulso que necesita para que esto funcione.
BeB00
eliot alderson
mike-ya no esta aqui
mike-ya no esta aqui
rdtsc
mike-ya no esta aqui
broma
Arce
mike-ya no esta aqui