Autor Tema: Problema al mandar datos mediante spi  (Leído 3783 veces)

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

Desconectado drakont

  • PIC10
  • *
  • Mensajes: 8
Problema al mandar datos mediante spi
« en: 19 de Abril de 2011, 19:09:29 »
Hola buena, estoy intentando comunicarme por spi con una tarjeta SD, utilizo un pic 18f25j50  y para programar en c el compilador C18, un cristal de 20MHz. Mi problema es el siguiente configuro el modulo spi2 ( utilizando los pines reconfigurables) , e intento enviar un byte, coloco el osciloscopio en el rejoj y en el pin de salida de mi pic y observo que en el osciloscopio tengo mi señal de reloj pero por el pin de salida del pic no obtengo nada. Aki pongo el codigo que estoy utililzando para hacer las pruebas. Alguna idea de porque puede pasar esto?? He probado a intercambiar los pines de reloj y de salida de datos (para desechar que sea el pin lo que este mal)y pasa lo mismo obtengo señal de reloj y no la de los datos. En los bits de configuracion lo que hago es indicarle que utilizo un cristal externo, utilizo las funciones que vienen en C18.  Gracias de antemano.


#include <p18F25J50.h>              // Libreria del pic 18F25J50
#include <stdlib.h>
#include <spi.h>
#include <pps.h>

char data_in=0;

int mmc_init();

//************************** inicialización MMC ********************* *****************
// Inicializa el modo de MMC en SPI y establece el tamaño de bloque, devuelve 0 en caso de éxito

