Estoy intentando conectar una tarjeta microSD de 32 GB con PIC32MX795F512L utilizando la comunicación SPI. La comunicación SPI está funcionando bien, ya que la he probado cortocircuitando la línea de Entrada y Salida de Datos y recuperando los datos que envié. Sigo los ejemplos proporcionados en el el libro de Lucio de Jasio, Programación de microcontroladores de 32 bits en C .
Las siguientes son las tareas que estoy realizando:
1. Initializing the SPI Communication in initSPI(), setting the baudrate=76 (250 kHz)
2. Initializing the SD card
-> CS = 1
-> Sending 80 clock cycles to wake the card
-> CS = 0
-> Sending CMD0 command (0x40, 0x00, 0x00, 0x00, 0x00, 0x95)
Pero el problema es que no estoy recibiendo la respuesta R1
de la tarjeta, en cambio estoy recibiendo el 0xFF
. El siguiente es el código:
#define FCY 77000000UL
#define FPB (FCY/2)
#define BAUDRATE 9600
#pragma config POSCMOD=HS,FNOSC=PRIPLL
#pragma config FPLLIDIV=DIV_3, FPLLMUL=MUL_21, FPLLODIV=DIV_1
#pragma config FPBDIV=DIV_2, FWDTEN=OFF
#include <stdio.h>
#include <stdlib.h>
#include <plib.h>
#include <stdbool.h>
#define SDI _RC4
#define SDCS _RA9
#define enableSD() SDCS = 0
#define disableSD() SDCS = 1
#define readSPI() writeSPI(0xFF)
int main(int argc, char** argv)
{
TRISAbits.TRISA9 = 0; // CS as output
TRISCbits.TRISC4 = 1; // SDI as input
TRISDbits.TRISD0 = 0; // SDO as output
TRISDbits.TRISD10 = 0; // SCK as output
AD1PCFG = 0xFFFF;
DDPCONbits.JTAGEN = 0;
OpenUART1( UART_EN | UART_NO_PAR_8BIT | UART_1STOPBIT, UART_RX_ENABLE | UART_TX_ENABLE, (FPB/16/BAUDRATE)-1 );
disableSD(); //CS PIN INITIALLY HIGH TO DISABLE CARD
initSPI();
initSD();
while(1)
{
}
return (EXIT_SUCCESS);
}
void initSPI( void)
{
SPI1BRG = 76; // FPB/154=250KHZ; (76+1)*2 = 154, so brg = 76
SPI1CONbits.MSTEN = 1; // MasterEnable
SPI1CONbits.CKE = 1; // CKE on
SPI1CONbits.ON = 1; // SPI Module ON
}
unsigned char writeSPI(unsigned int b)
{
SPI1BUF=b; // Write to buffer for TX
while( !SPI1STATbits.SPIRBF)
; // Wait transfer complete
return(SPI1BUF);
}
int initSD(void)
{
int i,r,rx;
int data;
// Step1: Disable SD card
disableSD();
// Step2: Send 80 clock cycles to wake up the card
for(i=0; i<=9; i++)
{
data = writeSPI(0xFF);
}
// Step3: Enable SD card
enableSD();
// Step4: Send CMD0 command to RESET
r = sendCMD0();
disableSD();
if(r!=1)
{
putsUART1("CMD reject\n");
}
}
int sendCMD0()
{
int i,r;
enableSD();
writeSPI(0x40);
writeSPI(0x00);
writeSPI(0x00);
writeSPI(0x00);
writeSPI(0x00);
writeSPI(0x95); //CMD0 Command
for( i=0; i<100; i++)
{
r = readSPI();
if ((r & 0x80) == 0)
break;
}
return ( r);
}
Aquí está el esquema :
No estoy recibiendo la respuesta R1
. Está atascado en el paso 4 en initSD()
.
¿Hay alguna manera de saber si la tarjeta se ha despertado o no después de enviar 80 pulsos de reloj? Después de 80 pulsos de reloj, la respuesta de la tarjeta es 0xFF
.
¿Necesito reducir la frecuencia del reloj? Actualmente es de 250 kHz.
¿Por qué la tarjeta no se está inicializando? ¿Cómo puedo solucionarlo?