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

Karta MMC. Odczytywanie sektorów. Program się zapętla.

Gieno100 17 Mar 2007 13:27 1503 8
  • #1 3687338
    Gieno100
    Poziom 10  
    Posty: 55
    Ocena: 5
    Witam!
    Zbudowałem układ na Atmega 16 do rejestracju temperatury, podłączyłem do niego kartę RS-MMC i procedury z EP 2004. Karta podłączona jest przez dzielniki napięcia oprócz styku DO, który jest podłączony bezpośrednio. Problem polega na tym iż mogę zapisać do karty jak i odczytać dane z niej, jednak gdy próbuję odczytać jeden sektor po drugium program zapętla się przy wykonywaniu polecenia:

    
    // ***********************************************************
    // Wysłanie komendy do karty i odbiór potwierdzenia R1
    // ***********************************************************
    u08 mmc_cmd(u08 cmd, u32 param, u08 state)
    { 
    	u08 i,tmp;
    	
    	cbi(MMC_PORT, MMC_CS); 		// aktywuj CS 
    	spi_tx_rx(cmd | 0x40); 		// wyślij komendę 
    	spi_tx_rx(param >> 24); //przy tym poleceniu się zapętla
    	spi_tx_rx(param >> 16); 
    	spi_tx_rx(param >> 8); 
    	spi_tx_rx((u08)param); 		// LSB 
    	spi_tx_rx(0x95); 			// wyślij poprawna sumę CRC 
    							// dla komendy CMD64 
     for(i=0 ; i<10 ; i++) 		// czekaj na odpowiedź 
    	{ 
    		tmp = spi_tx_rx(0xff); // odbierz odpowiedź 
    		if((tmp & R1_BUSY) == 0) // jeśli BUSY == 0 
    			{ 	
    				if(state == Finish) 
    					mmc_finish(); 
    				return tmp; // komenda wykonana 
    			} 
    	} 
     mmc_finish(); 
     return 3; // błąd braku odpowiedzi z karty}
    }
    



    u08 spi_tx_rx(u08 byte)			// wysłanie i odbiór bajtu przez SPI
    {
    	SPDR = byte;
    	loop_until_bit_is_set(SPSR, SPIF); 
    	return (SPDR);
    }
    


    a dokładniej w linijce

    
    loop_until_bit_is_set(SPSR, SPIF);
    

    gdy zapiszę jeden sektor a następnie odczytam sektor zapisamy bądź jakiś inny, program idzie bez problemu. I jeszcze dziwne jest to że po inicjacji karty i po upływie dłuższej czwili od tego momentu oraz próbie odczytu z karty sektora bądź CID w ogóle nie daje się nic odczytać. jedynie bezpośrednio po inicjacji można odczytać i zapisać kartę. Sprawdzałem kartę w czytniku wszystko jest ok. Ten sam problem dzieje się na innej karcie. Co może być przyczyną
    Załączniki:
    • mmc.h (6.68 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #2 3688733
    ziomal155
    Poziom 15  
    Posty: 211
    Pomógł: 6
    Ocena: 13
    hehe nie jestes pierwszy mi dokladnie w tym samym miejscu sie zapentla i nikt mi nie umie pomoc :( tu chyba chodzi o to ze trzeba ustawic ten bit zeby sie wyzerowal czy jakos tak, ale mi nadal nie dziala:(
    Pozdrawiam
  • #3 3689318
    Gieno100
    Poziom 10  
    Posty: 55
    Ocena: 5
    W takim razie jedynym wyjściem do czasu wyjaśnienia tej przyczyny jest podpięcie zasilania karty pod nóżkę z procesora i podawać napięcie na kartę chwilę przed odczytem/zapisem a następnie reset karty. Po takiej operacji da się odczytać jeden sektor lub zapisać i znowu wyłączyć napięcie.
  • #4 3689850
    ziomal155
    Poziom 15  
    Posty: 211
    Pomógł: 6
    Ocena: 13
    u mnie sie nic nie da odrazu sie zatrzymuje na tej instrukcji
  • Pomocny post
    #5 3689866
    VanThor
    Poziom 19  
    Posty: 224
    Pomógł: 34
    Ocena: 5
    A jak zamiast tego:

    
    u08 spi_tx_rx(u08 byte)			
    {
    	SPDR = byte;
    	loop_until_bit_is_set(SPSR, SPIF); 
    	return (SPDR);
    }
    


    zastosujesz to:

    
    u08 spi_tx_rx(u08 byte)			
    {
    	SPDR = byte;
    	while (!(SPSR & (1 << SPIF))); 
    	return (SPDR);
    }
    


    Jeszcze takie dwa pytania. Watchdog jest wyłączony? Przerwania są wyłączone?
  • #6 3690461
    ziomal155
    Poziom 15  
    Posty: 211
    Pomógł: 6
    Ocena: 13
    u mnie tak ale co za różnica?? mam debugowanie przez RS co dwie linijki i napewno wiesza sie w tym momencie.
    Pozd.
  • #7 3690518
    Gieno100
    Poziom 10  
    Posty: 55
    Ocena: 5
    ziomal155 Na jakim procesorze jest oparty twój układ?? Brałeś te funkcje z EP??

    Dodano po 1 [godziny] 3 [minuty]:

    Więc zamian kodu wg propozycji VanThor pomogła i karta śmiga bez problemu. ziomal155 co do twojego problemu: na początku mi również karta w ogóle nie śmigała ale problem był w tym iż przy ustawianiu nóżek jako wyjścia w czasopiśmie jest podane:
    
    void spi_init(void)		// inicjalizacja interfejsu SPI
    {
    	DDRB |= (1<<DDB3) | (1<<DDB5) | (1<<DDB2);  // tu powinno być DDB7 zamiast DDB2 dla Atmegi 16, 32
    	SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);		// SPI master 
    }


    Nie wiem dla jakiego procesora jest u Ciebie ale sprawdź czy ta konfiguracja pinów jest ok, powinny być ustawione trzy piny wyjściowe gdzie masz podłączoną katrę czyli CS, MOSI, SCK.
  • #8 3690879
    ziomal155
    Poziom 15  
    Posty: 211
    Pomógł: 6
    Ocena: 13
    ja mam ATMEGA162 i też kożystałem z tych funkcji z EP.
  • #9 3691072
    Gieno100
    Poziom 10  
    Posty: 55
    Ocena: 5
    czyli powinieneś mieć skonfigurowane wyjścia tak samo jak u mnie tj
    
    void spi_init(void)      // inicjalizacja interfejsu SPI 
    { 
       DDRB |= (1<<DDB3) | (1<<DDB5) | (1<<DDB7); 
       SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);      // SPI master 
    }


    Ta linijka:
    
    
       DDRB |= (1<<DDB3) | (1<<DDB5) | (1<<DDB7);  
    


    jest skofigurowana dla podłączenia CS -> PB3, MOSI-> PB5, SCK-> PB7, a jak jest u Ciebie?

    Dodano po 9 [minuty]:

    Jak pewnie zauważyłeś z tego co było w EP zmieniłem jeszcze
    SPCR = (1<<SPE) | (1<<MSTR);		// SPI master

    na:
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);      // SPI master


    Bo tak jest w manualu, ale nie wiem co to zmienia, reszta kodu jest bez zmian oprócz oczywiście tej pentli loop na while. A jak ty masz?

    Dodano po 1 [godziny] 18 [minuty]:

    Małe sprostowanie. Po dłuższej chwili zabawy z kartą obie wersje działają zarówno ta z loop jak i while a na przyczynę wpadłem całkiem przypadkowo a mianowicie podłączyłem zasilanie karty do portu PB4 czyli SS i przed każdym zapisem lub odczytem włączałem zasilanie karty i wyłączałem. Potem przyszedłten pomysł z while ale napięcie podłączyłem bezpośrednio do zasilania czyli 3.6V. Natomiast nie skasowałem setowania pinu PB4 czyli SS na samym początku programu i karta ruszyła. Po skasowaniu tego setowania karta się nie odzywała. Po ponownym ustawieniu tego pinu PB4, lub podłączeniu tej nóżki do zasilania przez rezystor, karta chodzi zarówno na loop jak i while. Nie mam pojęcia dlaczego tak się dzieje ale jak SS jest ustawione na '1' nie ma problemów z komunikacją.