int mmc_init()
{
int i;
CloseADC();                // esto es porque en otro lugar uso el conversor y por si acaso lo desabilito
INTCONbits.GIE=0;

ODCON3bits.SPI2OD=0; //open drain  // como mi pic funciona a 3,3V no habilito esta opcion
//LATCbits.LATC0 = 1;

//  lo pirmiero que tenemos que hacer es configurar los pines remapeable
PPSUnLock();                      // Desbloqueamos el modo remapeable para poder hacer los camibos
iPPSOutput (OUT_PIN_PPS_RP2,OUT_FN_PPS_SSDMA );
iPPSOutput (OUT_PIN_PPS_RP13,OUT_FN_PPS_SDO2 ); // configuramos el pin 13 como SDO2 ( salida)
iPPSOutput (OUT_PIN_PPS_RP12,OUT_FN_PPS_SCK2 ); // configuramos el pin 12 como SCK2 ( salida) debe estar como entrada y salida segun el data
iPPSInput (IN_FN_PPS_SCK2IN,IN_PIN_PPS_RP12 );  // configuramos el pin 12 como SCK2 (entrada)
iPPSInput (IN_FN_PPS_SDI2,IN_PIN_PPS_RP11 );    // configuramos el pin 11 con SDI2 (entrada)
// Nota la estructura de ippsoutput esta mal en la ayuda miramos en la libreria y es de esta f

PPSLock();                              // Bloqueamos el modo remapeable para que no se puendan hacer cambios
ANCON1bits.PCFG11=1;
LATCbits.LATC1 = 0;                            // Ponemos 0 ya que CKP va a ser = 0 con lo que cuando no hay transmision el nivel va a ser 0
LATCbits.LATC2 = 0;                                   // luego para que no de error debe estar a 0
TRISCbits.TRISC0 = 1;                     // Definimos como entrada corresponde a SDI
TRISCbits.TRISC1 = 0;                     // Definimos como salida corresponde a CLK
TRISCbits.TRISC2 = 0;                     // Definimos como salida corresponde a SDO
TRISAbits.TRISA5 = 0;                     // bit CS
CloseSPI2();
OpenSPI2(SPI_FOSC_64, MODE_00, SMPMID);          // configuramos SSPxSTAT y SSPxCON1
                                           // Activamos el puerto  serie y configura SDI, CLK, SDO y SS por defecto esta a 0

PORTAbits.RA5 = 1;
for(i=0;i<10;i++)                       // inicializar la tarjeta MMC en modo SPI mediante el envío de los CLK on
{                             
        WriteSPI2(0xFF);             
----------------------------------------------------------------------------------------------------------------------------------------------------------------
// esto ya no me lo hace no e transmite los datos si veo que se introducen en el SSP2BUf pero luego no salen por el pin
}
PORTAbits.RA5 = 0;

while(data_in !=1)
{
  WriteSPI2(0x40);                        // CMD0--- cadena a enviar: 0x40,0x00,0x00,0x00,0x00,0x95 esperar respuesta: 0x01 (significa tarjeta en modo idle).
  WriteSPI2(0x00);                        //  todos los argumentos son 0x00 para el comando de reset
  WriteSPI2(0x00);
  WriteSPI2(0x00);
  WriteSPI2(0x00);
  WriteSPI2(0x95);                        // suma precalculada  aun estamos en el modo MMC}
  for(i=0;i<64;i++)
  {
   WriteSPI2(0xFF);
   data_in = ReadSPI2();
   if(data_in==0x01)
   {
    break;
    }
  }
}   
« Última modificación: 19 de Abril de 2011, 19:12:59 por drakont »

Desconectado drakont

  • PIC10
  • *
  • Mensajes: 8
Re: Problema al mandar datos mediante spi
« Respuesta #1 en: 21 de Abril de 2011, 08:25:44 »
Ayer estube probando y con el mismo codigo cambiando el 2 por 1 controlo el modo SPI1 y ahi si m funciona y transmite bits, Supongo que el problema esta a la hora de utilizar los pines reconfigurable, el problema es que necesito utilizar el modulo SPI2 ya que el SPI1 es fijo y eso pines los necesito para I2C.

 ME he fijado que cuando hago la asignacion de los pines reconfigurables, miro los registros en el pic y estan a 0x00 (incluso asingnandole un valor directamente). Es un poco raro ya que la señal de reloj si la obtengo (he probado incluso a ponerla en pines distintos) sin embargo en el registro no me cambia el valor. Alguien sabe si para la reconfiguracion a parte de PPSunlock() hay que tocar algun bit mas??

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Problema al mandar datos mediante spi
« Respuesta #2 en: 21 de Abril de 2011, 11:55:43 »
Porque SCK2 lo re-mapeas como entrada y como salida? Lo demás parece todo correcto... En la configuración de SPI no habrá un bit que habilite SDO como en los PIC de 16-bits?


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado drakont

  • PIC10
  • *
  • Mensajes: 8
Re: Problema al mandar datos mediante spi
« Respuesta #3 en: 21 de Abril de 2011, 12:26:52 »
SCK2 La verdad es que no se porque hay que hacerlo asi, pero lo indica en el datasheet indica que es para no tener problemas de lat's  en el reloj pone esta nota en el data:
When MSSP2 is used in SPI Master  mode, the SCK2 function must be configured  as both an output and an input in the  PPS module. SCK2 must be initialized as
an output pin (by writing 0x0A to one of the RPORx registers). Additionally, SCK2IN must also be mapped to the same pin by initializing the RPINR22 register. Failure to initialize SCK2/SCK2IN as both output and input will prevent the module from receiving data on the SDI2 pin, as the module uses the SCK2IN signal to latch
the received data.

Respecto a lo del bit que habilite SDO no he visto nada, si sabes el nombre de ese bit aunque sea en los de 16-bits te lo agradeceria que me lo indicases y asi buscarlo en el data. Saludo y gracias por tu respuesta

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Problema al mandar datos mediante spi
« Respuesta #4 en: 21 de Abril de 2011, 13:56:31 »
SCK2 La verdad es que no se porque hay que hacerlo asi, pero lo indica en el datasheet indica que es para no tener problemas de lat's  en el reloj pone esta nota en el data:
When MSSP2 is used in SPI Master  mode, the SCK2 function must be configured  as both an output and an input in the  PPS module. SCK2 must be initialized as
an output pin (by writing 0x0A to one of the RPORx registers). Additionally, SCK2IN must also be mapped to the same pin by initializing the RPINR22 register. Failure to initialize SCK2/SCK2IN as both output and input will prevent the module from receiving data on the SDI2 pin, as the module uses the SCK2IN signal to latch
the received data.

No hay dudas al respecto, es propio del microcontrolador...  :?

Acabo de mirar un poco el datasheet (hermoso micro  :mrgreen: ) y no, no dispone de bit para controlar la configuración de SCK y SDO como los de 16-bits. Luego parece todo bien configurado, pines re-mapeables, ADC, módulo SPI  :? Revisa el Errata puede que indique algo, y revisa si los registros se cargan correctamente, puede ser algún bug de las funciones de C18.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado drakont

  • PIC10
  • *
  • Mensajes: 8
Re: Problema al mandar datos mediante spi
« Respuesta #5 en: 21 de Abril de 2011, 14:13:06 »
Hola gracias, por lo que podido probar en SSP2BUF cargo el valor correcto, lo que si me parece algo extraño es que al configurar los pines PPSUnLock();                      // Desbloqueamos el modo remapeable para poder hacer los camibos
iPPSOutput (OUT_PIN_PPS_RP2,OUT_FN_PPS_SSDMA );
iPPSOutput (OUT_PIN_PPS_RP13,OUT_FN_PPS_SDO2 ); // configuramos el pin 13 como SDO2 ( salida)
iPPSOutput (OUT_PIN_PPS_RP12,OUT_FN_PPS_SCK2 ); // configuramos el pin 12 como SCK2 ( salida) debe estar como entrada y salida segun el data
iPPSInput (IN_FN_PPS_SCK2IN,IN_PIN_PPS_RP12 );  // configuramos el pin 12 como SCK2 (entrada)
iPPSInput (IN_FN_PPS_SDI2,IN_PIN_PPS_RP11 );    // configuramos el pin 11 con SDI2 (entrada)

mirando los registros RPOR13,RPOR12 y RPINR12 su valor era de 0x00 incluso haciendo RPOR13=0xAA; su valor seguia siendo 0x00, supongo que sera algun fallo del compilador porque por RP12 si saco la señal de relojo y incluso cambiandola al RP13 tambien la sacaba. Ni se me habria ocurrido pensar en el Errata muchas gracias por la idea, revisare tambien las funciones por si acaso veo algo muchas gracias  :)

