Я пытаюсь подключить карту microSD на 32 ГБ к PIC32MX795F512L , используя связь SPI. Связь SPI работает нормально, так как я проверил ее, замкнув линию ввода и вывода данных и получив обратно данные, которые я отправил. Я следую примерам, приведенным в книге Лусио де Хасио « Программирование 32-битных микроконтроллеров на C ».
Ниже приведены задачи, которые я выполняю:
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)
Но проблема в том, что я не получаю R1
ответ от карты, вместо этого я получаю файл 0xFF
. Ниже приведен код:
#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);
}
Вот схема :
Я не получаю R1
ответ. Он застрял на шаге 4 в initSD()
.
Есть ли способ узнать, проснулась ли карта после отправки 80 тактовых импульсов? После 80 тактовых импульсов карта дает ответ 0xFF
.
Нужно ли уменьшать тактовую частоту? В настоящее время это 250 кГц.
Почему карта не инициализируется. Как я могу это исправить?
Я не вижу никакого кода для того, чтобы сделать вывод MISO входным выводом или сделать вывод SCK выводом. Поскольку вы не используете библиотеку SPI в plib
, вам нужно выполнить всю инициализацию выводов самостоятельно. Кроме того, после отправки CMD0
увеличьте количество итераций (в вашем for
цикле) с 8 до 20 (я использую 100), чтобы обеспечить достаточную свободу действий. Также вместо этого используйте это сравнение:
if ((r & 0x80) == 0)
break;
return r;
Также сделайте r
везде unsigned char
.
if ((r & 0x80) == 0)
. Можете ли вы объяснить немного.uint8_t
было бы лучше, чем unsigned char
.Внешне выглядит как проблема с электрикой
На более позднем этапе вам может понадобиться проверить следующее - нет определенного порядка.
https://www.sdcard.org/downloads/pls/simplified_specs/archive/part1_110.pdf
пг 47 говорит, что нужно опрашивать устройство, пока карта не придет в готовность Вы этим занимаетесь?
Check the 'endianness'
, можешь немного пояснить
Дэйвид
КрисР
пользователь3629249
пользователь007
пользователь3629249
СореDakeNoKoto