# Comunicacion SPI en PIC



## ingsevilla (Jul 6, 2010)

Hola a todos,

Me encuentro realizando un proyecto de electronica, campo del que inicialmente no disponia de mucho conocimiento.
Me han dado una placa, que consta de un PIC 18F2680, un adaptador RS-232 (MAX323) y los componentes electronicos tipicos de cualquier circuito digital.

Para empezar, elegi para programar el compilador CCS version 4.104, y Proteus 7.6 para hacer ejercios de simulacion. Tambien dispongo de todo lo necesario para programar el PIC.

Tras unos dias de recopilacion y lectura de documentacion referente a la programacion de PIC's, pasamos a implementar pequeñas programitas para jugar con unos led's que conectamos a salidas del PIC. Posteriormente, tratamos con interrupciones del temporizador y del puerto RS-232.

A continuacion, queremos empezar a hacer cosas un poco mas complejas. El siguiente objetivo que nos hemos propuesto es realizar algun programa en el que probar la comunicacion mediante SPI, pero la verdad que estamos bastante perdidos con esto.

¿Alguien podria orientarme un poco sobre este tipo de comunicacion? Algun programa sencillo para probarlo, o algo para tener una idea de como funciona.

He leido que para que se produzca la comunicacion SPI es necesario un dispositivo maestro, y otro esclavo, por lo tanto, ¿es necesario programar un codigo para el maestro y otro para el esclavo?

Agradeceria mucho vuestras respuestas, por que me encuentro en una situacion en la que no se como avanzar.

Gracias de antemano, y un saludo


----------



## ricber (Jul 6, 2010)

Hola, en la ayuda del CCS, en la seccion SPI, te da un programa (ex_spi.c), que es un ejemplo de como leer y escribir una memoria SPI.


----------



## ingsevilla (Jul 7, 2010)

Vale, he leido el ejemplo y lo entiendo mas o menos bien.
Quiero comunicar mi pic con mi PC, siendo el primero slave y el PC master.
¿Como realizo la conexion entre PC-pic? ¿A traves del conector rs-232? ¿Como puedo monitorizar los datos que voy enviando/recibiendo?

Perdone si mis dudas son demasiado principiantes, pero me estoy iniciando en el tema.

Un saludo


----------



## ricber (Jul 7, 2010)

Si quieres comunicar el pic con la PC, no debes usar el SPI, tienes que usar la puerta rs232, y no es necesario que alguien sea esclavo y maestro.


----------



## ingsevilla (Jul 7, 2010)

Entonces la comunicación SPI, sólo es entre PIC's?


----------



## ricber (Jul 7, 2010)

No solo entre pic, puede ser con  memorias, conversores A/D, acelerometros, relojes, display, etc.


----------



## fernandomt84 (Ago 25, 2010)

si, algunos A/D vienen con comunicacion paralela y otros con SPI, 

estaba tratando de probar la comnicacion SPI tambien, especificamente entre el pic 18f2550 y el ADS7884 un A/D de 10bits 3Msps, 

quisiera saber si tienen algun ejemplo en C para ver como leer desde el pic, para posteriormente enviar el resultado a la PC a traves del puerto usb, 

saludos!


----------



## f7peralta (Nov 5, 2011)

Hola, aquí hay un ejemplo de comunicación SPI en 2 pics 16f877a. El Maestro transfiere 6 bytes al esclavo, y el esclavo responde con 0x01 por cada byte recibido. El compilador utilizado es el PICC y la simulación está hecha en proteus. Les adjunto imágenes de proteus.

*Código del Maestro:*

```
#include <SPI_Master.h>

#byte SPIBUF=0x13

BYTE ADDR=0xFF;

#int_EXT
void  EXT_isr(void) 
{
   BYTE rx;
   BYTE tiempo=50;
   
   output_bit(PIN_C2, 0);    //Habilita SS

   //BYTE 0
   spi_write(0xF0);   //dato enviado
   while(!spi_data_is_in()); 
   rx=SPIBUF;      //dato recibido

   delay_us(tiempo);

   //BYTE 1
   spi_write(0xF1);   //dato enviado
   while(!spi_data_is_in()); 
   rx=SPIBUF;      //dato recibido

   delay_us(tiempo);

   //BYTE 2
   spi_write(0xF2);   //dato enviado
   while(!spi_data_is_in()); 
   rx=SPIBUF;      //dato recibido

   delay_us(tiempo);

   //BYTE 3
   spi_write(0xF3);   //dato enviado
   while(!spi_data_is_in()); 
   rx=SPIBUF;      //dato recibido

   delay_us(tiempo);

   //BYTE 4
   spi_write(0xF4);   //dato enviado
   while(!spi_data_is_in()); 
   rx=SPIBUF;      //dato recibido

   delay_us(tiempo);

   //BYTE 5   
   spi_write(0xF5);   //dato enviado
   while(!spi_data_is_in()); 
   rx=SPIBUF;      //dato recibido

   output_bit(PIN_C2, 1);    //Deshabilita SS
}

void main()
{

   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);

   setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_4|SPI_SAMPLE_AT_END);
   
   output_bit(PIN_C2, 0);
   output_bit(PIN_C2, 1);
          
   while(true);
}
```
*Código del Esclavo:*

