logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

carta sd spi atmega168 c++

qutrit 26 Lip 2011 23:22 3321 26
REKLAMA
  • #1 9762866
    qutrit
    Poziom 20  
    Witam.
    Otóż mam taki kod, do próby nawiązania komunikacji z kartą SD podłączoną w trybie SPI
    
    #include <avr/io.h>
    #include <util/delay.h>
    
    											//Komendy dostepne w trybie SPI
    
    #define go_idle_state			0x40 //0
    #define send_op_cond 			0x41 //1
    #define cend_csd				0x49 //9
    #define send_cid				0x4a //10//01001010
    #define send_status				0x4d //13
    #define set_blocken				0x50 //16
    #define read_single_block		0x51 //17
    #define write_block				0x58 //24
    #define program_csd				27
    #define set_write_port			28
    #define clr_write_port			29
    #define send_write_port			30
    #define tag_sector_start		0x60 //32
    #define tag_sector_end			0x61 //33
    #define untag_sector			0x62 //34
    #define tag_erase_group_start	0x63 //35
    #define tag_erase_group_end		0x64 //36
    #define untag_erase_group		0x65 //37
    #define erase					0x66 //38
    #define crc_on_off				0x7b //59
    
    												//odpowiedzi
    
    #define r1_busy					128
    #define r1_parametr				64
    #define r1_address				32
    #define r1_erase_seq			16
    #define r1_com_crc				8
    #define r1_illegal_com			4
    #define r1_erase_reset			2
    #define r1_idle_state			1
    								
    	#define Finish 1
    	#define leave 0
    								
    								#define pincs 			0
    								#define portcs 			PORTB
    								
    								#define dir_cs_in			DDRB&=~(1<<pincs);
    								#define dir_cs_out			DDRB|= (1<<pincs);
    								
    								#define out_cs_low 		portcs &=~(1<<pincs);
    								#define out_cs_hi		portcs |= (1<<pincs);
    
    										
    #ifndef mmc_asm
    
    											//deklaracje typow
    
    		typedef unsigned char u08;
    		typedef unsigned short u16;
    		typedef unsigned long u32;
    
    											//prototypy funkcji
    
    		u08 reset(void);
    		u08 read_sector(u32 sector);
    		u08 write_sector(u32 sector);
    		u32 capacity(void);
    		u08 get_cid(void);
    #endif
    
    
    u08 mmc_sbuf[512]; //bufor sektora
    
    
    //procedury pomocnicze
    
    void spi_init(void)
    {
    DDRB |= (( 1 << PB5 ) | ( 1 << PB3 ) | ( 1 << PB2 )); //MOSI, SCK, SS' jako wyjścia
    SPCR = (( 1 << SPE ) | ( 1 << MSTR ) | ( 1 << SPR1 ) | ( 1 << SPR0 ));   //Włączamy SPI,    
    }					//układ Master, najmniejsza częstotliwość SCK fosc / 128
    
    
    u08 spi_tx_rx(u08 byte)					//wysylanie i odbior przez spi
    {
    SPDR = byte;
    while((SPSR & 128)!=128) 				//czekaj na zakonczenie transmisji 
    return (SPDR);
    }
    
    void finish(void)						//zakonczenie trasmisji
    {
    dir_cs_out;				//cs wyjscie
    out_cs_hi;				//cs wysoki
    spi_tx_rx(0xff);				//wysli 8 imp zegarowych
    }
    
    void flush_mmc(u08 count)
    {
    while(count--)
    spi_tx_rx(0xff);
    }				
    
    									//wysylanie komendy i odbior potwierdzenia		
    u08 mmccmd(u08 cmd, u32 param, u08 state)
    {
    u08 i, tmp;
    dir_cs_out;						//cs wyscie
    out_cs_low;	 					//cs niski
    	spi_tx_rx(cmd);					//wysli komende
    	spi_tx_rx(param>>24);				//wysli 4 bajty argumentu
    	spi_tx_rx(param>>16);	
    	spi_tx_rx(param>>8);
    	spi_tx_rx((u08)param);				//lsb
    	spi_tx_rx(0x95);				// wysli crc
    	
    	for(i=0;i<10;i++) 
    	{
    		tmp=spi_tx_rx(0xff);  			  //odbierz odpowiedz, wysylajac cokolwiek np 0xff
    	}
    		PORTD=tmp;   //Caly czas 0xFF !!! a powinno byc 0x01 -co oznacza in idle state 	
    		finish();
    			
    		return tmp;
    
    }
    						
    						
    						
    							//inicjalizacja spi oraz reset
    u08 reset(void)
    {
    u08 tmp;
    dir_cs_out;					//cs wyjscie
    out_cs_hi;	 					//cs niski
    spi_init();						// inicjalizacja spi
    flush_mmc(10);					//80 pustych cykli zegarowych
    tmp=(mmccmd(go_idle_state, 0, Finish));
    return 1;								
    
    }
    
    main()
    {
    DDRD = 0xff;
    reset();
    }
    


    Do PORTD mam podłączonych 8diód za pomocą których monitoruję sobie, co odpowiada mi karta. Cały problem w tym, ze w funkcji mmccmd, PORTD cały czas równa się 0xFF (wszystkie diody świecą). A powinno choćby raz na jakiś czas być 0x01, co oznaczałoby prawidłowe przełączenie się w tryb "in idle state".
    Kartę mam 512MB mikroSD z telefonu Nokia, włożoną do adapteru który jest podłączony do płytki stykowej. Procesor oraz karta zasilana jest z portu USB za pomocą stabilizatora LM1117T 3.3V. Karta jest prawidłowo wykrywana i daje się formatować w komputerze.
    Nie mam już pojęcia ani pomysłów, co może być nie tak :( Czy hardware czy software ? Moze ktoś z forumowiczów wie, co może być nie tak, lub widzi jakiś "głupi" błąd w sofcie ?
    Pozdrawiam
  • REKLAMA
  • #3 9766812
    qutrit
    Poziom 20  
    Jeszcze uprościłem kod:
    
    
    #include <avr/io.h>
    #include <util/delay.h>
    								
    	#define Finish 1
    	#define leave 0
    								
    								#define pincs 			0
    								#define portcs 			PORTB
    								
    								#define dir_cs_in			DDRB&=~(1<<pincs);
    								#define dir_cs_out			DDRB= (1<<pincs);
    								
    								#define out_cs_low 		portcs &=~(1<<pincs);
    								#define out_cs_hi		portcs |= (1<<pincs);
    
    										
    #ifndef mmc_asm
    
    											//deklaracje typow
    
    		typedef unsigned char u08;
    		typedef unsigned short u16;
    		typedef unsigned long u32;
    
    											//prototypy funkcji
    
    		u08 reset(void);
    		u08 read_sector(u32 sector);
    		u08 write_sector(u32 sector);
    		u32 capacity(void);
    		u08 get_cid(void);
    #endif
    
    
    
    
    
    
    
    u08 spi_tx_rx(u08 byte)					//wysylanie i odbior przez spi
    {
    SPDR = byte;
    while(!(SPSR & (1<<SPIF))) 				//czekaj na zakonczenie transmisji 
    return (SPDR);
    }
    
    void finish(void)						//zakonczenie trasmisji
    {
    dir_cs_out;				//cs wyjscie
    out_cs_hi;				//cs wysoki
    spi_tx_rx(0xff);				//wysli 8 imp zegarowych
    }				
    
    main()
    {
    _delay_ms(3);	
    DDRB |= (1 << PB3) | (1 << PB5)| ( 1 << PB2 ); //MOSI, SCK, SS' jako wyjścia
    SPCR = (( 1 << SPE ) | ( 1 << MSTR ) | ( 1 << SPR1 ) | ( 1 << SPR0 ));   //Włączamy SPI,    
    					//układ Master, najmniejsza częstotliwość SCK fosc / 1
    u08 i, tmp;
    DDRD = 0xff;
    dir_cs_out;						//cs wyjscie
    out_cs_hi;
    _delay_ms(1);		 	 		// inicjalizacja spi
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    dir_cs_out;						//cs wyscie
    out_cs_low;	 	
    //_delay_ms(1); 					//cs niski
    	spi_tx_rx(0x40);					//wysli komende
    	spi_tx_rx(0x00);			//wysli 4 bajty argumentu
    	spi_tx_rx(0x00);
    	spi_tx_rx(0x00);
    	spi_tx_rx(0x00);				//lsb
    	spi_tx_rx(0x95);				// wysli crc dla komendy cmd64
    	
    	for(i=0;i<10;i++)
    		{
    		tmp=spi_tx_rx(0xff);
    		}
    			
    			finish();
    			PORTD=tmp;   //JAKIEŚ PRZYPADKOWE KOMBINACJE,  NAJCZĘŚCIEJ 0XFF tj. wszystkie diody świecą
    		return tmp;
    
    }
    

    Schemat:
    carta sd spi atmega168 c++
    Oczywiście do zasilania podłączone są również pin 20 i 22.
    Pozdr.
  • REKLAMA
  • Pomocny post
    #4 9767063
    LordBlick
    VIP Zasłużony dla elektroda
    A rezystory (około 100 Ω) w szereg z LED to gdzie... ?
    Jakiej karty właściwie używasz ?
  • #5 9767194
    qutrit
    Poziom 20  
    :arrow: Light-I
    W pierwszym poście jest napisane:
    Kartę mam 512MB mikroSD z telefonu Nokia, włożoną do adapteru który jest podłączony do płytki stykowej.
    Chyba, ze potrzebne są jakieś inne informacje :?: Ale z tego co pamiętam(piszę z pracy) to na obudowie był tylko jakiś długi numer, nic po za tym.
    Rezystory do diod podłączę, jeżeli miałoby to coś zmienić.

    Znalazłem podobny temat i autor tez ma problem z kartą od telefonu nokia.
    AVR - karta MMC NOKIA - nie obsługuje SPI?
    Będę musiał sprawdzić na innej karcie.
    Ale swoją drogą uwagi, co do programu lub schematu chętnie poczytam.

    Pozdr.
  • #6 9780009
    qutrit
    Poziom 20  
    Witam,
    sprawdziłem program na 2 innych kartach 32MB oraz 1GB i żadna nie działa :cry: Dodatkowo linie DI, DO podłączyłem przez rezystory 56k do plusa zasilania. Również wstawiłem kondensator 100uF na zasilaniu. Sprawdzam program na wszystkie sposoby i nadal nic :cry:
    Pozdr.
  • Pomocny post
    #7 9785527
    LordBlick
    VIP Zasłużony dla elektroda
    1. Daj te rezystory, o których pisałem - narażasz się na resetowanie poprzez zanik napięcia w momencie zaświecenia LED, nie mówiąc o możliwości przeciążenia portu - sprawdzałeś jaki prąd jest pobierany ? ...
    2. Sprawdź ustawienia BOD w fusebitach.
    3. Po stronie 3,3 V za stabilizatorem daj chociaż 47 µF. Przy karcie pamięci bezpośrednio też dodaj 100nF. to się nazywa filtrowanie szpilek obciążeniowych w zasilaniu.
    4. Nie zadawałem pytania "skąd masz tą kartę", tylko jaka ona jest - w domyśle - jakie ma oznaczenia producenta...
  • #8 9809013
    qutrit
    Poziom 20  
    Witam,
    Rezystory i kondensatory podłączyłem. Efektu brak, więc wziąłem się za fusebity.
    BOD = BODLEVEL ??? Jeśli tak, to jaka wartość powinna być ustawiona ? 1,8V 2,7V 4,3V ?
    Pytam, bo nie znam się na tych fusebitach i nie chciałbym uwalić uC.
    Karta SD to np. Panasonic 16MB i dalsze oznaczenia: D020 BP4LA260803 RP-SD016B MADE IN JAPAN.
    Pozdrawiam.
  • Pomocny post
    #9 9830065
    hacker17
    Poziom 17  
    a takie pytanie a nie powinieneś podpiąć pin CS z karty do SS z mikroprocesora ???? Może się mylę ale może będzie to jakaś podpowiedzi :)
  • #10 9830178
    qutrit
    Poziom 20  
    Prawie we wszystkich postach (99.9%) jakie przeczytałem CS było podłączane do osobnego portu sterowanego programowo. Z tego co pamiętam tez łączyłem CS z SS ale nic to nie dało. Spróbuje jeszcze raz podłączyć może teraz zadziała.
    Program już tak okroiłem, ze mam prawie wszystko w main(). I nadal coś jest nie tak :(

    
    #include <avr/io.h>
    #include <util/delay.h>
                            
                            #define pincs          0
                            #define portcs          PORTB
                            
                            #define dir_cs_in         DDRB&=~(1<<pincs);
                            #define dir_cs_out         DDRB= (1<<pincs);
                            
                            #define out_cs_low       portcs &=~(1<<pincs);
                            #define out_cs_hi      portcs |= (1<<pincs);
    
          typedef unsigned char u08;
       
    
    u08 spi_tx_rx(u08 byte)               //wysylanie i odbior przez spi
    {
    SPDR = byte;
    while(!(SPSR & (1<<SPIF)))             //czekaj na zakonczenie transmisji
    return (SPDR);
    }
    
    void finish(void)                  //zakonczenie trasmisji
    {
    dir_cs_out;            //cs wyjscie
    out_cs_hi;            //cs wysoki
    spi_tx_rx(0xff);            //wysli 8 imp zegarowych
    }            
    
    main()
    {
    _delay_ms(3);   
    DDRB |= (1 << PB3) | (1 << PB5)| ( 1 << PB2 ); //MOSI, SCK, SS' jako wyjścia
    SPCR = (( 1 << SPE ) | ( 1 << MSTR ) | ( 1 << SPR1 ) | ( 1 << SPR0 ));  
    
    u08 i, tmp;
    DDRD = 0xff;
    dir_cs_out;   //reset karty             
    out_cs_hi;
    _delay_ms(1);               
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    spi_tx_rx(0xff);
    dir_cs_out;                  
    out_cs_low;       
    //_delay_ms(1);                //cs niski
       spi_tx_rx(0x40);             //wysli komende go idle state 
       spi_tx_rx(0x00);       
       spi_tx_rx(0x00);
       spi_tx_rx(0x00);
       spi_tx_rx(0x00);          
       spi_tx_rx(0x95);      
       
       for(i=0;i<10;i++)             //czekaj na odpowiedź
          {
          tmp=spi_tx_rx(0xff);
          if(tmp==0x01)
             {
             PORTD=tmp;  //JAKIEŚ PRZYPADKOWE KOMBINACJE,  NAJCZĘŚCIEJ 0XFF  tj. wszystkie diody świecą. Na podstawie dokumentacji powinna świecić tylko      jedna 0x01 - typ odpowiedzi R1 z ustawionym najmłodszym bitem !!!
             finish();
             }
         } 
               
          return tmp;
    
    } 
    
  • #11 9836685
    qutrit
    Poziom 20  
    Eh... Znalazłem błąd pisząc kod od nowa. Wszystko przez to, ze do tej pory używając while() podobnie jak for(), if() przy programowaniu software nie używałem średnika. A w programowaniu sprzętowy przy operacjach na bitach okazuje się, ze jest on nie zbędny. Więc
    jest:
    
    u08 spi_tx_rx(u08 byte)               //wysylanie i odbior przez spi
    {
    SPDR = byte;
    while(!(SPSR & (1<<SPIF)))             //czekaj na zakonczenie transmisji
    return (SPDR);
    } 
    


    powinno być:

    
    u08 spi_tx_rx(u08 byte)               //wysylanie i odbior przez spi
    {
    SPDR = byte;
    while(!(SPSR & (1<<SPIF))) ;            //czekaj na zakonczenie transmisji
    return (SPDR);
    } 
  • #12 9857121
    qutrit
    Poziom 20  
    Witam ponownie
    Tak więc po nawiązaniu kontaktu z moją kartą np. poprzez odczytywanie CID, przeszedłem do następnego etapu jakim jest jest implementacja FAT16. Zaczynając oczywiście od szukania info w internecie.
    Więc FAT16 oznacza, iz mamy do dyspozycji 2^16 adresów do adresowania klastrów (jednostek alokacji).
    Jak wiadomo klastry składają się z sektorów których rozmiar najczęściej wynosi 512Bajtów.
    Dysponując kartą 16MB wychodzi (16MB/2^16), ze mój klaster ma rozmiar ok. 245 Bajtów, czyli pół sektora. Gdy założę sobie wielkość klastra=wielkości sektora tj. jeden klaster składa się z jednego sektora (na karcie mamy możliwość ustawienia wielkości sektora) otrzymam (16MB/512B) 31250 klastrów.
    Pytania:
    1. Gdy ustawiam wielkość sektora na karcie SD na 512B "system" sam obliczy ile potrzebuje klastrów ?
    2. Jaka będzie wielkość tych klastrów ? Czy "system" sam przyjmie w tym przypadku 1 klaster=1 sektor, ponieważ ma dość zapasu w tablicy ?
    3. Dlaczego na stronie http://technet.microsoft.com/en-us/library/cc958073.aspx przy volume size 7-16MB przyjęto wielkość klastra = 2KB tj. 4 sektorów ? Skoro jak wspomniałem jest dość miejsca w tablicy aby adresować klaster składający się z jednego sektora ?
    Dziękuję za ewentualne rozwianie wątpliwości :)
  • REKLAMA
  • Pomocny post
    #13 9858302
    maly_elektronik
    Poziom 23  
    System sam ustali ile przypada sektorów na klaster i sam obliczy ile jest klastrów:)
    Ilość klastrów odczytasz z tablicy alokacji FAT saź to ile sektorów przypada na klaster odczytasz z BootSectora:) Tak samo z BootSectora odczytasz ile bajtów przypada na sektor ale przy kartach sd jest to chyba zawsze 512 bo tyle ma sam sektor karty :) odczytasz tam także ilość ReservedSectors oraz adres Root Directry :)
  • #14 9864452
    qutrit
    Poziom 20  
    Powiedzmy ze sformatowałem sobie kartę w winXp i w głównym katalogu \ utworzyłem plik test.txt Przekładam kartę do uC i jak mam go otworzyć (skąd mam wiedzieć w jakim klastrze się on utworzył) i powiedzmy zapisać w nim napis "hallo world", tak żeby ujrzeć ten tekst później w kompie ? Kurcze niby wszystkie podstawowe procedury mi działają, a nie wiem za bardzo jak się za to zabrać. Wiem ze są biblioteki PetitFat ale jak dla mnie są za bardzo skomplikowane. Poza tym myślę sobie ze do otwarcia i zmiany zawartości już wcześniej utworzonego pliku nie potrzeba aż tak rozbudowanej biblioteki-chyba ze się mylę.
    Domyślnie obsługa kart jest mi potrzebna do akwizycji danych z czujnika temperatury.
  • Pomocny post
    #15 9864743
    maly_elektronik
    Poziom 23  
    Mylisz się :) Aby znaleźć plik to już trzeba trzeba trochę kodu (czyli wystarczy petitFatFs) :)
    Ale żeby już zmienić jego zawartość to już sporo zabawy :)
    Należy:
    1. Wyliczyć wielkość danych które chcesz zapisać (pestka)
    2. Zlokalizować plik w RootDirectry (trochę trudniej)
    3. Wyciągnąć interesujące nas informacja o pliku z RootDirectry
    3. Zmienić rozmiar pliku w RootDirectry (bo przecież coś do niego wpisujesz)
    4. Wykorzystać informacje z RootDirectry i odnaleźć plik w tablicy alokacji FAT
    5. Jeśli wartość do zapisania przekracza 1klaster znaleźć nowy pusty klaster w FAT
    5.1 Jeśli nie przekracza czyliczyć nr 1 sektora istniejącego klastra i tam zapisać

    6. Wpisać adres nowej komurki FAT (klastra) do poprzedniej komórki (wówczas ostatniej)
    7. Wyliczyć gdzie znajduje się określona ilość sektorów przypadająca na nowo dodany klaster
    8. Wpisać dane :)
    9. Pamiętać że wszystko musi współgrać z zaimplementowaną obsługą karty SD lub innego nośnika danych :)

    Jeżeli się jeszcze tym nie zajmowałeś skorzystaj z gotowych bibliotek :)
    Wierz mi nie jest to takie proste (chodź bardo trudne też nie) bo sam pisałem taką bibliotekę i wiem ile to zajmuje czasu :)

    Dodano po 50 [sekundy]:

    Acha pamiętaj że nie możesz tworzyć katalogów na karcie w rozwiązaniu opisanym przeze mnie bo wówczas musisz jeszcze dopisać obsługę katalogów co znacznie bardziej skomplikuje Ci życie :)

    Dodano po 2 [minuty]:

    Radze skorzystanie z fat32 jest bardzo podobny tylko bardziej rozbudowany :) a skoro już piszesz bibliotekę to wykorzystasz ja w przyszłości na większych kartach SD :)
    Nawet kartę 128MB (chyba nie ma mniejszych) sformatujesz na fat32 i będzie działać poprawnie :)
  • #16 9873996
    qutrit
    Poziom 20  
    Witam ponownie.
    Poniżej przedstawiam mój kod póki co do odczytu rejestrów CID oraz CSD. Mam taki problem ponieważ według dokumentacji w CID pierwszy bit=1. Czyli czytam sobie wszystkie 16bajtów do tablicy buf[i]; a na PORTD podaję pierwszy tzn.PORTD|=buf[0]; co oznacza, ze powinna mi się zapalić dioda na najmłodszy bicie, a tak nie jest. Pozostałe 7bitów (CRC) również się nie świeci.
    Posiadam kartę firmy SanDisc. W CID ostatni bajt zwany Manufacturer ID MID i dla SanDisc powinien wynosić 0b00000011 (0x03) a u mnie jest 0b10000001 (0x81). Po wyjęciu i wkładaniu karty cały czas otrzymuję te same wartości bajtów, więc to nie są przypadkowe wartości w związku z czym wykluczam przekłamania. Moze ktoś mógłby wskazać mi ewentualny błąd, lub zasugerować w jaki inny sposób można upewnić się, ze komunikacja z kartą jest poprawna.

    Kod: text
    Zaloguj się, aby zobaczyć kod
    [/img]
  • #17 9874245
    elektryk101
    Warunkowo odblokowany
    Jeżeli wszystko masz podłączone tak jak na schemacie który wcześniej podałeś, to powinieneś jeszcze podłączyc zasilanie części analogowej procesora(piny 20 i 22). To też jest ważne.
  • Pomocny post
    #18 9874314
    maly_elektronik
    Poziom 23  
    widzę ustawiłeś blocklen na 0x200 (zamiast 0x0200 możesz napisać 0x200 -> wg mnie wygląda przejrzyściej) :)
    Skoro ustawiłeś blok/sektor danych na 512 to jak chcesz je zmieścić do bufora 16B :?:

    Oczywiście jest to możliwe,można odczytać pozostałe 498B w powietrze, ale czy Ty tak robisz :?: Czy po prostu próbujesz upchać 512B do tablicy 16B :?:

    Dodano po 2 [minuty]:

    Pomyłka ty chcesz odczytać CID (powyższe w tym przypadku nie ważne ale zostawiam bo przyda się do czego innego) :)

    Przy odczycie CID dzieją się różne cuda (najlepiej wychodzi to przy transmisji SD bus), masz ustawioną prędkość SPI przy odczycie na 100-400kHz jak podaje nota :?:

    Dodano po 1 [minuty]:

    A sprawdzanie CID i CSD nie jest konieczne do sprawdzenie czy karta działa poprawnie z programem :) Wystarczy sprawdzić czy karta przeszła z trybu IDLE do trybu pracy :) Jeśli tak znaczy że jest gotowa i można działać :D
  • REKLAMA
  • #19 9874410
    qutrit
    Poziom 20  
    Patrząc na moją funkcję GO IDLE STATE:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    wydaje się ze jest dobra ponieważ zapala mi się dioda, tylko wtedy jeżeli jest spełniony warunek if(tmp==0x01). Inne warunki np. if(tmp==0x04) nie powodują zapalenia się diody. Podobnie rzecz się ma z pozostałymi funkcjami :)
    Tylko ten CID mnie zaniepokoił. Sprawdzę tą prędkość, ale z tego co pamiętam to ustawiłem ją na najnizszą SPCR = ( 1 << SPE ) | ( 1 << MSTR ) | ( 1 << SPR0 ) | ( 1 << SPR1 ); Chyba, ze chodzi o jakąś inną prędkość ?
  • Pomocny post
    #20 9874430
    maly_elektronik
    Poziom 23  
    Nie tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    tylko tak:
    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #21 9875585
    qutrit
    Poziom 20  
    Poprawiłem zapis SPCR:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    Kurcze mam trzy karty i z żadnej nie mogę odczytać rejestru CID czy tez CSD tak aby zgadzał się z dokumentacją :( Będę "walczył" ale jakby komuś z użytkowników przyszedł jakiś pomysł, to z chęcią bym go sprawdził. Bo wydaje mi się, ze mimo wszystko coś jest nie tak. Moze czyta to użytkownik który ma jakieś doświadczenie w czytaniu CID-u i CSD, czy miał podobne problemy ??
  • #22 9899880
    qutrit
    Poziom 20  
    Postanowiłem inaczej przetestować zapis/odczyt. Sformatowałem kartę SD w komputerze. Zainstalowałem WinHexa i widzę bajt po bajcie jak ona wygląda.
    carta sd spi atmega168 c++

    Funkcja do odczytu pojedyńczego bloku wygląda następująco:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Podając w argumencie komendy 0 powinienem odczytać cały pierwszy sektor czyli MBR. Program jednak "zawiesza" się w pętli for(). Tablica buf[i] jest 512 elementowa tupu char. Ma może ktoś pomysł co może być źle ?
  • Pomocny post
    #23 9900151
    michalko12
    Specjalista - Mikrokontrolery
    Popraw to:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #24 9900170
    qutrit
    Poziom 20  
    poprzednio było poprostu:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    i tez nie działało :(
  • Pomocny post
    #25 9900267
    michalko12
    Specjalista - Mikrokontrolery
    W 8 bitach nie policzysz do 512!
  • #26 9900298
    qutrit
    Poziom 20  
    Upsss ale gamoń ze mnie. Jak tylko wrócę do domku zaraz sprawdzę. Zasugerowałem się tym, ze odczyt CID działał, ale tam przecież jest do odczytania tylko 16 bajtów.
  • #27 9918673
    qutrit
    Poziom 20  
    Więc, małymi kroczki (ze względu przede wszystkim na czas) doszedłem do momentu prawidłowego odczytu/zapisu informacji z/na kartę. Odebrane dane wyświetlane za pomocą diod zgadzają się z tym, co pokazuje WinHex :)
    Teraz przyszedł czas na FAT, Kupiłem sobie książkę w której jest gotowy PetitFAT. Z internetu tez mam sporo artykułów, ale to wszystko (jak dla mnie) jest pobieżnie opisane, nie mogę się w tym połapać. W związku z tym czy ktoś z forumowiczów zna może ciekawe strony, książki, gdzie byłoby to opisane w przejrzysty sposób krok po kroku. Oczywiście w języku c. Byłbym bardzo wdzięczny :) Mógłbym wgrać jakiegoś gotowca i pewnie z waszą pomocą bym go uruchomił:) Ale tez chciałbym co nie co wiedzieć, jak i dlaczego to działa :)
REKLAMA