Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Obsługa EEPromu w AVR GCC

mas24 17 Lip 2015 13:25 1266 28
  • #1 17 Lip 2015 13:25
    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
    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.

    0 28
  • #2 17 Lip 2015 13:42
    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.

    0
  • #3 17 Lip 2015 14:22
    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?

    0
  • #4 17 Lip 2015 14:23
    michalko12
    Specjalista - Mikrokontrolery

    Przykład może da Ci do myślenia:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #5 17 Lip 2015 14:45
    mas24
    Poziom 16  

    OK, więc stworzyłem taką strukturę z nastawami do urządzenia, które programuję:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    potem inicjalizacje wartości domyślne

    Kod: 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ć.

    0
  • #6 17 Lip 2015 14:51
    tmf
    Moderator Mikrokontrolery Projektowanie

    @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).

    0
  • #7 17 Lip 2015 14:59
    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
    Zaloguj się, aby zobaczyć kod


    Tutaj możesz jeszcze coś podpatrzyć https://www.elektroda.pl/rtvforum/viewtopic.php?p=7750406#7750406

    0
  • #8 17 Lip 2015 17:48
    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.

    0
  • #9 17 Lip 2015 19:02
    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
    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.

    0
  • #10 17 Lip 2015 22:14
    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"?

    0
  • #11 17 Lip 2015 23:21
    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.

    0
  • #12 18 Lip 2015 11:34
    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 :-?

    0
  • #13 18 Lip 2015 21:48
    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
    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
    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.

    0
  • #15 19 Lip 2015 11:15
    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?

    0
  • #16 19 Lip 2015 11:19
    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
    Zaloguj się, aby zobaczyć kod


    Kod: c
    Zaloguj się, aby zobaczyć kod

    Tego w pliku nagłówkowym nie może być!

    0
  • #18 19 Lip 2015 12:38
    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.

    0
  • #19 19 Lip 2015 13:12
    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.

    0
  • #21 19 Lip 2015 13:39
    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.

    0
  • #22 19 Lip 2015 13:47
    szczywronek
    Poziom 27  

    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ą!

    0
  • #23 19 Lip 2015 14:08
    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.

    0
  • #24 19 Lip 2015 14:09
    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.

    0
  • #25 19 Lip 2015 14:20
    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?

    0
  • #26 19 Lip 2015 14:31
    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.

    0
  • #27 20 Lip 2015 11:27
    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.

    0
  • #29 20 Lip 2015 13:25
    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.

    0