Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Wyszukaj w ofercie 200 tys. produktów TME
Europejski lider sprzedaży techniki i elektroniki.
Proszę, dodaj wyjątek elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[ASM] Tiny2313 - Zapis/odczyt wewnętrznej pamięci EEPROM

Artur k. 24 Sie 2016 17:40 1152 26
  • #1 24 Sie 2016 17:40
    Artur k.
    Admin grupy audio

    Witam

    Od kilku dni walczę z prostym programem w asemblerze. Program ma sterować kluczem analogowym CD4052, samą obsługę klucza napisałem w godzinkę i ruszyło z kopyta, problem pojawił się gdy zechciałem by zapisywać w wewnętrznym EEPROM stan ostatnio wybranego wejścia tak by po ponownym włączeniu zasilania było ono aktywne.

    Zamieszczam fragment programu:

    Kod: avrasm
    Zaloguj się, aby zobaczyć kod


    W całości program składa się z 4 pętli (zamieściłem tylko dwie, żeby zobrazować jak to ma działać).
    Ma to działać tak - po włączeniu zasilania odczytywana jest zawartość pamięci o adresie 1. Następnie porównuję zawartość rejestru R19 do którego przerzucam zawartość pamięci z 4 różnymi stałymi które charakteryzują każdą z 4 pętli. Jeśli zawartość jest zgodna, to program ma skoczyć do odpowiedniej pętli, jeśli jest niezgodna - ma odpowiednio ustawić zawartość rejestrów DDRD i PORTD, które są wartościami startowymi i następnie przejść "do porządku dziennego".
    Po naciśnięciu któregoś z 4 przycisków ma zapisać do pamięci odpowiadający mu stan rejestru PORTD (po którym przy odczycie identyfikuję odpowiednią pętlę).
    Program krąży w pętli dopóki nie zostanie naciśnięty inny przycisk - wówczas przeskakuje do innej pętli i w niej krąży do czasu naciśnięcia kolejnego przycisku.
    Ogólnie sam program bez procedur zapisu/odczytu EEPROM działa dobrze, problem pojawił się gdy postanowiłem dorobić mu pamięć. W symulatorze pakietu AVR Studio niby wszystko jest dobrze, jednak w rzeczywistości nie działa prawidłowo.
    Po zapisaniu pamięci wartościami FF, program "stwierdza" że zawartość pamięci nie pasuje do żadnej stałej i ustawia wartości startowe i wchodzi do pierwszej pętli (zapala się odpowiednia dioda), natomiast po wyłączeniu zasilania i włączeniu ponownie nie dzieje się nic. Dopiero gdy nacisnę przycisk zapala się dioda do niego przyporządkowana i potem już działa prawidłowo dopóki nie wyłączę zasilania.

    Wygląda to tak, jakby był jakiś problem z odczytem pamięci i skokiem do odpowiedniej pętli - zapis jest prawidłowy, po wyłączeniu zasilania i odczytaniu zawartości pamięci EEPROM jest tam prawidłowa zawartość.
    Nie wiem, może to trzeba jakoś inaczej rozwiązać niż poprzez mnemonik breq? Niestety nie wiem jak - utknąłem na tym etapie.

    Proszę o sugestie.

  • #2 24 Sie 2016 18:52
    excray
    Poziom 38  

    Spróbuj tak jak zaleca nota:

    Kod: avrasm
    Zaloguj się, aby zobaczyć kod

  • #3 24 Sie 2016 19:03
    Artur k.
    Admin grupy audio

    Tak było na początku, ale na symulatorze wychodziło, że bit EEPE jest po włączeniu ustawiony (w sumie nie wiem z jakiego powodu), dlatego dołożyłem jego zerowanie, myśląc że właśnie w tym jest problem. Poza tą jedną linijką moja wersja nie różni się od tej z noty katalogowej.
    W każdym razie czy zeruję bit EEPE, czy nie, nie wpływa to na działanie programu w rzeczywistym układzie.

  • #4 24 Sie 2016 19:40
    excray
    Poziom 38  

    Twój zapis do EEPROM też znacząco się różni od DSa. Skąd takie rozbieżności?

  • #5 24 Sie 2016 20:05
    Artur k.
    Admin grupy audio

    Zapis się różni, ale działa poprawnie, bo jak sprawdzam na programatorze zawartość to zawsze jest poprawna.
    Różnica wynika z tego, że w mądrej książce wyczytałem że należy się upewnić że EEPROM jest gotowy do zapisu (np nie trwa inny zapis) oraz żeby się upewnić że przed zapisem bit EEPE jest ustawiony.

    Stąd wymyśliłem tak:

    Kod: avrasm
    Zaloguj się, aby zobaczyć kod

    Najpierw próbuję wyzerować bit EEPE, potem sprawdzam czy jest wyzerowany, jeśli nie jest to próbuję ponownie i tak do skutku. Potem typowa procedura adresowania pamięci oraz zapisu danych do rejestru EEDR, na koniec ustawiam bit EEMPE, upewniam się że został ustawiony i jeśli nie to zaczynam całą procedurę od początku (tu akurat nie jest konieczne zaczynanie od początku ale tak jest prościej) i jeśli EEMPE jest ustawiony to ustawiam EEPE. Tak wymyśliłem, ponieważ bit EEPE trzeba ustawić w przeciągu 4 taktów od momentu ustawienia EEMPE - inaczej EEMPE zostanie automatycznie wyzerowany. Gdyby z jakiegoś powodu bit EEMPE zostałby wyzerowany to zapis się nie powiedzie, dlatego sprawdzam jego stan przed potwierdzeniem zapisu. Takie zabezpieczenie sobie wymyśliłem, żeby na pewno zapis się powiódł.

  • #6 24 Sie 2016 20:27
    excray
    Poziom 38  

    W oryginale jest:

    Kod: avrasm
    Zaloguj się, aby zobaczyć kod

    U Ciebie:
    Kod: avrasm
    Zaloguj się, aby zobaczyć kod

    Takie same jak w DSie są funkcje zapisu i odczytu tworzone przez AVRGCC i powiem szczerze nigdy nie miałem problemu. Za chwilę spróbuję wrzucić Twoje wersje i przetestować.

  • #8 24 Sie 2016 20:42
    Artur k.
    Admin grupy audio

    Odpowiadając na pytania:

    excray napisał:
    cbi EECR, EEPE <= po co kasujesz ten bit?

    Po to by na pewno był wyzerowany. Ew. trwające zapisy mnie nie interesują bo nie mają skąd się wziąć. Wyszedłem z założenia, że skoro nie może trwać poprzedni zapis, a ten bit potencjalnie mógłby być ustawiony to go wyzeruję.

    excray napisał:
    rjmp eeprom_write <= po co ten skok?

    A tutaj skok na wypadek gdyby z jakiegoś powodu bit EEMPE był wyzerowany - wówczas zapis się nie powiedzie. Żeby na pewno się powiódł, procedura ma być powtarzana do skutku (aż EEMPE będzie ustawiony).

    W sumie mógłbym to zrobić tak:
    Kod: avrasm
    Zaloguj się, aby zobaczyć kod

    ale nie robi mi różnicy czy będę powtarzał całą procedurę, czy tylko sprawdzanie EEMPE.

  • #9 24 Sie 2016 20:46
    Piotrus_999
    Poziom 40  

    Artur k. napisał:
    Po to by na pewno był wyzerowany. Ew. trwające zapisy mnie nie interesują bo nie mają skąd się wziąć. Wyszedłem z założenia, że skoro nie może trwać poprzedni zapis, a ten bit potencjalnie mógłby być ustawiony to go wyzeruję.


    Nie możesz zakładać czegoś innego, niz mówi DS. Ten bit generalnie jest zerowany tylko przez sprzęt.
    Zakładając że z jakiegoś powodu bylby podniesiony to należy poczekać na jego wyzerowanie (ale nie zerować go)

  • #10 24 Sie 2016 20:46
    excray
    Poziom 38  

    Sprawdziłem Twoje wersje na attiny2313 i działają, niemniej radziłbym Ci używać zalecanych w DSie gdyż jak wspomniał @Piotrus_999 bit EEPE powinien być wyzerowany sprzętowo.

  • #11 24 Sie 2016 20:59
    kamyczek
    Poziom 33  

    Bit eepe wskazuje na zajętość modułu obsługującego eeprom wystarczy więc poczekać na jego zwolnienie inaczej zapis czy odczyt może skończyć się niepowodzeniem . Procedura z noty katalogowej działa poprawnie nie ma co wymyślać i jej zmieniać . Należy się natomiast zapoznać z całą notą bo na jej końcu często umieszczone są uwagi dotyczące nieprawidłowego działania czy też wersji układu . Zdarzało się np. tak że zapis eeprom był prawidłowy jedynie dla vcc=5V . Poza tym musisz zwrócić uwagę że zapis eeprom nie jest zbyt szybki więc lepiej operować na ram i przy bezczynności mikrokontrolera w tle uaktualniać zmienne z ramu do eepromu a przy starcie czytać je i umieszczać w ram .

  • #12 24 Sie 2016 21:03
    Piotrus_999
    Poziom 40  

    Jak byś zobaczył DS-ie ten bit ma initial value X czyli nie jest to zdeterminowane, a Twoim obiwiązkiem jest czekać aż się wyzeruje bez względu na to co go ustawiło.

  • #13 24 Sie 2016 21:16
    excray
    Poziom 38  

    Piotrus_999 napisał:
    Jak byś zobaczył DS-ie ten bit ma initial value X czyli nie jest to zdeterminowane, a Twoim obiwiązkiem jest czekać aż się wyzeruje bez względu na to co go ustawiło.

    Popatrzyłem w DSie. Wiem o tym, że jest zerowany sprzętowo i nigdy tego nie negowałem, a nawet dwukrotnie sugerowałem autorowi, żeby sam tego nie robił. Więc nie wiem o co ten przytyk do mnie.

  • #15 24 Sie 2016 21:33
    Artur k.
    Admin grupy audio

    Piotrus_999 napisał:
    Nie możesz zakładać czegoś innego, niz mówi DS.

    Wiesz, akurat moje doświadczenia z przeróżnymi DS są zgoła inne. W DS są przedstawione tylko przykłady realizacji, co wcale nie oznacza że należy ściśle się do nich stosować. Z uC doświadczenia za wielkiego nie mam, ale elektroniką zajmuję się już naście lat i trochę już rzeczy w życiu zrobiłem. :)
    Przykładowo, DS nie przewiduje by EEPE był ustawiony po resecie (a przynajmniej nie znalazłem takiej informacji), a symulator AVR Studio 4 twierdzi że tak jest - dlatego wprowadziłem jego zerowanie podczas odczytu. Nie mam jak sprawdzić czy symulator się myli, czy faktycznie tak się dzieje, więc wolę go na wszelki wypadek zerować zwłaszcza że odczyt EEPROM to pierwsza czynność jaką ma wykonać procesor po włączeniu zasilania.
    Określenie w DS jako X dla mnie oznacza, że stan jest nieokreślony, zabroniony lub nieistotny. We wszystkich DS układów cyfrowych jest to w ten sposób rozumiane.
    Jak pisałem - procedura odczytu pierwotnie wyglądała dokładnie tak jak w DS, ale też układ nie działał prawidłowo, przepatrzyłem dokładnie co się dzieje w symulatorze i wyszło że po resecie EEPE jest ustawiony - dlatego postanowiłem go zerować. Tyle że to niczego nie zmieniło.

    Piotrus_999 napisał:
    Zakładając że z jakiegoś powodu bylby podniesiony to należy poczekać na jego wyzerowanie (ale nie zerować go)

    No tak, ale w tym programie nie ma żadnego powodu dla którego miałby być ustawiony w innym momencie niż w tym w którym ma być ustawiony. A jeśli tak, to znaczy że jego ustawienie wynika z jakiegoś błędu - dlatego go zeruję.

    excray napisał:
    Sprawdziłem Twoje wersje na attiny2313 i działają

    kamyczek napisał:
    Bit eepe wskazuje na zajętość modułu obsługującego eeprom wystarczy więc poczekać na jego zwolnienie inaczej zapis czy odczyt może skończyć się niepowodzeniem . Procedura z noty katalogowej działa poprawnie nie ma co wymyślać i jej zmieniać . Należy się natomiast zapoznać z całą notą bo na jej końcu często umieszczone są uwagi dotyczące nieprawidłowego działania czy też wersji układu . Zdarzało się np. tak że zapis eeprom był prawidłowy jedynie dla vcc=5V . Poza tym musisz zwrócić uwagę że zapis eeprom nie jest zbyt szybki więc lepiej operować na ram i przy bezczynności mikrokontrolera w tle uaktualniać zmienne z ramu do eepromu a przy starcie czytać je i umieszczać w ram .

    Procedura zapisu działa na pewno, można to łatwo sprawdzić co też uczyniłem. Za każdym razem do EEPROM wpisana jest właściwa wartość.
    Zostawmy więc zapis i te nieszczęsne bity EEPE i EEMPE bo nie tutaj leży problem.

    Dziękuję za sprawdzenie procedury odczytu, pozostaje więc pytanie - skoro procedura odczytu działa poprawnie, to dlaczego całość nie działa prawidłowo?
    Tzn. działa prawidłowo tylko raz - gdy zawartość pamięci nie pasuje do żadnej stałej z którą jest porównywana. Wówczas program ustawia wartości początkowe i zaczyna normalnie działać.
    W momencie gdy wyłączę zasilanie i włączę ponownie nie dzieje się nic. Sygnalizacja wybranego wejścia 4052 odbywa się za pomocą diod - nie zapala się żadna dioda, tak jakby nie zostały prawidłowo skonfigurowane rejestry DDRD lub występowały nieprawidłowe stany w rejestrze PORTD. Dopiero gdy nacisnę jakikolwiek przycisk, układ zaczyna działać i będzie działał dopóki go nie wyłączę.

    Zamieszczę schemat układu żeby rozjaśnić ideę działania:
    [ASM] Tiny2313 - Zapis/odczyt wewnętrznej pamięci EEPROM

  • #16 24 Sie 2016 21:42
    Piotrus_999
    Poziom 40  

    Artur k. napisał:
    a symulator AVR Studio 4 twierdzi że tak jest

    Czy Kolega uważa że symulator to to samo co kość? Symulator moze jest i dobry do generalnej logiki programu ale nigdy nie odda w 100% procesora.

    W DS jest napisane ze nie wiadomo jaki jest jego stan, oraz ze jeżeli jest 1 to należy czekać + to że jest zerowany przez sprzęt.

    Artur k. napisał:
    Dopiero gdy nacisnę jakikolwiek przycisk, układ zaczyna działać i będzie działał dopóki go nie wyłączę.

    Uroki pisania w asemblerze, że tak powiem :). To co napisanie w C zajmuje 5 minut w asm często dni bo ciężko sie czyta, analizuje i debuguje.

  • #17 24 Sie 2016 22:03
    Artur k.
    Admin grupy audio

    Piotrus_999 napisał:
    Czy Kolega uważa że symulator to to samo co kość? Symulator moze jest i dobry do generalnej logiki programu ale nigdy nie odda w 100% procesora

    Ja doskonale o tym wiem, nie mniej jednak jeśli symulator coś takiego robi na co by nie mówić dość prostym poziomie, to mam podstawy twierdzić że z jakiegoś powodu procesor też może tak robić.

    Piotrus_999 napisał:
    W DS jest napisane ze nie wiadomo jaki jest jego stan, oraz ze jeżeli jest 1 to należy czekać + to że jest zerowany przez sprzęt.

    W DS jest napisane dokładnie tak:
    Cytat:
    The EEMPE bit determines whether writing EEPE to one will have effect or not.
    When EEMPE is set, setting EEPE within four clock cycles will program the EEPROM at the
    selected address. If EEMPE is zero, setting EEPE will have no effect. When EEMPE has been
    written to one by software, hardware clears the bit to zero after four clock cycles.

    Wynika z tego tylko tyle że EEMPE zostaje automatycznie wyzerowany po 4 taktach.

    oraz tak:
    Cytat:
    The EEPROM Program Enable Signal EEPE is the programming enable signal to the EEPROM.
    When EEPE is written, the EEPROM will be programmed according to the EEPMn bits setting.
    The EEMPE bit must be written to one before a logical one is written to EEPE, otherwise no
    EEPROM write takes place. When the write access time has elapsed, the EEPE bit is cleared by
    hardware. When EEPE has been set, the CPU is halted for two cycles before the next instruction
    is executed.

    Z czego wynika że EEPE zostanie automatycznie wyzerowany jeśli przekroczony zostanie czas dostępu do pamięci czyli najpóźniej po 3.4ms w zależności od trybu pracy pamięci.
    Co do czekania - a jak długo mam czekać? Wartość początkowa bitu EEPE oraz EEMPE jest oznaczona jako X, czyli nieokreślona - może tam być przypadkowy stan. Dla mnie to oczywiste, że jeśli program zaczyna działanie od odczytu pamięci to nie mam na co czekać, tylko sam muszę zadbać o wyzerowanie EEPE.

    Zostawmy jednak te bity EEPE i EEMPE gdyż akurat procedura zapisu działa prawidłowo, i z tego co napisał Kolega excray wynika że procedura odczytu również działa prawidłowo. Zatem nie tu tkwi problem.

    Piotrus_999 napisał:
    Uroki pisania w asemblerze, że tak powiem :). To co napisanie w C zajmuje 5 minut w asm często dni bo ciężko sie czyta, analizuje i debuguje.

    Ale ja uparty jestem i będę pisał w asemblerze. :)

  • #18 24 Sie 2016 22:16
    excray
    Poziom 38  

    W wywołaniach masz odwołania do main3 i main4 których nie ma w kodzie.

    Dodano po 1 [minuty]:

    Artur k. napisał:

    Ale ja uparty jestem i będę pisał w asemblerze. :)

    Też tak miałem. Ale z niechęcią zacząłem pisać w C ze względu na ARMy i teraz nawet nie dotykam się asemblera. Jak wspomniał @Piotrus_999 kod jest dużo czytelniejszy, szybciej się go pisze, a narzut kodu ze względu na C jest nieduży. W C brakuje mi tylko dostępu do flag.

  • #19 24 Sie 2016 22:37
    Piotrus_999
    Poziom 40  

    excray napisał:
    Też tak miałem. Ale z niechęcią zacząłem pisać w C ze względu na ARMy i teraz nawet nie dotykam się asemblera.

    poza wstawkami, nie pisze się na RISC-ach w asemblerze. Te architektury są wręcz stworzone dla optymalizujących kompilatorów.

    Ale nie martw się mamy tu kolegę, który modyfikuje nawet pliki hex z głowy :)

  • #20 24 Sie 2016 22:42
    Artur k.
    Admin grupy audio

    excray napisał:
    W wywołaniach masz odwołania do main3 i main4 których nie ma w kodzie.

    Nie ma gdyż one są prawie identyczne jak te wyżej. Różnica polega na innych zawartościach rejestrów DDRD i PORTD.
    Napisałem o tym w pierwszym poście:
    Artur k. napisał:
    Zamieszczam fragment programu:
    Artur k. napisał:
    W całości program składa się z 4 pętli (zamieściłem tylko dwie, żeby zobrazować jak to ma działać).

    W związku z tym, że te pętle są praktycznie takie same, uznałem że nie ma potrzeby ich zamieszczania żeby zamieszczony kod nie wyszedł długi bo komu by się chciało to analizować w całości, zwłaszcza że program bez procedur obsługi EEPROM działa prawidłowo więc to nie wina brakujących tutaj pętli.

    Cały program działa tak że pierwsza pętla sprawdza stan PIND.1, druga PIND.2, trzecia PIND.3 zaś czwarta PIND.4, każda z nich zmienia zawartość rejestrów DDRD i PORTD w zależności od naciśniętego przycisku.
    Zobacz na schemat - wymyśliłem sobie takie rozwiązanie by każde wyprowadzenie procesora sprawdzało stan klawiszy, a jednocześnie sygnalizowało ten który został naciśnięty. W ten sposób oszczędzam 4 wyprowadzenia procesora. To jest wersja próbna, bo docelowo będę budował przełącznik na 4051, który ma 8 wejść i będę potrzebował 8 przycisków i 8 diod, a do tego 4 wyprowadzenia sterujące samym kluczem. Do tak prostej rzeczy musiałbym użyć dużego ATMega8, a tak - wystarczy mi Tiny2313. :)

    excray napisał:
    Też tak miałem. Ale z niechęcią zacząłem pisać w C ze względu na ARMy i teraz nawet nie dotykam się asemblera.

    Ja generalnie jestem sprzętowcem, od zawsze siedzę w elektronice, a nie w programowaniu. Asemblera rozumiem, bo widzę co się dzieje od początku do końca (tak jakbym miał stertę tranzystorów), jest dla mnie najbardziej logiczny, C czy Bascoma jakoś nie potrafię ogarnąć. Może kiedyś...

    Piotrus_999 napisał:
    poza wstawkami, nie pisze się na RISC-ach w asemblerze. Te architektury są wręcz stworzone dla optymalizujących kompilatorów.

    Ale nawet najlepszy kompilator nie zoptymalizuje bezmyślności programisty. Asembler zmusza do myślenia i właśnie dlatego się uparłem na ten język, a akurat w kwestiach uC jestem dość początkujący. Jak poznam i zrozumiem co się dzieje w procesorze i dlaczego, to może łatwiej mi będzie się przesiąść na język wyższego poziomu.

  • #21 24 Sie 2016 22:44
    kamyczek
    Poziom 33  

    Piotrus_999 napisał:
    Uroki pisania w asemblerze, że tak powiem . To co napisanie w C zajmuje 5 minut w asm często dni bo ciężko sie czyta, analizuje i debuguje.


    Artur k. napisał:
    Ale ja uparty jestem i będę pisał w asemblerze.


    Ja piszę w asemblerze i nie będę pisał o jego urokach czy też braku , to samo zrobię z C. Po prostu jeśli lepiej znasz asemblera to i debugowanie wychodzi łatwiej z asemblera jak piszesz w C i znasz je lepiej debugowanie takiego kodu jest łatwiejsze ocena więc jest oparta o znajomość języka i tak jak w życiu jak znasz dobrze polski i słabo angielski będziesz wolał czytać i pisać po polsku a angielski tekst sprawi więcej problemów i zajmie więcej czasu . Ponieważ zaczynałem od asemblera 51 , przesiadłem się na asemblera avr i mnie nawiasy , klamerki i inne znaczki doprowadzają do białej gorączki poza tym z pliku hex nie za bardzo da się zrobić plik z rozszerzeniem .c za to .asm nie ma problemu . To taka mała dygresja dlaczego w inż. odwrotnej z c się niezbyt da powalczyć ;) . Kody umieszczone w notach zazwyczaj działają i często mają odpowiednik napisany w C czy jest jakiś dłuższy inny tu bym napisał że raczej nie bo plik wynikowy takiego kodu jest taki sam lub bardzo podobny , a sam kod robi to samo w końcu . Zamiast więc zmieniać coś w kodzie zazwyczaj używam kodu z przykładów zmieniając jedynie to co potrzeba .

  • #22 24 Sie 2016 22:46
    Piotrus_999
    Poziom 40  

    Bakom proponuję w pominąć w dalszych studiach.
    C - po prostu nie musisz myśleć czy ten jump zostanie ominiety albo jak wybrac wartość. Po prostu kod zrozumiały dla człowieka, którego mózg pracuje inaczej niż procesor.

  • #23 24 Sie 2016 22:52
    Artur k.
    Admin grupy audio

    kamyczek napisał:
    Po prostu jeśli lepiej znasz asemblera to i debugowanie wychodzi łatwiej z asemblera jak piszesz w C i znasz je lepiej debugowanie takiego kodu jest łatwiejsze ocena więc jest oparta o znajomość języka

    Ja akurat nie znam dobrze ani jednego, ani tym bardziej drugiego. Z tych dwóch wolę asemblera, bo dla mnie jest bardziej zrozumiały niż klamerki i nawiasy w C.
    Czasami jednak coś nie działa i nikt nie wie dlaczego. :)

    Dobra, pogadali my, a czy ktoś ma jakiś pomysł odnośnie omawianego problemu?

  • Pomocny post
    #24 25 Sie 2016 00:43
    excray
    Poziom 38  

    Wrzuć cały kod.

    Dodano po 1 [godziny] 30 [minuty]:

    U Ciebie błąd jest w tym, że po odczycie poprawnego zapisu z EEPROM nie inicjujesz rejestrów PORTD i DDRD, tylko od razu przechodzisz do testowania wejść, przez co porty są nie zainicjowane dopóki nie naciśniesz jakiegoś przycisku. Na dodatek nie odświeżałeś wartości r19 po zapisie nowej wartości do EEPROM. W układzie należy również zadbać o to aby procesor nie grzebał przy EEPROM przy niestabilnym zasilaniu. Oprócz funkcji wait na starcie należy jeszcze odpowiednio ustawić fusebity BOD, aby attiny podczas zaniku napięcia nie próbował zapisywać do EEPROM. I jeszcze jedna drobna uwaga - najpierw zmieniaj wartość PORTD a później rejestr DDRD. Inaczej przez kilka taktów masz zwarcie na pinie. Na bazie Twojego programu napisałem coś takiego co testowałem i działa:

    Kod: avrasm
    Zaloguj się, aby zobaczyć kod

  • #25 25 Sie 2016 08:02
    Artur k.
    Admin grupy audio

    excray napisał:
    U Ciebie błąd jest w tym, że po odczycie poprawnego zapisu z EEPROM nie inicjujesz rejestrów PORTD i DDRD, tylko od razu przechodzisz do testowania wejść, przez co porty są nie zainicjowane dopóki nie naciśniesz jakiegoś przycisku.

    Ha, rzeczywiście. Dopiero jak o tym wspomniałeś to zauważyłem ten ewidentny błąd. Dziękuję.

    Myślę że wystarczy zrobić tak w pętlach:

    Kod: avrasm
    Zaloguj się, aby zobaczyć kod


    i tak w procedurze sprawdzania:

    Kod: avrasm
    Zaloguj się, aby zobaczyć kod


    Co o tym myślisz?

    excray napisał:
    Na dodatek nie odświeżałeś wartości r19 po zapisie nowej wartości do EEPROM.

    Rzeczywiście pasowałoby nie tyle odświeżać zawartość, co w każdej pętli wraz z dokonaniem zapisu do EEPROM kopiować zawartość R16 do R19, gdyż w przeciwnym wypadku każdy obieg pętli będzie powodował zapis do pamięci. O tym nie pomyślałem.

    excray napisał:
    I jeszcze jedna drobna uwaga - najpierw zmieniaj wartość PORTD a później rejestr DDRD. Inaczej przez kilka taktów masz zwarcie na pinie.

    Nie bardzo rozumiem w jaki sposób to zwarcie powstaje.
    Najpierw ustawiam DDRD a potem PORTD gdyż tak mi logika podpowiadała. DDRD to port kierunku, najpierw więc muszę określić kierunek działania portu, a potem wysyłać dane. Zresztą ustawienie stanu na pinie podczas gdy jest on wejściem powoduje włączenie rezystora podciągającego.

    Na razie dziękuję za wskazanie błędów, jak wrócę z pracy to sprawdzę czy działa.

  • Pomocny post
    #26 25 Sie 2016 10:59
    excray
    Poziom 38  

    Artur k. napisał:
    Nie bardzo rozumiem w jaki sposób to zwarcie powstaje.

    Masz konfigurację DDRD = 0b00000001; i PORTD = 0b001110 czyli PD0 się "świeci". Teraz naciskasz na klawisz PD1 i pierwsze co robisz w kodzie to zmieniasz DDRD. Więc masz zwarcie do masy przyciskiem na PD1 i konfigurację DDRD = 0b00000010 i stary PORTD = 0b00001110. Czyli teraz masz silne 1 na wyjściu PD1 które aktualnie jest zwarte przyciskiem PD1 do masy. I taki stan trwa dopóki nie przestawisz PORTD na 0b00001101 czyli kilka cykli. Niby nic, ale skoro można inaczej to czemu nie.

    Dodano po 4 [minuty]:

    Artur k. napisał:
    Myślę że wystarczy zrobić tak w pętlach:

    Wystarczy. Tak zrobiłem w pierwszej testowanej poprawce i działało. Ale skoro znaczna część kodu jest identyczna dla wszystkich funkcji to czemu by jej nie wyciągnąć jako jedną procedurę. Tak samo nie potrzebujesz rcall delay_20m. Tam drgania styków nie mają znaczenia. Te funkcje działają jak zatrzask. Jak raz dotkniesz pinu to on i tak się zatrzaskuje niezależnie czy ten kontakt drga, czy nie.

    Dodano po 3 [minuty]:

    Artur k. napisał:
    Rzeczywiście pasowałoby nie tyle odświeżać zawartość, co w każdej pętli wraz z dokonaniem zapisu do EEPROM kopiować zawartość R16 do R19

    Dokładnie to miałem na myśli.

  • #27 25 Sie 2016 19:02
    Artur k.
    Admin grupy audio

    Ok, kod po zmianach jak wyżej działa. :) Dopiero teraz wezmę się za upraszczanie i optymalizację.
    Tematu na razie nie zamykam.

 Szukaj w ofercie
Zamknij 
Wyszukaj w ofercie 200 tys. produktów TME