```
#include <SPI_Slave.h>

#byte SPIBUF=0x13

BYTE BUFFER_SIZE=7;
BYTE i=0;
BYTE BUFFER[6];


#int_SSP
void  SSP_isr(void) 
{   

   for(i=0;i<BUFFER_SIZE;i++) {
      while(!spi_data_is_in());
      BUFFER[i]=SPIBUF; //Read from the Master
      SPIBUF=0x01;      //Write to the Master
      i=i+1;
   }

}

void main()
{
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_SSP);
   setup_spi(SPI_SLAVE|SPI_L_TO_H|SPI_CLK_DIV_4|SPI_SAMPLE_AT_END);

   SPIBUF=0x01;   
   
   while(true);
   
}
```


----------



## josb86 (Oct 28, 2013)

Buenas noches agradecería su ayuda con una consulta estoy utilizando un modulo RFID RC522 segun la hoja de datos del chip del lector este trabaja en modo SPI Slave, puden verlo aqui en la pagina 10 (http://www.nxp.com/documents/data_sheet/MFRC522.pdf) 

para configurar el pic estoy utilizando lo siguiente:

#use SPI( MASTER, DO = PIN_C4,DI = PIN_C5, CLK = PIN_C3, baud = 100000, BITS = 8, LSB_FIRST, SAMPLE_RISE, stream = RFID )

pero creo que no esta funcionando por que en el pin c3 no hay señal, creo que debería haber algo no, como una onda cuadrada?


----------



## AG-1 (Nov 14, 2013)

Efectivamente, el módulo MFRC522 esta configurado para trabajar en modo SPI. 

En el pin CLK no obtendras ninguna variación hasta que no actues sobre él con instrucciones como por ejemplo: 
   output_high(CLK); // pin C3 alto

   output_low(CLK); // pin C3 bajo

Salu2.




josb86 dijo:


> Buenas noches agradecería su ayuda con una consulta estoy utilizando un modulo RFID RC522 segun la hoja de datos del chip del lector este trabaja en modo SPI Slave, puden verlo aqui en la pagina 10 (http://www.nxp.com/documents/data_sheet/MFRC522.pdf)
> 
> para configurar el pic estoy utilizando lo siguiente:
> 
> ...


----------



## ilcapo (Sep 25, 2015)

hola amigos ! 
les comento que estoy haciendo mi primer programa para probar la comunicacion SPI entre 2 pics 16f886, pero el problema que tengo es que el LCD del Esclavo no me muestra el valor recibido, siempre muestra un 0 sea cual sea el valor enviado 
Les dejo adjunto el programa para el maestro, el esclavo y la simulacion en Proteus8 para que jueguen un poco con el programa y si pueden ayudarme a encontrar en que estoy metiendo la pata ! 

desde ya gracias ! saludos !

PD: si no tienen el Proteus 8 les puedo hacer la simulacion en el 7.2sp


----------



## D@rkbytes (Sep 26, 2015)

Si no generas un bucle correctamente para recibir los datos o alguna interrupción,  nunca vas a recibir nada.

Y si únicamente envías un dato al iniciar, tendrían que estar muy sincronizados los PIC al iniciarse para que se pudiera lograr la comunicación. Cosa que es muy difícil que suceda, y menos usando retardos.

Adjunto los programas modificados y compilados, pero sin archivos de proyecto porque usas una versión muy anterior a la que tengo.

Suerte.


----------



## Scooter (Sep 26, 2015)

Spi es síncrono. Va sin más si están activadas y atendidas las interrupciones.
 Cuando el receptor recibe el nivel por SS ya sabe que está entrando dato por spi, cuando entran 8 bits salta la interrupción.


----------



## ilcapo (Sep 26, 2015)

D@rkbytes sos mi idolo lo dejo a messi en el segundo puesto jaja! funciona genial  ! 

ahora voy a intentar hacer que el esclavo le mande al maestro y le coloco un LCD al maestro 

una ayudita para mi porque no me tengo mucha fe,,,, el esclavo le manda en cualquier momento o tengo que esperar que llegue el dato del maestro antes ?


Scooter: luego voy a intentar hacerlo con interrupciones por ahora pretendo hacerlo desde los mas simple asi y complicarlo paso a paso asi le sirve a alquien mas, como una especie de tutorial SPI


----------



## D@rkbytes (Sep 26, 2015)

El esclavo también puede mandar datos en cualquier momento, pero también se puede hacer a petición del maestro.
Eso lo defines tú, no es una regla ni norma obligada.


----------



## ilcapo (Sep 26, 2015)

hola amigos como han estado ! 
bueno aca sigo con esta especie de tutorial SPI desde -1  porque desde cero ya seria muy avanzado para mi 

no me tenian fe y yo menos pero pude hacer que el esclavo le devuelva el mismo valor que le entregó el maestro, no me pregunten cuanto tiempo estuve para poder hacer esto porque no quiero arruinar mi poca reputacion en el foro 

pero no todo es color de rosas y fiesta! porque tiene un pequeño error: 
al comenzar,en el Display del Master sale un numero 105, como si el buffer del SPI tuviera ese valor cargado? habrá que limpiar el buffer al comienzo ? 

otra cosa rara es que en el Debugger del SPI del Proteus se ven bien los valores 1 ,2 ,3 ...etc que entrega el master al esclavo,,, pero los valores del esclavo al master no son 1, 2, 3 .....etc ? porque si en los  Displays se ven bien ? 

les envio el programa del master, del slave y la simulacion en archivo adjunto 

NOTA: en los programas yo tengo que colocar esta linea #define use_portb_lcd TRUE porque en algun momento modifique la libreria original del CCS   
creo que ustedes tendrian que comentar esa linea en el programa y descomentarla en la libreria para que puedan usarla en el PORTB del pic


----------