Desconectado drakont

  • PIC10
  • *
  • Mensajes: 8
Re: Problema al mandar datos mediante spi
« Respuesta #6 en: 28 de Abril de 2011, 12:39:16 »
Hola buenas ya tengo la soluciona a porque no podia enviar datos, el problema estaba pines reconfigurables yo lo hice asi:

/  lo pirmiero que tenemos que hacer es configurar los pines remapeable
PPSUnLock();                      // Desbloqueamos el modo remapeable para poder hacer los camibos
iPPSOutput (OUT_PIN_PPS_RP2,OUT_FN_PPS_SSDMA );
iPPSOutput (OUT_PIN_PPS_RP13,OUT_FN_PPS_SDO2 ); // configuramos el pin 13 como SDO2 ( salida)
iPPSOutput (OUT_PIN_PPS_RP12,OUT_FN_PPS_SCK2 ); // configuramos el pin 12 como SCK2 ( salida) debe estar como entrada y salida segun el data
iPPSInput (IN_FN_PPS_SCK2IN,IN_PIN_PPS_RP12 );  // configuramos el pin 12 como SCK2 (entrada)
iPPSInput (IN_FN_PPS_SDI2,IN_PIN_PPS_RP11 );    // configuramos el pin 11 con SDI2 (entrada)
La solucion es cambiar la frase en rojo por:
RPOR13=9;
Esto es lo mismo que la frase en rojo ya que esa sentencia lo que hace es a rpor13 asignarle el valor de SDO2 que esta definido como 9.

Por algun motivo esta sentencia no lo hace. 

Ahora voy a pelearme con la lectura de informacion, ya que no me carga el valor de lecutra en ssp2buf ya que he mirado el pin de lecutra cuando la señal de reloj esta en nivel alto el pin de lecutra se pone a lo que haya en la entrada y si esta en nivel bajo se pone a 0.

Espero que le sirva de ayuda a alguien esta solucion, cuando tenga la lectura tambien lo publicare. Saludos.

Desconectado drakont

  • PIC10
  • *
  • Mensajes: 8
Re: Problema al mandar datos mediante spi
« Respuesta #7 en: 19 de Mayo de 2011, 07:11:39 »
Hola buenas, bueno escribo y leeo aunque no lo hace del todo bien, me gustaria saber que escribo en la SD. Alguien sabe como se puede leer la SD en el ordenador ya que al meterla en el ordenador no me reconoce el formato y  me indica que le de formato.... Hay algun programa o algo?

Desconectado drakont

  • PIC10
  • *
  • Mensajes: 8
Re: Problema al mandar datos mediante spi
« Respuesta #8 en: 25 de Mayo de 2011, 11:56:13 »
Hola ya he en contrado un programa por si le puede servir a alguien es el Hexplorer. Mi codigo de escritura es

int mmc_response(unsigned char response)
{
        unsigned long count = 0xFFFF;           // Repetir 16 bits, puede ser posible para reducir esta a 8 bits, pero no tiene mucho sentido
       // Son 32bits 65535=FFFF es exadecimal 8bits=1byte luego son 4bytes= 1 word una palabra son 16bits
       // F=15=4bits

        while(ReadSPI2() != response && --count > 0);  // Lee lo que hay en el buffer de entrada y mientras sea distinto de la reuspuesta continua

        if(count==0) return 1;                  // bucle se sale por tiempo de espera
        else return 0;                          // bucle se salió antes de tiempo de espera
       
       // El bloque espera a que recibir la respuesta  obternida, si el tiempo de espera llega a 0 (count)revuelve un 1 indicando error si es distinto
      // de cero esque a recibido el dato deseado y devuelve un 0 indicando que esta todo ok.
}

