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

[AVR w C] Konfiguracja i użytkowanie DataFlash na ATmega48 - pytania o SPI i ISP

marenc 10 Lis 2007 11:14 5719 16
REKLAMA
  • #1 4464948
    marenc
    Poziom 24  
    Posty: 881
    Pomógł: 37
    Ocena: 5
    Witam, muszę wykorzystać do mojego projektu pamięć DataFlash. Wiem, że jest na Atmel'u guide na podstawie SoundRecorder'a, ale gubię się w zapisie już któryś raz.

    Prosił bym o informację:
    -czy w fazie testowania będzie kolidowało to z ISP?(wyłączać linię MISO programatora podczas pracy z pamięcią?)
    -jak skonfigurować SPI
    -jak odczytać bufor ze strony o danym numerze
    -jak odczytać daną z bufora 1 o danym adresie
    -jak zapisać bufor do strony o danym numerze
    -jak zapisać daną do bufora 1 o danym adresie

    Czyli praktycznie cała konfiguracja i użytkowanie tej pamięci. Piszę na ATmega48(ale dane mogę być ogólne dla AVR).
  • REKLAMA
  • #2 4465797
    Batmanmen
    Poziom 15  
    Posty: 205
    Pomógł: 9
    Ocena: 4
    Z autopsji wiem, że bywają problemy właśnie z sygnałem MISO. Podłącz go przez rezystor zarówno do procesora jak i SD. Mi czasami nie chciało programować procesora, musiałem wyjmować kartę, zaprogramować, i włożyć kartę z powrotem - albo rezystory.

    Konfigurowanie SPI w atmega16.
    void spi_init()		// inicjalizacja interfejsu SPI
    {
    	DDRB |= (1<<DDB4) | (1<<DDB5) | (1<<DDB7) ; // ss, mosi, sck
    
    	bit_set(PORTB, 4);											//ss stan wysoki
    	SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR1) | (1<<SPR0);		// Enable SPI, SPI master,  clk/128
    
    }
  • #3 4466267
    marenc
    Poziom 24  
    Posty: 881
    Pomógł: 37
    Ocena: 5
    Pamięć to AT45DB161D, a podłączyłem ją tak:
    -1-MOSI
    -2-SCK
    -3-VCC
    -4-SS
    -5-VCC
    -6-VCC
    -7-GND
    -8-MISO

    Poświęcę się i będę wypinał tą kość do czasu programowania ... będzie ona używana podczas odbioru danych przez UART'a, więc nie jest potrzebna zaraz po zaprogramowaniu.

    Nie do końca łapię o co Ci chodzi z tymi rezystorami. No i byłbym wdzięczny za gotowe rozwiązanie ... lub chociaż słowny opis algorytmu zapisu/odczytu do bufora oraz zapisu/odczytu bufora do strony.
  • REKLAMA
  • Pomocny post
    #4 4466362
    Batmanmen
    Poziom 15  
    Posty: 205
    Pomógł: 9
    Ocena: 4
    Jeżeli możesz programować procesor tzn. nie zakłóca nic linii używanych do programowania to nie ma potrzeby wyjmowania pamięci.
    Jeżeli obawiasz się, że podczas programowania dane które mają iść do procesora zaczną skonfigurować twoją pamięć to daj rezystor podciągający do plusa na SS w twojej pamięci. Ten rezystor podciągający potrzebny jest podczas programowania uC, gdyż wtedy IO są w stanie wysokiej impedancji a ty musisz wymusić stan wysoki na SS żeby żadne dane po SPI nie były przyjmowane przez twoją pamięć.

    PS. nie miałem styczności z AT45DB161D.
  • #5 4466409
    marenc
    Poziom 24  
    Posty: 881
    Pomógł: 37
    Ocena: 5
    Podczas programowania nie ma problemu... chodziło mi raczej czy jak będę korzystał z pamięci to programator nie zgłupieje i np. nie zapisze mi czegoś do flash'a(mikrokontrolera) niepotrzebnie...

    W takim razie czekam dalej na pomoc w używaniu tej pamięci...

    //Może kostka jest walnięta ... mógłby ktoś sprawdzić dla mnie kod z pliku poniżej? Podłączenie dowolnego DataFlash do złącza SPI(CS do SS).

    ////Odczytany u mnie status to 0xff, a odczytanie danych z bufora(niezależnie czy nadpisane przeze mnie czy nie) na adresach 0 i 1 to 0xc0. Status powinien być w formie 0bxx1011xx więc nie możliwe, żebym odczytał 0xff :(
    Załączniki:
    • DATAFLASH.h (1.6 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #6 4472086
    arturt134
    Poziom 27  
    Posty: 792
    Pomógł: 76
    Ocena: 24
    Tak jak pisał ktoś wcześniej, sprawę załatwia rezystor podciągający do plusa na CS flasha. Takie roziązanie mam w moim projekcie i nie ma żadnych problemów.
    Chodzi o to, że gdy procesor jest w resecie (wszystkie piny I/O to wejścia, czyli Hi-Z), to programator coś do niego wysyła. Gdyby nie ten rezystor, to programator przypadkiem mógłby wydać jakąś komendę pamięci i uszkodzić dane.
  • #7 4473606
    marenc
    Poziom 24  
    Posty: 881
    Pomógł: 37
    Ocena: 5
    Kolego arturt134 ... używam tej pamięci ze względu na jej pojemność i interface SPI. Dane są do niej zapisywane i odczytywane po zaprogramowaniu, a zawartość tej pamięci po resecie, power-up'ie i innych jest dla mnie zbędna.

    W najbliższych dniach zamontuje tam rezystor, ale to chyba nic nie da :(
  • #8 4475742
    arturt134
    Poziom 27  
    Posty: 792
    Pomógł: 76
    Ocena: 24
    Załączam moje sterowniki (Atmega 128, AT45DB041):
    spi.c - obsługa interfejsu SPI
    flash.c - obsługa operacji DataFlash
    Sterownik obsługuje dwa układy, w twoim przypadku wystarczy zignorować drugi układ. Odwołania do operacji I/O też nie są potrzebne - zignoruj je.
    Jeżeli masz pytania do kodu, to służę pomocą.

    Mam nadzieję, że to pomoże.
    Załączniki:
    • spi.c (3.92 KB) Musisz być zalogowany, aby pobrać ten załącznik.
    • flash.c (19.92 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #9 4479266
    marenc
    Poziom 24  
    Posty: 881
    Pomógł: 37
    Ocena: 5
    Czyli chyba mam uszkodzoną kostkę, bo każde czytanie z bufora zwraca 0x00 nawet jak wcześniej zapisałem daną do tej samej komórki którą odczytuje... Odezwę się jak kupie nową kość i będę miał z nią problemy ;)

    Dzienx za kod ... pewnie bardzo się przyda ;)
  • REKLAMA
  • #10 5569725
    kbosak
    Poziom 12  
    Posty: 62
    Pomógł: 1
    Ocena: 1
    Batmanmen napisał:
    Z autopsji wiem, że bywają problemy właśnie z sygnałem MISO. Podłącz go przez rezystor zarówno do procesora jak i SD. Mi czasami nie chciało programować procesora, musiałem wyjmować kartę, zaprogramować, i włożyć kartę z powrotem - albo rezystory.

    To pewnie dlatego do zlacza ISP daje sie MUXa, zobacz plytki ZL7AVR od Kamami i ich schemat.
  • #11 6444532
    autotransformat
    Poziom 10  
    Posty: 21
    Nie wiem, czy temat jest jeszcze aktywny, ale chcialem zapytać, do czego w pliku spi.h odnosi sie instrukcja #include "dsa_50_def.h"?
  • #12 6446640
    arturt134
    Poziom 27  
    Posty: 792
    Pomógł: 76
    Ocena: 24
    To plik nagłówkowy od mojego projektu. Dla ciebie bez znaczenia.
  • #13 8185214
    mutexxx
    Poziom 10  
    Posty: 13
    artur134,

    Nigdy nie używałem pamięci DataFlash, widzę, żę Twój sterownik jest przygotowany na 2 połączone ze sobą kości. Ja mam tylko jedną, w dodatku nie wersję B tylko D, czyli AT45DB041D , czy ta różnica jest istotna?
    Przeczytałem w dokumentacji, że ten mój DataFlash ma:
     User Configurable Page Size
    –256 Bytes per Page
    –264 Bytes per Page
    –Page Size Can Be Factory Pre-configured for 256 Bytes
     Page Program Operation
    –Intelligent Programming Operation
    –2,048 Pages (256/264 Bytes/Page) Main Memory 4-megabit

    Czy w takim razie ta pamięć ma standardowo wielkość strony ustawioną na 264 B? A jeśli nie to w jaki sposób to ustawić?


    Interesują mnie poniższe informacje:
    1> Zapisanie do pamięci 264 B danych spod "char *dana1zapis" na adres 0, następnie zapisanie danych spod "char *dana2zapis" na kolejny adres, czyli kolejną stronę po tej danej.
    2> Skasowanie całej zawartości pamięci
    3> Odczytanie 264 B danych i zapisanie ich do "char *dana1odczyt" a następnie sięgnięcie do kolejnych 264 B danych w pamięci i zapisanie ich do "char *dana2odczyt".

    Czy ten kod jest prawidłowy:

    #include "flash.c"
    
    int main(void)
    {
    	flash_init();
    	char dane1_zapis[264];
    	char dane2_zapis[264];
    	char dane1_odczyt[264];
    	char dane2_odczyt[264];
    
    	
    	//	zapis
    	//	void zapisz_do_bufora(unsigned nr_strony, unsigned offset, unsigned char* blok, unsigned ilosc);
    	//	void bufor_na_strone(unsigned nr_strony);
    	
    	zapisz_do_bufora(0, 0, dane1_zapis, 264);
    	bufor_na_strone(0);
    	zapisz_do_bufora(1, 0, dane2_zapis, 264);
    	bufor_na_strone(1);
    
    	
    	//	odczyt
    	//	void odczytaj_bez_bufora(unsigned nr_strony, unsigned offset, unsigned char* blok, unsigned ilosc);
    	
    	odczytaj_bez_bufora(0, 0, dane1_odczyt, 264);
    	odczytaj_bez_bufora(1, 0, dane2_odczyt, 264);
    
    	
    	//	skasowanie całej pamięci
    	//	void kasuj_blok(unsigned nr_bloku);
    	
    	int i = 255;
    	while (i--)	kasuj_blok(i);
    	
    	return 0;
    }


    Jaka jest różnica funkcjonalna funkcji (w jakim przypadku warto skorzystać z bufora?):
    void odczytaj_z_bufora(unsigned nr_strony, unsigned offset, unsigned char* blok, unsigned ilosc);
    void odczytaj_bez_bufora(unsigned nr_strony, unsigned offset, unsigned char* blok, unsigned ilosc);

    I jeszcze jedno pytanie: czy ta biblioteka spi.h bedzie dzialac gdy mam polaczony uklad w taki sposob, gdyz zauwazylem, ze niektore funkcje odnosza sie do PORTE?
    [AVR w C] Konfiguracja i użytkowanie DataFlash na ATmega48 - pytania o SPI i ISP

    Powyzsze porty pelnia te funkcje:

    - PB1 (SCK)
    Alternatywne funkcje:
    SCK – linia zegarowa interfejsu SPI

    - PB2 (MOSI)
    PB2 – wejście/wyjście cyfrowe ogólnego przeznaczenia
    Alternatywne funkcje:
    MOSI – linia danych MOSI interfejsu SPI

    - PB3 (MISO)
    PB3 – wejście/wyjście cyfrowe ogólnego przeznaczenia
    Alternatywne funkcje:
    MISO – linia danych MISO interfejsu SPI

    - PB5 (OC1A/PWM1A)
    PB5 – wejście/wyjście cyfrowe ogólnego przeznaczenia
    Alternatywne funkcje:
    OC1A - wyjście A komparatora przy Timerze/Liczniku1 (może działać jako wyjście PWM)

    Jednak czy o to, żeby te porty pełniły te "alternatywne funkcje" trzeba się dodatkowo postarać?

    Niestety w tym momencie nie mam możliwości sprawdzić tego wszystkiego w praktyce, a czas na realizację projektu mnie nagli stąd moje pytania.
    Za wszelką pomoc megadzięki.
  • REKLAMA
  • #14 8187915
    arturt134
    Poziom 27  
    Posty: 792
    Pomógł: 76
    Ocena: 24
    Witam.
    Tak napisane funkcje będą działać.

    O ile pamiętam, to nie ma istotnych różnic między wersją B i D (oczywiście najlepiej przejrzeć dokumentację, szczególnie notę aplikacyjną, która się nazywa "Migrating from B to D family" lub coś w tym rodzaju).

    Fabrycznie układ na 264 bajty/stronę i można to przeprogramować na 256, ale chyba tylko jeden raz.

    Bufor podczas odczytu można wykorzystać do przyspieszenia operacji, jeżeli nie czyta się danych sekwencyjnie, tylko "skacze" po całej stronie. Przy odczycie jednocześnie całej strony (tak jak u ciebie) szybszy będzie odczyt bez bufora.

    Sterownik działa na sprzętowym SPI, Chip select jest wystawiany ręcznie (nie pamiętam z jakiego portu). Po włączeniu interfejsu SPI piny MOSI/MISO/SCK zostaną przechwycone przez niego. Chip select musi być wybierany ręcznie.

    Mam nadzieję, że udało mi się pomóc.
    Pozdrawiam.
  • #15 8195248
    mutexxx
    Poziom 10  
    Posty: 13
    Dzięki za odpowiedzi, jednak nie rozumiem co masz na myśli mówiąc, Chip select jest wybierany ręcznie? Ten Chip select jest związany z wyborem kości w przypadku, gdy są dwie szeregowo podpięte? Czy jeśli mam tylko jedną to mam się tym przejmować? Jeśli tak to w jakim przypadku?

    Poza tym wyskoczyło mi trochę errorów:

    spi.c: In function 'spi_cs1_on':
    spi.c:45: error: 'ss1' undeclared (first use in this function)
    spi.c:45: error: (Each undeclared identifier is reported only once
    spi.c:45: error: for each function it appears in.)
    spi.c: In function 'spi_cs1_off':
    spi.c:53: error: 'ss1' undeclared (first use in this function)
    spi.c: In function 'spi_cs2_on':
    spi.c:61: error: 'ss2' undeclared (first use in this function)
    spi.c: In function 'spi_cs2_off':
    spi.c:69: error: 'ss2' undeclared (first use in this function)

    Moje obawy budzi fakt, że zapisy te odwołują się do portu E np:

    void spi_cs1_on(void)
    {
    PORTE &= ~ss1;
    }//spi_cs1_on

    a jak wynika z obrazka jaki załączyłem, pamięć u mnie nie jest w ogóle podłączona do portu E. Rozumiem, że jest to związane z owym "chip select", które u mnie jest na nóżce PB5, ale nie wiem czy się mylę, czy nie, nie jest to u mnie na stałe ustawione przez ten rezystor? A idąc dalej tym tropem, mam sobie zawracać tym głowę, czy powyrzucać wszystkie te funkcje
    void spi_cs1_on(void);
    void spi_cs1_off(void);
    void spi_cs2_on(void);
    void spi_cs2_off(void);
    oraz wszystkie podziały na 2 pamięci z pliku flash.c, które odwołują się do tych funkcji? Tzn wiadomo, że tak będzie najlepiej, gdy mam tylko jeden układ, ale czy nie muszę ustawiać tego nigdzie w procesie inicjalizacji, tzn nie muszę wykonać na początku funkcji spi_cs1_on()?

    Czy potrzebuję również funkcję:
    void flash_busy(unsigned char nr_flash)?


    Errory wyskoczyły jeszcze z pliku flash.c, ale usunąłem funkcję test_pamieci_flash(void);
    i dodałem z dokumentacji:

    #define FLASH_ILOSC_STRON_NA_UKLAD 2048
    #define FLASH_ILOSC_BAJTOW_NA_STRONE 264
    #define FLASH_ILOSC_BLOKOW_NA_UKLAD 256

    Pozdrawiam
  • #16 8195358
    arturt134
    Poziom 27  
    Posty: 792
    Pomógł: 76
    Ocena: 24
    Oczywiście piny musisz sobie zdefiniować sam. Musisz znaleźć wszystkie odwołania do rejestrów pinów I/O procesora i je pozmieniać na te, do których masz dołączony rzeczywisty układ. Wybacz, ale mój sterownik jest napisany tak, aby działał z moim schematem.
    Funkcja spi_cs1_on() aktywuje chip select od układu 1, funkcja spi_cs1_off() deaktywuje w/w chip select. Funkcje spi_cs2_on() i spi_cs2_off() aktywują / deaktywują chip selecyt dla układu drugiego. Jak działa SPI nie muszę Ci chyba tłumaczyć, opis znajdziesz w każdej dokumentacji do mikrokontrolera.

    Jeżeli zadasz sobie chociaż minimalny trud i przeczytasz dokumentację od kontrolera, na który chcesz napisać program (przynajmniej przejrzysz SPI oraz piny IO) oraz pamięci FLASH, z którą chcesz się skomunikować, to znajdziesz tam odpowiedzi na wszystkie Twoje pytania. Ewentualnie wtedy zadasz pytanie, na które odpowiedzi nie znalazłeś.

    Pozdrawiam.
  • #17 9543416
    marenc
    Poziom 24  
    Posty: 881
    Pomógł: 37
    Ocena: 5
    Nowa pamięć DataFlash i program minął. Po dokładnym przeczytaniu datasheet'a zrozumiałem ideę działania komunikacji i samej pamięci - jest ona stosunkowo prosta w obsłudze. Podstawową sprawą jest podciągnięcie linii CS do VCC - nie wiem jak zrobiłem w projekcie bo to już dosyć dawno było.

Podsumowanie tematu

✨ Dyskusja dotyczy konfiguracji i użytkowania pamięci DataFlash AT45DB161D z mikrokontrolerem ATmega48 (ogólnie AVR) poprzez interfejs SPI. Poruszono problem kolizji linii MISO podczas programowania ISP, sugerując stosowanie rezystorów podciągających na linii CS (SS) pamięci, aby zapobiec przypadkowemu aktywowaniu układu DataFlash przez programator. Przedstawiono przykładową inicjalizację SPI dla AVR (ustawienie pinów MOSI, MISO, SCK, SS oraz rejestru SPCR). Omówiono konieczność ręcznego sterowania linią Chip Select, zwłaszcza przy obsłudze wielu układów, oraz dostosowanie definicji pinów do konkretnego sprzętu. Wskazano, że DataFlash fabrycznie ma stronę o rozmiarze 264 bajtów, którą można jednorazowo zmienić na 256 bajtów. Zaproponowano wykorzystanie buforów pamięci do przyspieszenia operacji odczytu i zapisu. Użytkownik zgłaszał problemy z odczytem statusu i danych (np. odczyt 0xFF lub 0x00), co mogło wskazywać na uszkodzenie układu lub błędy w podłączeniu. Wskazano również na konieczność dokładnego zapoznania się z dokumentacją techniczną mikrokontrolera i pamięci DataFlash oraz na przykład sterowników SPI i DataFlash dla Atmega128, które można zaadaptować. Podkreślono, że połączenie linii CS do VCC przez rezystor podciągający jest kluczowe dla stabilnej pracy i uniknięcia zakłóceń podczas programowania i resetu mikrokontrolera.
Wygenerowane przez model językowy.
REKLAMA