Podsumowanie tematu

✨ Problem dotyczy zapętlania się programu podczas odczytu kolejnych sektorów z karty RS-MMC podłączonej do mikrokontrolera Atmega16, wykorzystującego procedury z Elektroniki Praktycznej 2004. Karta jest podłączona przez dzielniki napięcia, z wyjątkiem linii DO podłączonej bezpośrednio. Zapętlenie występuje przy wysyłaniu parametrów komendy SPI, szczególnie podczas przesyłania bajtu parametru przesuniętego o 24 bity. Rozwiązaniem okazała się modyfikacja funkcji spi_tx_rx, gdzie zamiast instrukcji loop_until_bit_is_set zastosowano pętlę while oczekującą na ustawienie bitu SPIF w rejestrze SPSR. Dodatkowo ważne jest prawidłowe skonfigurowanie pinów SPI jako wyjścia (CS, MOSI, SCK) zgodnie z mikrokontrolerem (np. DDB7 zamiast DDB2 dla Atmegi16/32). Zmiana ustawień rejestru SPCR poprzez dodanie bitu SPR0 również pomogła w stabilizacji komunikacji. Wskazano także, że zasilanie karty można podawać chwilowo przed operacją odczytu/zapisu, a następnie resetować kartę, co umożliwia poprawne działanie przy odczycie pojedynczego sektora. Problemy mogą wynikać z nieprawidłowej inicjalizacji SPI lub błędów w obsłudze protokołu komunikacji z kartą MMC.
Wygenerowane przez model językowy.
REKLAMA