Autor Tema: Comunicación entre 2 pic por SPI  (Leído 643 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado kapotik

  • PIC16
  • ***
  • Mensajes: 118
Comunicación entre 2 pic por SPI
« en: 12 de Diciembre de 2016, 11:47:47 »
Hola, intento aprender a comunicar 2 16F877a atraves de SPI por harware, pero antes de introducirme en el código me surge una duda, y es si se puede enviar caracteres o palabras como en una comunicación serial RS232, por ejemplo:

Código: [Seleccionar]
movlw 'H'
call enviaRS232
movlw 'O'
call enviaRS232
movlw 'L'
call enviaRS232
movlw 'A'
call enviaRS232

en una comunicacion SPI tambien se pueden enviar palabras?

Saludos

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 6050
Re:Comunicación entre 2 pic por SPI
« Respuesta #1 en: 12 de Diciembre de 2016, 12:49:37 »
Si podes. De la misma forma que en la UART. Al menos lo que es el envio unidireccional.


En caso de querer hacer algo bi-direccional:

La diferencia la tenes en como lees lo del otro PIC. En la UART tenes un pin de transmision y uno de recepcion, mientras que en el SPI lo que llaman MISO y MOSI  ( Master-input Slave-Output ; Master-Ouput Slave Input ) O como otros fabricanes lo suelen llamar SDI, SDO respectivamente ( Serial Data Input ;Serial data Output)

La UART queda claro como es que envia y recibe, envia por el TX y recibe por el RX. Pero la UART es serial pero Asincrona, no necesita una señal de reloj, Ya que la misma señal sirve para reloj tambien. Entonces el otro aparato puede enviar cuando le guste.

Pero el SPI es serial, pero Sincrono, es decir va a tener una señal de reloj, tambien vas a tener un maestro y uno o varios esclavos, solo puede haber comunicacion 1 a 1 bidireccionalmente y para esto se usan los CS ( chip Select).
Como dije antes la UART es claro, simplemente cuando le quieren enviar algo se lo envian por el pin RX. En el SPI el que maneja el reloj es el maestro y nadie mas. Como los datos se toman en los flancos de la señal de reloj, el esclavo no puede enviar cuando se le plazca un dato. Ya que el maestro tiene el poder del reloj,

Entonces el maestro debe enviar pulsos de reloj y asi de esa forma el esclavo puede responder. Suponete que es como un circuito cerrado y tenes 2 shift register. La salida de un shift register va a la entrada del otro, asi para ambos. Como una imagen vale mas que mil palabras:



Suponente que el esclavo cargas el valor 0x42, y en el maestro cargas el valor 0x56, al cargarlo empieza a enviarlo, cuando se envia es decir se dan los 8 pulsos de reloj en SCK, el 0x56 del maestro pasa al esclavo y el 0x42 del esclavo pasa al maestro.

Algunos dspositivos con interfaz SPI, exigen que se les envie un comando, y luego los proximo 16 bits por ejemplo son omitidos por el dispositivo y solo entregan el resultado. O podes hacer que a medida que le entregue datos el otro dispositivo deje tambien datos para enviar. Lo que si vas a necesitar saber cuantos datos son o tener un valor de finalizacion, asi el maestro para de enviar señales de clock.
En si pedirle datos al esclavo seria como escribir 0x00 en el maestro, lo cual seria enviar pulsos de reloj nomas. O un valor que omita el receptor.

Desconectado kapotik

  • PIC16
  • ***
  • Mensajes: 118
Re:Comunicación entre 2 pic por SPI
« Respuesta #2 en: 12 de Diciembre de 2016, 13:29:51 »
gracias por tu respuesta a sido muy clara, ahora se puede tener 1 maestro con varios esclavos y que estos reciban los datos al mismo tiempo?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 6050
Re:Comunicación entre 2 pic por SPI
« Respuesta #3 en: 12 de Diciembre de 2016, 14:29:02 »
Si es posible.

Te propongo 2 situaciones:

1era:
Podes tener 1 maestro ( usando el pin SDO nomas para la salida ) y lo llevas a todos los esclavos ( usando el pin SDI nomas para la entrada de cada uno)

Es decir que no exista un "retorno". Normalmente no poseen un pin como CS, pero creo que se puede habilitar, este seria el caso de que quisieras enviar a uno si y otro no.

Esta solucion es simple, y la mayor limitante es si el pin de salida puede manejar la capacidad/carga de los demas pines de entrada (solucionable con un buffer). Lo bueno es que si hay uno que falta no hay problema.

Si quisieras enviar un valor especifico a cada esclavo quedan 2 formas. Usar el CS, o crear una especie de protocolo que tengan una direccion cada uno. Pero ya para esto creo que prefiero usar I2C.

2da:

Crear una cadena.. Maestro SDO -> Esclavo1 SDI ; Esclavo1 SDO -> Esclavo2 SDI ; Esclavo2 SDO -> ..... ( Aca EsclavoN SDI o Maestro SDI, o simplemente dejarlo libre )

De esa forma si por ejemplo queres enviar 0x40 al primero y 0x30 al segundo. Podes enviar el valor: 0x30 y luego 0x40

Los esclavos deberian saber que cada 2 valores es el que deben tomar. Y eso te permite enviar a cada uno un dato distinto sin necesidad de usar otro pin como CS.

El problema es obvio. falta o falla un esclavo y todos los demas quedan sin comunicacion. Lo bueno es que usas solo 2 hilos y que permite una comunicacion bi-direccional Si es que al final se conecta al SDI del maestro.
« Última modificación: 12 de Diciembre de 2016, 14:31:28 por KILLERJC »

Desconectado kapotik

  • PIC16
  • ***
  • Mensajes: 118
Re:Comunicación entre 2 pic por SPI
« Respuesta #4 en: 12 de Diciembre de 2016, 14:38:23 »
gracias killer muy presisa tu explicacion,si bien a modo de aprender voy a probar con las dos, al final me quedare con la segunda opcion.
Ahora me voy a poner con el codigo....y seguro que buelvo a molestar con mas dudas.. :D :D :D :D :D

Desconectado kapotik

  • PIC16
  • ***
  • Mensajes: 118
Re:Comunicación entre 2 pic por SPI
« Respuesta #5 en: 16 de Diciembre de 2016, 19:33:00 »
Si quisiera controlar por spi un 74hc545 y quisiera hacer un juego de luces en el cual por ejemplo quisiera tener un led parpadeando y el resto ir prendiendo y apagando a diferentes tiempos que el que parpadea como se hace.
Ya tengo claro como como comunicarme con el, cargo el dato por ej 00000001 y luego le doy al clok y despues al lacht, quedandome un led encendido y el resto apagado, pero no entiendo como se hace para que quede parpadeando.
Saludos

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 6050
Re:Comunicación entre 2 pic por SPI
« Respuesta #6 en: 16 de Diciembre de 2016, 20:08:29 »
Creo que quisiste poner 74HC595 que es un shift register.

Para comunicarte con el 74HC595 usaria SPI + un pin extra.

SDO del PIC ---> DS 74HC545
SCLK del PIC ---> SHCP 74HC545
Pin del PIC ---> Latch 74HC545

Entonces lo que haces es enviar el dato ( que es de 8 bits ) por SPI, y luego cuando termina, darle un pulso al latch.

Si quisieras hacer el efecto de intermitencia en un led.. seria algo asi:

Código: [Seleccionar]
enviar 0000 0001 por SPI
latchear
esperar 250ms
enviar 0000 0000 por SPI
latchear
esperar 250ms

Comenzar de nuevo

El 74HC549 por si solo no va a hacer que quede "parpadeando", es tu deber hacerlo.

Se podria hacer tambien sin SPI, esto te permite algunas combinaciones de forma mas facil pero lo que ganas sin usar el SPI, lo perdes en la complejidad ya que tenes que realizarlo a mano.
Muchos hace un SPI por software. En el que una salida oficia de datos, otra de clock y otra de latch. Y los datos tenes que ir poniendolos bit a bit en el shift-register.

Lo bueno de este metodo es poder tener un SPI de ancho variable y que no sea multiplo de 8. Aunque hay integrados que permiten cambiar la cantidad de bits.
La otra es que podes ir cargando 1 bits solo. Imaginate el caso en que tengas en el shiftregister es 1010 1010, y queres hacer que quede 0101 0101

Con el SPI, deberias enviar 0101 0101, lo cual tarda el tiempo necesario que es enviar los 8 bits.
Con el SPI por software, simplemente pones un 0 en la salida de datos, das un pulso de clock, y un pulso de latch. Ya que puedo enviar 1 bit de esta forma.

Ahora si necesitas cambiar los 8 de una forma significativa, el SPI por hardware siempre gana.

Desconectado kapotik

  • PIC16
  • ***
  • Mensajes: 118
Re:Comunicación entre 2 pic por SPI
« Respuesta #7 en: 16 de Diciembre de 2016, 21:15:08 »
Para el caso del parpadeo entiendo que el 74HC595 hay que hacerlo manual, pero no logro entender como hacerlo desde el assembler, por que para un solo led tu ejemplo va bien pero he visto algunos proyectos que controlan 128 led a la vez, y si para que parpadee hay que prender y apagar me resultaria muy dificil recordar cual tiene que parpadear cual deberia estar prendido, y volviendo al tema de que para que parpadee 1 tengo que enviar todo el dato nuevamente, lo veo engorroso, pero como dije he visto de hasta 128 led incluso parpadeando a distintos tiempos.
Me imagino que para hacerlo debe de haber un metodo, no se por hay tipo tabla o algo, y ese metodo es el que quisiera saber como hacerlo.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 6050
Re:Comunicación entre 2 pic por SPI
« Respuesta #8 en: 17 de Diciembre de 2016, 04:18:41 »
Te entendi mal entonces...
Pense que querias hacer parpadear a cada led en un tiempo distinto. O si queres modificar 1 solo led nomas. Vas a tener que hacer si o si lo que dije antes, no es engorroso para nada.
Respecto a los 128 leds, se mantiene 128 bits o 16 bytes con la info enviada dentro del micro, se modifica esto y luego se envia en intervalos regulares. Mas que seguro que lo vas a manejar con acceso indirecto al acceso de esta memoria.

Si lo que queres hacer es hacer parpadear a TODOS aquellos encendidos, vas a necesitar otro pin y conectarlo al Output Enable. Cuando lo pones en alta impedancia ( un 1 en OE ) estarian apagados. Y cuando le pones un 0 en OE aquellos que estan encendidos o tienen un 1 van a encender y los que tenian un 0 quedaran apagados.
La ventaja es que al enviar una unica ves el dato la podes hacer parpadear, y la desventaja es que todos los leds al mismo ritmo.


----------

Citar
y volviendo al tema de que para que parpadee 1 tengo que enviar todo el dato nuevamente, lo veo engorroso, pero como dije he visto de hasta 128 led incluso parpadeando a distintos tiempos. Me imagino que para hacerlo debe de haber un metodo, no se por hay tipo tabla o algo, y ese metodo es el que quisiera saber como hacerlo.

Como dije antes, si queres hacer parpadear solo 1 de esos 128, usando un 74hc595 vas a tener que enviar todo nuevamente.
En tu memoria vas a reservar 16bytes o tal ves 32 bytes, los cuales van a servirte para tener los datos enviados. Sobre esos 16 bytes vas a aplicar cualquier "efecto" que quieras y luego vas a llamar una rutina que envie todos.

El envio es muy simple la rutina seria:
Con acceso indirecto apuntas al primer valor. Envias por SPI, aumentas tu registro de acceso indirecto FSR, envias, asi hasta enviar 16 veces. Pulso de latch, fin. Como mucho seran 20/25 lineas de codigo hacer esto

Modificas los 16bytes como te gusten, le aplicas lo que quieras y llamas a la rutina anterior.
« Última modificación: 17 de Diciembre de 2016, 04:23:30 por KILLERJC »