Autor Tema: Problema en comunicación RFID-RC522 por SPI en PIC18F452-C18  (Leído 4376 veces)

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

Desconectado Crengifo.e

  • PIC10
  • *
  • Mensajes: 3
Problema en comunicación RFID-RC522 por SPI en PIC18F452-C18
« en: 30 de Marzo de 2015, 04:32:04 »
Buen día a todos!! :)  :-/ :)

Escribo buscando solución a mi problema como última esperanza  :( , he buscado por todo el foro y casi media internet sobre el tema y no logro dar solución. Intento comunicar por SPI mi PIC18F452 con el módulo RFID RC522, he usado la librería SPI.h de c18 pero no tuve resultados ni al compilar, así que configuro yo mismo los registros y consulto el registro SSPBUF para leer y escribir al módulo desde el pic como Maestro.  :oops:  :D

He modificado una librería para controlar el módulo RC522, a partir de lo desarrollado en los siguientes links (códigos en MikroC, Arduino, ¿CSS?  :shock:).

Diseñado para Pic 18f4550: http://microcontrolandos.blogspot.mx/2014/02/pic-rfid-mfrc522.html
Diseñado para Pic 16f877 : http://simplesoftmx.blogspot.com/2014/11/libreria-para-usar-lector-rfid-rc522.html
Diseñado para Arduino     : https://github.com/JoyLabs/arduino/blob/master/libraries/RFID/MFRC522.h

A partir del datasheet del módulo no comprendo bien qué modo SPI(CKP,CPHA) usar. Sin embargo, de ahí solo entiendo que la señal NSS debe ser BAJA para poder envíar una serie de byts en un flujo de datos.
http://www.nxp.com/documents/data_sheet/MFRC522.pdf

Concretamente debo llamar las siguientes funciones en c18 para comunicar, pero no entiendo como llamarla a través de la libreria "lib_rc522.h", ya que esta se queda en un ciclo continuo sobre las funciones MFRC522_Wr y MFRC522_Rd.

- MFRC522::Init(); // Inicialización y activación de la antena
- MFRC522::Request(..); // Busca tarjetas en el campo
- MFRC522::Anticoll(...); // Lee el número de serie de la tarjeta


A continuación, fragmentos importantes del código que he desarrollado ( ADJUNTO, el archivo .zip del proyecto)


*RFID.C  - Archivo principal (Main)

Código: [Seleccionar]




#define MFRC522_CS  PORTBbits.RB6    //Pin 39 //SDA           
#define MFRC522_SCK PORTCbits.RC3  //Pin 18
#define MFRC522_SI  PORTCbits.RC4    //Pin 23
#define MFRC522_SO  PORTCbits.RC5   //Pin 24         
#define MFRC522_RST PORTDbits.RD6     //Pin 29

#include    "lcd.h"
#include "set_up.h"
#include "lib_rc522.h"
#include "RFID_SPI.h"

 char key[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
char writeData[] = "Microcontrolandos";

void main()
{

char msg[12];
char UID[6];
unsigned int TagType;
char size;
char i;

char dest;

set_up();

SPI_Init();

MFRC522_Init();

set_up();

lcd_init(); 

Texto_lcd("\f Inicio :\n    Inicio")
delay(1000);

   
   while (1)
   {     
     unsigned char status,str;
 // Find cards, return card type
 status = MFRC522_Request(PICC_REQIDL, str);
 if (status == MI_OK){
 
 Texto_lcd("\f Card detected :\n detected   ")

 }

if (MFRC522_isCard(&TagType))       {       
//         printf ("Ttp:%X ",TagType);                                 
         //Read ID
         
         Texto_lcd("\f Tarjeta Leida :\n TagType  ")
         delay(1000);
         
        if (MFRC522_ReadCardSerial (&UID))             
               
         
         {
        //    printf (":UID:");
            for (i = 0; i < 5; i++)
            {
         //   printf ("%X",UID[i]);
            }
       //     printf("\n");
         }                                       
         MFRC522_Halt () ;
      }
   }
 }

*RFID_SPI.h  -  Congifuración de registros SSPCON1 y SSPSTAT


Código: [Seleccionar]
  #ifndef _RFID_SPI_H
#define _RFID_SPI_H


unsigned void SPI_Init(void){
    //set tris bits for serial port pins
    TRISCbits.TRISC5 = 0; //output
    TRISCbits.TRISC4 = 1; //input
    TRISCbits.TRISC3 = 0; //output
    TRISBbits.TRISB6 = 0; //output
    TRISDbits.TRISD6 = 0;

    PIR1bits.SSPIF = 0; // Clear interrupt flag
    PIE1bits.SSPIE = 0; // Disable MSSP interrupt
    INTCONbits.PEIE = 0; // Disable perriferal interrupts


    SSPSTATbits.SMP = 0; //input sampled at middle of interval
    SSPSTATbits.CKE = 0; //Data transmitted from low to high clock

    //Enable SSP, Master mode, clock Fosc/4
    SSPCON1 |= 0b00100000;

} #endif



* Estas son las funciones que declaro para escribir y leer el contenido del registro SSPBUF, donde creo se guarda la información que envían tanto el Pic como el Módulo

Código: [Seleccionar]
 

unsigned char MFRC522_Rd(unsigned char Address) 
{
   
   unsigned char value;
   unsigned int i, ucAddr,temp;
   unsigned int ucResult = 0;
   MFRC522_SCK = 0;
   MFRC522_CS = 0;
   
   while( !SSPSTATbits.BF );
   
   SSPBUF = ((Address<<1)&0x7E)| 0x80;
   SSPBUF = 0x00;
   
   value = SSPBUF;

 
//   return SSPBUF;
   
   // SSPBUF = 0xFF; // send a dummy byte
   // temp = SSPBUF;
     
     
     
   MFRC522_CS  = 1;
   MFRC522_SCK = 1;
      return value;
}

void MFRC522_Wr(unsigned int Address, unsigned int value)
{
   
   unsigned int i, ucAddr,t,temp;
   MFRC522_SCK = 0;
   MFRC522_CS = 0;
   SSPBUF = ( (Address<<1)&0x7E);
   
   while( !SSPSTATbits.BF );// wait for the tramsit/recieve to finish
   SSPBUF = value;
   
                               // has to be SSPSTAT.BF not just BF!! (for some reason)
 
   
 

   MFRC522_CS = 1;
   MFRC522_SCK = 1;
}


« Última modificación: 31 de Marzo de 2015, 19:46:10 por Crengifo.e »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Problema en comunicación RFID-RC522 por SPI en PIC18F452-C18
« Respuesta #1 en: 30 de Marzo de 2015, 05:23:43 »
Uf... jodido jodido, todos los ejemplos que mostraste son hechos con SPI a mano ( soft ).

Y lo unico que deberias de tocar y cambiar es la funcion de escribir un byte por hw en ves de software.
En el .zip que pasaste hay muchisimos archivos. hay como 3/4 todos sobre el RC522

Normalmente lo que yo hago es tener un .c con todas las funciones y un .h con los prototipos, alli cargo solo 1 solo .h por libreria.

Citar
Sin embargo, de ahí solo entiendo que la señal NSS debe ser BAJA para poder envíar una serie de byts en un flujo de datos.
NSS parece ser como CS chip select. Y cada "transaccion" sea escribir o leer deberian estar separadas por un pulso alto en el NSS

Citar
A partir del datasheet del módulo no comprendo bien qué modo SPI(CKP,CPHA)
Parece ser:
CKP = 0 , CKE = 1 y SMP = 1

Es decir primero cambia el bit de datos y luego por flanco positivo es validado ese dato
Fijate en ambos datasheet los diagramas de tiempo

Claramente el problema esta en el SPI, los tiempos parecen estar. Ya que RC522 exigue el reloj maximo de 50ns+50ns = 100ns -> 10Mhz
Y teniendo un cristal+PLL al maximo que es 40Mhz  si lo dividis por 4 estas en el maximo.
Primero proba con una velocidad mas lenta. y luego a renegar con esas funciones, podrias probar hacer una funcion simple y ver si realmente te responde como debe el SPI y no tratar de hacer funcionar toda la libreria de golpe.

Tal ves al no recibir todos los bits no activa el bit BF...
« Última modificación: 30 de Marzo de 2015, 05:49:57 por KILLERJC »

Desconectado Crengifo.e

  • PIC10
  • *
  • Mensajes: 3
.
« Respuesta #2 en: 31 de Marzo de 2015, 19:28:27 »
.
« Última modificación: 31 de Marzo de 2015, 19:44:35 por Crengifo.e »

Desconectado Crengifo.e

  • PIC10
  • *
  • Mensajes: 3
Re: Problema en comunicación RFID-RC522 por SPI en PIC18F452-C18
« Respuesta #3 en: 31 de Marzo de 2015, 19:42:22 »
Buena tarde.

Aún sigo algo bloqueado. Ahora estoy usando la librería SPI.h para controlar lectura y escritura de la siguiente forma...

Código: [Seleccionar]
  unsigned char MFRC522_Rd(unsigned char Address) 
{
char value;
MFRC522_CS = 0;
WriteSPI( (( Address << 1 ) & 0x7E) | 0x80 );
value = ReadSPI();
MFRC522_CS = 1;

return value;

}

void MFRC522_Wr(unsigned char Address, unsigned char value)
{
   
 MFRC522_CS = 0;
 WriteSPI( ( Address << 1 ) & 0x7E );
 WriteSPI( value );
 MFRC522_CS = 1;
 
}

Inicializando la comunicación desde el archivo .c con los siguientes líneas, donde más abajo llamo la función que quiero me de respuesta de alguna tarjeta en el main...

Código: [Seleccionar]


main (){

CloseSPI();
OpenSPI(SPI_FOSC_4, MODE_01, SMPMID);

MFRC522_Init();


   while (1)
   {      
  unsigned char status,str;
 // Find cards, return card type
 status = MFRC522_Request(PICC_REQIDL, str);
 if (status == MI_OK){
 
 Texto_lcd("\f Card detected :\n detected   ") }

 if (MFRC522_isCard(&TagType))       {      
//         printf ("Ttp:%X ",TagType);                                
         //Read ID
        
         Texto_lcd("\f Tarjeta Leida :\n TagType  ")
         delay(1000);

}
}

}


El problema sigue en que no recibo respuesta aparente del módulo RC522. Simulando en ISIS Proteus encuentro las siguientes señales en SDO, SCK y CS..



Aclaro que tanto el Pic, como el módulo RC522 están alimentados a 3.3V y la configuración de pines es la siguiente:

PIC18F452               (CS)        RB6   _______________________ SS      RC522         
 *            (SDO)       RC5 _______________________ MISO
 *                            RB4   _______________________ RST      
 *            (SCK)        RC3   _______________________ SCK
 *            (SDI)   RC4   _______________________ MOSI   


He buscado información sobre SPI por HW en c18 pero no encuentro información clara. Adjunto el .zip del proyecto con los archivos actualizados.

Desconectado AG1

  • PIC16
  • ***
  • Mensajes: 105
Re: Problema en comunicación RFID-RC522 por SPI en PIC18F452-C18
« Respuesta #4 en: 26 de Abril de 2015, 11:39:33 »
Puedes implementar tus propias funciones SPI. Aquí te dejo un ejemplo para CCS:


void spi_write_byte(unsigned char tosend)
{
unsigned char i;
for(i=0;i<8;i++)
{
if (tosend & 0x80)
{
output_high(SPI_SI);
}
else
{
output_low(SPI_SI);
}
output_low(SPI_SCK);
output_high(SPI_SCK);
tosend <<= 1;
}
}
.....
.....
.....
Llamando a  spi_write_byte ....
{
unsigned Addr;
unsigned char Address;
unsigned char value;
.....
.....
.....
output_low(SPI_NSS);
ucAddr = ((Address<<1) & 0x7E);
spiwrite(Addr);
spiwrite(value);
output_high(SPI_NSS);
}

Salu2.