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

Jak odczytać i zapisać dane w EEPromie Atmega16 za pomocą AVR GCC?

mas24 17 Lip 2015 13:25 1824 28
  • #1 14855236
    mas24
    Poziom 16  
    Witam,

    Nie miałem okazji przedtem pobawić się EEPromem zawartym w Atmega16, aż do dzisiaj. Pogrzebałem po necie i napisałem taki oto programik:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Niestety program nie działa zgodnie z oczekiwaniami. Jego celem jest zapisanie predefiniowanych wartości w eepromie, gdy komórki są puste. Jednakże do epromu zapisywane są zupełnie inne liczby, czasami zapisuje właściwie, czasami nie i nie wiem, od czego to zależy. Adresy chcę mieć zdefiniowane wcześniej, gdyż będę się do tych komórek epromu odwoływał w dalszych częściach programu.
  • #2 14855281
    michalko12
    Specjalista - Mikrokontrolery
    Źle podchodzisz do tematu.

    Tworzysz sobie typ danych w postaci struktury z ustawieniami wraz z polami na CRC. Alokujesz takie typy w RAM, ROM i EEPROM. Strukturę w ROM inicjujesz wartościami domyślnymi. Przy każdej zmianie danych w RAM w tej strukturze aktualizujesz sumę kontrolną. Tworzysz funkcję zapisu całej struktury z funkcjami update do EEPROM. Przy uruchamianiu kopiujesz całą strukturę z EEPROM do RAM i sprawdzasz czy zgadza się suma kontrolna, jeśli nie to kopiujesz do RAM dane z ROM, bez zapisu do EEPROM. W ten sposób masz pewność, że dane są aktualne i nie uległy uszkodzeniu. Możesz również w EEPROM umieścić kilka kopii danych i podczas ładowania danych z EEPROM szukać takiej kopii która ma właściwe CRC. Uszkodzone struktury danych w EEPROM powinny być zregenerowane właściwymi danymi.
    Kilka kopii ma tą zaletę, że nie tracisz danych gdy podczas zapisu do EEPROM zostanie wyłączone zasilanie.
  • #3 14855323
    mas24
    Poziom 16  
    Widziałem podobne rozwiązania ze strukturami, jak piszesz, przy czym ten prosty sposób także powinien działać, ale tak nie jest i nie wiem czemu?

    Dodano po 24 [minuty]:

    Poczytałem o strukturach i wygląda na to, że do eepromu trzeba zapisywać od razu całą strukturę, przy czym ja w programie czasami chcę uaktualnić tylko jedną zmienną, więc po co zapisywać wszystko, jak mam tych zmiennych w epromie np. 6?
  • #4 14855387
    michalko12
    Specjalista - Mikrokontrolery
    Przykład może da Ci do myślenia:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #5 14855449
    mas24
    Poziom 16  
    OK, więc stworzyłem taką strukturę z nastawami do urządzenia, które programuję:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    potem inicjalizacje wartości domyślne

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    czy można te zmienne używać w programie tak jak normalne zmienne? Jak z widocznością zmiennych w innych plikach projektu? Czy wystarczy, że napiszę:

    extern nastawy.ilediod; ?

    czy muszę "externować" całą strukturę, jak w innym pliku używam tylko tej jednej zmiennej?

    Podana przez michalko12 procedurka wydaje mi się kopiować całą strukturę do eeprom, ale mogę się mylić.
  • #6 14855468
    tmf
    VIP Zasłużony dla elektroda
    @mas24 Do tej pory wszystko masz w SRAM, więc możesz to używać jakkolwiek chcesz. Natomiast po skopiowaniu do EEPROM już nie. TFunkcja kol. @michalko12 oczywiście kopiuje wszystko do EEPROM, na lokalnej kopii w SRAM ciągle możesz pracować.
    BTW, o ile dobrze pamiętam działasz też na XMEGA? Tam masz fajnie, bo EEPROM można zmapować w obszar przestrzeni adresowej MCU, w efekcie przynajmniej odczyt odbywa się w C bezpośrednio, bez żadnych makr. Zapis też się wtedy mocno upraszcza i przyśpiesza (nawet 32 razy).
  • #7 14855482
    michalko12
    Specjalista - Mikrokontrolery
    No to w XMEGA masz spore ułatwienia, ja z XMEGA nie miałem nic wspólnego.
    Kontynuując dla męczących się w AVR...
    Tworzysz takie definicje i deklaracje i na nich potem stosujesz to co opisałem wyżej

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Tutaj możesz jeszcze coś podpatrzyć https://www.elektroda.pl/rtvforum/topic1591158.html#7750406
  • #8 14855700
    mas24
    Poziom 16  
    Tym razem to nie jest Xmega, tylko zwykła Atmega16, ale dzięki za wyjaśnienie, wprowadzam powoli struktury do programu zamiast garści "zwykłych" zmiennych.

    Dodano po 38 [minuty]:

    Mam problem w użyciu jednej ze zmiennych struktury w innym pliku. Nie wiem, jak przekazać ta zmienną do fragmentu programu w innym pliku.
  • #9 14855904
    michalko12
    Specjalista - Mikrokontrolery
    mas24 napisał:
    Mam problem w użyciu jednej ze zmiennych struktury w innym pliku. Nie wiem, jak przekazać ta zmienną do fragmentu programu w innym pliku.

    Tworzysz plik nagłówkowy np setup.h a w nim

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    i masz dostęp ro zmiennych w strukturze w każdym pliku źródłowym który ma dołaczony w/w plik.
  • #10 14856271
    mas24
    Poziom 16  
    A nie w głównym main.c? plik setup.h mam także, są tam ustawienia portów,z zegarów, ADC itp.

    A czy to słowo nastawyRAm ma znaczenie, czy można np. samo "nastawy"?
  • #11 14856408
    michalko12
    Specjalista - Mikrokontrolery
    mas24 napisał:
    A nie w głównym main.c? plik setup.h mam także, są tam ustawienia portów,z zegarów, ADC itp.

    A czy to słowo nastawyRAm ma znaczenie, czy można np. samo "nastawy"?


    Przepraszam, ale ręce mi opadły.
    Zamiast setup.h nazwij sobie ten plik ustawienia.h lub nazwę wygeneruj z jakiegoś generatora haseł. To samo dotyczy się nazwy tej zmiennej.

    C masz opanowane w miernym stopniu, poświęć trochę czasu na doszkolenie. Każda minuta na doszkoleniu zastąpi wiele minut na pisaniu kodu.
  • #12 14857014
    mas24
    Poziom 16  
    Teraz jak przeczytałem swoje pytania, to sam się złapałem za głowę, co wypisałem wczoraj w nocy, zamiast iść spać. Pytań nie było :-?
  • #13 14858364
    mas24
    Poziom 16  
    OK, powinno działać, program się skompilował, ale działanie będę mógł zobaczyć dopiero w poniedziałek.

    W pliku nagłówkowym "setup.h", który już miałem dopisałem:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    bardzo ważna jest ostatnia linia, bo bez niej kompilator nie czaił, co to są te "nastawy".

    W każdym pliku (w tym "main.c"), gdzie chcę użyć zmiennych z tej struktury, mam zainkludowany "setup.h" i w zmiennych globalnych:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    czyli taka sama definicja jak w nagłówkowym "setup.h", tylko ze wskazaniem, że struktura jest w innym pliku (extern).

    I chyba o to chodziło, a ja mam juz większą wiedzę, jak stosować struktury. Nadal pozostaje zabawa z eepromem. Specjalnie wybrałem z programu odpowiednie zmienne do struktury, które mają się znaleźć w eepromie.
  • #15 14859140
    mas24
    Poziom 16  
    Mam sporo książek o C, ale z podstaw korzystam z tzw. "Blue Booka" M. Kardasia i extern zrozumiałem właśnie tak. Skoro w moim rozumowaniu/programie występuje błąd, to mi go pokaż, bo ja jak na razie go nie widzę i przykład, który podałeś w innym wątku zgadza mi się z moją wiedzą, wiec nie wiem, w czym problem?
  • #16 14859145
    michalko12
    Specjalista - Mikrokontrolery
    Zmień tą książkę od podstaw.

    mas24 napisał:
    W pliku nagłówkowym "setup.h", który już miałem dopisałem:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Tego w pliku nagłówkowym nie może być!
  • #18 14859353
    mas24
    Poziom 16  
    @micha_łko12: czyli wystarczą odpowiednie externy w odpowiednich plikach, a ten w nagłówkowym jest zbędny?

    @szczywronek: program działa, ale tylko zaraz po zaprogramowaniu. Po wyłączeniu zasilania i ponownym włączeniu, wartości odczytane z eepromu są z kosmosu wzięte.
  • #19 14859435
    michalko12
    Specjalista - Mikrokontrolery
    mas24 napisał:
    a ten w nagłówkowym jest zbędny?

    W kodzie pliku nagłówkowego którego przedstawiłeś nie miałeś żadnego externa, miałeś tylko definicję zmiennej, a definicji zmiennych nie wykonuje się w plikach nagłówkowych.

    Mam wrażenie, że kompletnie nie pojmujesz zagadnienia. Więc jeszcze raz proszę Cię o pogłębienie wiedzy w odpowiedniej profesjonalnej literaturze, a nie jakiś tam bluebookach.
    Teoretycznie ilość informacji jaką Ci podałem powinna Ci wystarczyć, ale najwyraźniej jest jakiś opór w twoim przyswajaniu, albo ja nie mam zdolności dydaktycznych.
  • #20 14859502
    szczywronek
    Poziom 28  
    mas24 napisał:
    program działa, ale tylko zaraz po zaprogramowaniu. Po wyłączeniu zasilania i ponownym włączeniu, wartości odczytane z eepromu są z kosmosu wzięte.
    To coś źle robię bo u mnie działa :(
  • #21 14859525
    mas24
    Poziom 16  
    Dopisanie "extern" do pliku nagłówkowego, gdzie jest definicja struktury powoduje wywalenie błędu "undefined reference to `nastawy' ", taki sam efekt daje wywalenie tej linijki zupełnie. Piszesz, że nie podajemy definicji w plikach nagłówkowych, a sam tak napisałeś kilka postów wyżej.
    Cytat:

    Tworzysz plik nagłówkowy np setup.h a w nim

    typedef struct
    {
    uint32_t Val_A;
    uint32_t Val_B;
    uint32_t Val_C;
    }TSetup

    extern TSetup NastawyRAM;



    i masz dostęp ro zmiennych w strukturze w każdym pliku źródłowym który ma dołaczony w/w plik.
  • #22 14859554
    szczywronek
    Poziom 28  
    Ciekawe co teraz Koledze michalko12 opadnie...

    @mas24 przestań próbować na chybił trafił byle się skompilowało, tylko poświęć godzinę i przeczytaj co powoduje extern, jak przebiega kompilacja i jak dzielić kod na pliki źródłowe i nagłówkowe.

    Błąd undefined reference to `nastawy' jest jak najbardziej w porządku. Wynika z tego, że nie masz pojęcia co robisz i nigdzie nie umieściłeś definicji zmiennej nastawy. Linijka z extern nie jest definicją!
  • #23 14859616
    mas24
    Poziom 16  
    To ja już czegoś nie rozumiem. Po co pisać słówko "extern" w pliku (setup.h), skoro deklaracja jest właśnie w tym pliku?

    I skoro extern służy do poinformowania kompilatora, żeby szukał deklaracji w innym pliku, to moim zdaniem dobrze robię, że w innych plikach piszę

    extern Tnastawy nastawy

    i program się kompiluje. Nie wiem, dlaczego wmawiacie mi, że moje myślenie jest błędne?

    Dodano po 5 [minuty]:

    OK, można tak zrobić, żeby walnąć w nagłówkowym (setup.h) ten extern, a w źródłowym (setup.c) napisać:

    Tnastawy nastawy

    i to też jest zgodne z logiką, bo mamy już 2 pliki i program także się kompiluje. Wygląda na to, że chodzi tu o jakąś poprawność programistyczną. Niestety nie mam jak sprawdzić programu, bo układ będę mógł zaprogramować w poniedziałek.
  • #24 14859631
    michalko12
    Specjalista - Mikrokontrolery
    szczywronek napisał:
    Ciekawe co teraz Koledze michalko12 opadnie...

    Teraz to mi się ciśnienie podniosło
    mas24 napisał:
    Piszesz, że nie podajemy definicji w plikach nagłówkowych, a sam tak napisałeś kilka postów wyżej.
    Cytat:


    To jeszcze doczytaj czym się różni definicja od deklaracji
    i jeszcze raz precyzyjnie przeczytaj zawarte w tym
    wątku przykłady, zwróć uwagę na nazwy plików w przykładach.
  • #25 14859656
    mas24
    Poziom 16  
    I wszystko się teraz zgadza. Napisałem w swoim programie tak, jak jest w poście, co linka teraz podałeś. Program skompilował się bez błędów, tak więc:

    W pliku "setup.h" mam deklarację z extern, to samo w pozostałych plikach, gdzie chcę tej struktury użyć. Oczywiście w tych pozostałych plikach musi być zaincludowany plik "setup.h". A dopiero w pliku "setup.c" w zmiennych globalnych mam definicje tej struktury (już bez extern).

    Mam nadzieję, ze o to chodziło?
  • #26 14859679
    michalko12
    Specjalista - Mikrokontrolery
    mas24 napisał:
    Napisałem w swoim programie tak, jak jest w poście, co linka teraz podałeś

    Ten link już Ci wcześniej podałem w tym poście. Czytaj i analizuj uważnie to co Ci inni podsuwają.

    mas24 napisał:
    Mam nadzieję, ze o to chodziło?

    To Ty powinieneś wiedzieć czy o to Ci chodziło.
  • #27 14861201
    mas24
    Poziom 16  
    No i właśnie lektura tego postu doprowadziła mnie do szczęśliwego zakończenia, bo układ działa (sprawdziłem).

    Teraz zapis i odczyt z EEPROMu.

    Dodano po 1 [godziny] 25 [minuty]:

    Zaczął się robić bałagan w programie, wiec utworzyłem sobie oddzielne pliki EEprom.h i EEprom.c i tam chcę też umieścić funkcje zapisu i odczytu.

    Po podłączeniu zasilania potrzebuje zrobić taką procedurę, która sprawdza stan komórek w eepromie, i jeśli są puste (wartość 0xFF), to ma zapisać predefiniowane wartości, a jeśli mają jakieś wartości, ma je odczytać do użytku w programie. Sytuacja taka będzie wtedy, gdy świeżo zmontowaną płytkę trzeba pierwszy raz zaprogramować i uruchomić.

    Dodano po 2 [godziny] 24 [minuty]:

    OK, z obsługą EEpromu też sobie poradziłem. Chciałbym jednak zapytać o taką rzecz:

    Czy procedura "eeprom_update_block" zapisuje całą strukturę, czy jedynie te komórki (zmienne), które się różnią? Czym się ona różni w działaniu od "eeprom_write_block"? Wspominałem wcześniej, że chcę uaktualniać w eepromie pojedyncze zmienne struktury, stąd moje pytanie, bo nie mogłem dojść do tej informacji.
  • #29 14861830
    mas24
    Poziom 16  
    Powinni tą idiotyczną opcję z Googla usunąć, a opis był nieco inny, choć sprowadzał się do tego samego, ale OK, niech im będzie, ze to jest rzeczywiście update.
REKLAMA