//------------------------------------------- Fin Bloque que espera la respuesta de la tarjeta _---------------------------------------------------------








//----------------------------------------- Bloque de escritura ------------------------------------------------------------------------
int mmc_write_block(unsigned long block_number,int porcentaje2, int Valor2 )
{
char direccion[4]={0,0,0,0};   
char porcentaje[2]={0,0};   // estas dos las tendre que poner en el main
char Valor[2]={0,0};
int i;

direccion[0]=block_number>>24;              // aqui intento guardar la direccion que le paso la divido en dos hay que comprobar si guarda bien
direccion[1]=block_number>>16;
direccion[2]=block_number>>8;
direccion[3]=block_number;               // si hace el desplazamiento bien y guarda la parte alta
porcentaje[0]=(porcentaje2>>8);              // aqui intento guardar el porcentaje que le paso la divido en dos hay que comprobar si guarda bien
porcentaje[1]=porcentaje2;
Valor[0]=(Valor2>>8);              // aqui intento guardar el porcentaje que le paso la divido en dos hay que comprobar si guarda bien
Valor[1]=Valor2;

PORTAbits.RA5 = 1;
for(i=0;i<10;i++)                       // inicializar la tarjeta MMC en modo SPI mediante el envío de los CLK on
{                              // esto igual lo tengo que borrar no quiero que cada vez que se inicie me borre la tarjeta
        WriteSPI2(0xFF);               // lo podria usar para resetear la tarjeta si me interesaras pero probar a ver si me resetea la tarjeta
 }
PORTAbits.RA5 = 0;

        WriteSPI2(0x58);                // envia mmc escribe en el bloque
        WriteSPI2(direccion[0]);         // aqui le indicamos con estas 4 instrucciones la direccion de memoria donde queremos que escriba
        WriteSPI2(direccion[1]);         // en el 0 metemos la parte mas alta y el en 3 la mas baja este sera el orden en el 0 la mas alta
        WriteSPI2(direccion[2]);
        WriteSPI2(direccion[3]);                // siempre cero en múltiplos de 8 porque yo he definido el tamaño en 8
        WriteSPI2(0xFF);                // suma de comprobación no es necesaria, pero siempre enviar 0xFF
// Enviar el comando 24 0x58, 0xXX,0xXX,0xXX,0xXX,0xYY. Los 4 bytes XX corresponden a la dirección a partir de la cual se quieren guardar los datos.
//0xYY corresponde al byte de CRC
 
if((mmc_response(0x00))==1) return 1;  // espera respuesta de que todo esta correcto

  WriteSPI2(0xFE);                        // envia datos token
 for(i=0;i<512;i++)                       
{                             
        WriteSPI2(0xFF);               //  escribo 512 bytes
 }
WriteSPI2(0xFF);                        // erro CRC
WriteSPI2(0xFF);
i=0;
while((ReadSPI2()&0x0F)!=0x05)
{
if(i==30) return 1;   // nos indica si hay fallo en la escritura si hay fallo devuelve un 1 si leo un 5 es que esta bien y saca un 0
i++;
 }
return 0;
}

//-----------------------------------------Fin Bloque de escritura ------------------------------------------------------------------------


El problema aque tengo es que me empieza en lugar de escribir el FE antes de eso me pone 0000 0000 0000 0 y despues de eso ya escribe lo que yo le pongo

quedando la secuencia de lectura  0x00 0x07 0xF7 y ya FF...   osea 0000 0000 0000 0111 1111 0111 lo que hace la tarjeta es meter antes una serie de ceros 13 en concreto y luego ya va mentiendo los datos que yo le digo.   Como se ve parte del FE que le pongo esta dividida en dos parte esta en el 2 byte y el resto en el bit 3. Alguien sabe porque puede ser esto?  Saludox

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Problema al mandar datos mediante spi
« Respuesta #9 en: 25 de Mayo de 2011, 13:12:40 »
Mira por aquí, es probado y funcionando.... http://www.micros-designs.com.ar/memorias-sdmmc-libreria-a-nivel-hardware/


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado drakont

  • PIC10
  • *
  • Mensajes: 8
Re: Problema al mandar datos mediante spi
« Respuesta #10 en: 25 de Mayo de 2011, 13:41:06 »
Hola muchas gracias Suky, voy a hecharle un vistazo a ver que tal. Saludos