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

ATmega reset i utrata EEPROM silne zakłócenia EMI

mcswirus 01 Sty 2020 22:50 897 7
REKLAMA
  • #1 18374630
    mcswirus
    Poziom 8  
    Witam,

    na bazie ATmega8A-PU zbudowałem moduł zapłonowy do motocykla Junak i Ural.
    Generalnie wszystko działa poprawnie jeśli odległość samego modułu
    czy przewodu sygnałowego z czujnika halla od przewodu wysokiego napięcia
    jest powiedzmy co najmniej 5 cm.

    Testując filtry przeciwzakłóceniowe zbliżam ekranowany przewód sygnałowy
    do przewodu WN tak, że praktycznie się dotykają na odcinku 15-20cm.
    Iskra jest, wszystko działa ale w pewnym momencie następuje reset uC
    po którym traci zapisane ustawienia w EEPROM, przyjmuje ustawienia,
    które ma zapisane we FLASH czyli jakby wraca do "ustawień fabrycznych".
    Identyczny efekt powstaje jak zbliżę płytkę z uC do przewodu WN
    na odległość np. 2cm.

    Wiem, że to ekstremalne testy i zabawy, które mogą uszkodzić uC
    ale chciał bym wiedzieć dlaczego on traci dane z pamięci EEPROM
    a nie traci z FLASH ? Wiem, że FLASH można zapisać około 10 tyś razy
    a EEPROM około 100 tyś razy, więc może ma to jakiś wpływ
    na konstrukcję tych pamięci i ich odporność na zakłócenia EMI ?

    Bardzo proszę o wyjaśnienie tematu ;-)

    Pozdrawiam
    Sławek
  • REKLAMA
  • #2 18374668
    tmf
    VIP Zasłużony dla elektroda
    Może nie traci - odczytaj EEPROM i porównaj. Prawdopodobnie przekłamanie dotyczy jednego bajtu EEPROM, tego na który aktualnie wskazuje rejestr adresowy EEPROM. Stąd też, ustaw wartość tego rejestru na nieużywaną komórkę pamięci EEPROM zawsze kiedy się do tej pamięci nie odwołujesz, możesz np. na 0 i pominąć tą komórkę pamięci przy zapisie (zapisywać od adresu 1). Warto też ustawić BOD.
  • REKLAMA
  • #3 18375379
    mcswirus
    Poziom 8  
    OK, dzięki za podpowiedź.
    Przetestuję na dniach i dam znać.

    Sławek

    Dodano po 6 [godziny] 34 [minuty]:

    Witam ponownie,

    oto wyniki testu:

    1. przesunięcie danych w EEPROM o 1 lub 2 bajty dalej
    i wskazanie rejestrem EEAR = 0; po zapisie lub po odczycie
    całego bloku danych nic nie zmieniło ale ...

    2. sprawdzając co siedzi w EEPROM okazuje się,
    że praktycznie dane są, nie doszukiwałem się
    czy w każdym bajcie jest OK, ale 95% danych wygląda OK.

    Na starcie programu po ustawieniu wszystkich portów,
    timerów, przerwań, itd. Tuż przed uruchomieniem
    głównego bloku programu dokonuję sprawdzenia
    wczytuję dane z EEPROM do RAM i sprawdzam
    sumę kontrolną, jak jest OK to kontynuuję program
    jak nie to ładuję ustawienia "fabryczne" i zapisuję do EEPROM
    a dopiero odpalam program główny.

    Za każdym razem gdy wyłączam i włączam zasilanie jest OK.
    Sprawdzanie sumy kontrolnej działa poprawnie. Zmiany wprowadzone
    w firmware wpływające na potrzebę zmiany zawartości EEPROM
    powodują przeładowanie go do ustawień fabrycznych, więc jest OK,
    ale podczas silnego zakłócania polem EMI, następuje chwilowe
    przerwanie wykonywania programu i powrót z wgranym fabrycznym
    ustawieniem w EEPROM.

    Zasilanie jest cały czas, nie jest wyłączane podczas tego testu.
    Gdzie szukać ?
    Sprawdzać dokładnie każdy Bajt w EEPROM ?

    Sławek
  • REKLAMA
  • #5 18383383
    mcswirus
    Poziom 8  
    Witam,

    dzisiaj miałem czas na zgranie kodu i wyrzucenie z niego
    tego co nie dotyczy tematu:

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


    Dodano po 7 [minuty]:

    Przepraszam za dziwne znaki w komentarzach
    ale przerzucałem z Windowsa na Linuxa
    i nie konwertowałem kodowania.

    Będę wdzięczny za pomoc.

    Sławek
  • #6 18384472
    tmf
    VIP Zasłużony dla elektroda
    Tak jak pisałem, po operacjacvh na EEPROM, rejestr adresowy powinien wskazywać na nieużywaną komórkę pamięci. Ty zapisujesz i nadajesz mu 0, czyli wskazuje na komórkę pamięci używaną przez twoją strukturę. W przypadku problemów zawartość tej komórki zostanie uszkodzona. Poza tym dlaczego nie używasz funkcji bibliotecznych dostępu do EEPROM? Masz tam też funkcje odczytu i zapisu blokowego, co ułatwia odczyt/zapis struktur.
    No i zamiast PROGMEM przejdź na __flash, dzięki czemu unikniesz konstrukcji typu pgm_read_byte.
  • #7 18384533
    mcswirus
    Poziom 8  
    Dzięki za odpowiedź,

    > Tak jak pisałem, po operacjacvh na EEPROM, rejestr adresowy
    > powinien wskazywać na nieużywaną komórkę pamięci.
    > Ty zapisujesz i nadajesz mu 0, czyli wskazuje na komórkę pamięci używaną przez twoją strukturę.
    > W przypadku problemów zawartość tej komórki zostanie uszkodzona.

    Wskazuję na 0 gdyż zapisu dokonuję od komórki 2.
    Czyli 2 pierwsze bajty zostawiam nieużywane.

    #define EPROM_ADDRESS 2;
    save_to_EEPROM(EPROM_ADDRESS);

    Po tej operacji wskazuję na komórkę 0.
    Chyba o to chodziło ?

    > Poza tym dlaczego nie używasz funkcji bibliotecznych dostępu do EEPROM?
    > Masz tam też funkcje odczytu i zapisu blokowego, co ułatwia odczyt/zapis struktur.

    Szczerze pisząc to nie zagłębiałem się w tą bibliotekę.
    Poczytam co ona oferuje.

    >No i zamiast PROGMEM przejdź na __flash, dzięki czemu unikniesz konstrukcji typu pgm_read_byte.

    A możesz podesłać jakiś link do materiałów na ten temat ?
    Tego nauczyłem się z książki ale jak są prostsze metody to chętnie użyję :)
    Pierwszy raz się z tym spotykam, ja programuję AVR'y hobbystycznie.

    Sławek
  • REKLAMA
  • #8 18390446
    mcswirus
    Poziom 8  
    Witam ponownie,

    próbowałem ogarnąć na początek funkcję eeprom_write_block.
    Oto fragment kodu:

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


    Przy kompilacji mam ostrzeżenie:
    warning: passing argument 1 of '__eewr_block_m8' discards qualifiers from pointer target type

    Jak usunę przedrostek volatile to kompiluje się poprawnie.

    I tu mam pytania:

    1. Dane używane ze zmiennej Engine są w kilku miejscach i przez różne procedury i przerwania czy w takiej sytuacji mogę zlikwidować volatile ?
    Czy kod będzie wtedy optymalizowany i być może część tych danych będzie w rejestrach a to nie może nastąpić. Tam jest ponad 100 Bajtów.

    2. Dlaczego dodając volatile kod wynikowy rośnie ? Czy odwoływanie się bezpośrednio do komórek pamięci względem operacji na rejestrach aż tak bardzo zwiększa kod ?

    3. Co zrobić aby pozostało volatile a kompilacja przebiegała bez ostrzeżeń ?

    Pozdrawiam
    Sławek
REKLAMA