karta SD a PIC18

Feb 21, 2008 2 Replies

Witam! Chciałbym ( a właściwie to muszę ) odczytać i zapisywać kartę SD w moim układzie. Karta jest podłączona do PIC18LF4550 chodzącego na 3,3V do portu SPI. na liniach portu są pull-upy 1k. do tego oczywiście linia CS. Karta to Panasonic 16MB



Korzystałem z kilku różnych przykładów, chodzi mi o cokolwiek, żeby to zrozumieć, a potem wykorzystywać. inicjacja wygląda u mnie tak:


  1. Wysyłam 80 cykli zegarowych
  2. wysyłąm CMD0 R1=0x01
  3. wysyłam CMD1 R1=0x00
  4. wysyłam CMD55
  5. wysyłam ACMD41 R1=0x00
  6. wysyłam CMD16 z parametrem 8 R1=0x00 //i tu powinna być karta zainicjowana (wygląda na to że jest) przy parametrze 512 (wyskakuje Parameter Error).

Następnie próbuję coś odczytać, ale z pamięci to ni jak ma się do tego co powinno tam być, większość zera + jakieś śmieci. Jak czytam rejestr CID to wychodzi 0x01 (może to jest kod Matsushity, ale nie udało mi się tego znaleźć) potem PASO i dalej śmieci. Ale co dziwne, cokolwiek bym nie próbował odczytać, to co 8 bajt dostaję 0x04 (co wygląda jak error Illegal Command). Mam nadzieję, że ktoś mi coś poradzi. Wklejam oczywiście kod:



pozdrawiam Grzegorz Latocha P.S. sorry za długość posta



//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& OpenSPI(SPI_FOSC_64, MODE_11, SMPMID); //otwieram port na wolnej prędkości DelayMS(100); //odczekuję, aż karta się uruchomi



SD_CE = 1; for (timeout=0; timeout<10; timeout++) WriteSPI(0xFF); //wysyłam 10 razy 8 cykli - tego wymaga karta



SD_CE = 0; DelayMS(10); //włączam SPI w karcie //Wysyłanie CMD0 do { odpowiedz = SDSendCMD(0x00,0x00000000,0x95); } while(odpowiedz != 0x01); EEPROMWrite(0x00,odpowiedz); //nie ma wyświetlacza, więc tak sprawdzam co przyszło LED1=0;



//wysyłanie CMD1 tak długo, aż karta się uruchomi do { SD_CE = 1; WriteSPI(0xFF); SD_CE = 0; odpowiedz = SDSendCMD(0x01,0x00000000,0xFF); }while((odpowiedz & 0x01)!=0); EEPROMWrite(0x01,odpowiedz); LED2=0; WriteSPI(0xff);



SD_CE = 0; odpowiedz = SDSendCMD(55,0x00000000,0xFF); //przed komendą ACMD41 WriteSPI(0xFF); LED3=0;



do { odpowiedz = SDSendCMD(41,0x00000000,0xFF); } while((odpowiedz & 0x01) !=0); EEPROMWrite(0x02,odpowiedz);


WriteSPI(0xFF);



odpowiedz=SDSendCMD(16,8,0xff); //ustawiam rozmiar bloku na 8B EEPROMWrite(0x03,odpowiedz);



WriteSPI(0xFF);



//odczyt karty chcę odczytać 8 bajtow z adresu 0 ReadData();



LED4 = 0; DelayMS(1000); LED4 = 1;


//888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 //888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 void ReadData(void) { SD_CE = 0; if(SDSendCMD(17,0,0xFF)==0x00) LED3=0;



//czekanie na początek danych do { odpowiedz = ReadSPI(); } while(odpowiedz!=0xFE); //czekanie na tokena



EEPROMWrite(0x12,odpowiedz);



LED4=0;



for(Temp=0;Temp<8;Temp++) SD_Buffer[Temp] = ReadSPI(); //czytanie danych



ReadSPI(); //czytanie crc ReadSPI(); WriteSPI(0xFF); //wysyłam clock



SD_CE = 1;



for(Temp=0;Temp<8;Temp++) EEPROMWrite(0x20+Temp,SD_Buffer[Temp]); SD_CE = 1; }


Nie jest czasem tak, ¿e karty umo¿liwiaj± jedynie zapis / odczyt ca³ych 512 bajtowych bloków? Mniej nie odczytasz / zapiszesz - musisz mieæ procka z buforem w ram 512 bajtów...

Xaveri pisze:

Teoretycznie nie, ale komenda ustawienie bloku na 512B wywala mi błąd Illegal Prarameter. A jak odczytywałem całe 512bajtów, to początek był identyczny jak przy 8, a potem co 8 bajt to 04 tak jak pytałem.

Zamówiłem kartę MMC, podobno robi mniej problemów na początek :-)

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required