Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[Atmega8][BASCOM]Prośba o odchudzenie kodu

stayout 16 Dec 2011 20:03 3927 27
Computer Controls
  • #1
    stayout
    Level 14  
    Witam.
    Zrobiłem sobie mały sterownik do akwarium, którego zadaniem w chwili obecnej jest kontrola oświetlenia (dwie świetlówki i linijka led) i grzałki. Chciałbym upchnąć jeszcze kilka funkcji ale programista ze mnie żaden dlatego też mój kod rozrósł się do 97% pojemności pamięci Atmega8.
    Czy istnieją jakieś prostsze rozwiązania realizowanych funkcji tak by kod zajmował mniej miejsca?
    Kod programu w chwili obecnej (przetestowany na działającym urządzeniu):
    Code: vbnet
    Log in, to see the code
  • Computer Controls
  • Helpful post
    #2
    Szumlus
    Level 17  
    Witam,

    Jeśli nie musisz nie korzystaj ze zmiennych typu single, lepiej przeskalować int'a kilka razy (np zamiast 1,232 robisz 1232 a przy wyświetlaniu dodajesz przecinek) operacje na liczbach zmiennoprzecinkowych zjadają spora flash i czasu procesora.

    Pozdrawiam,
    Marcin
  • #3
    stayout
    Level 14  
    Próbuję zrobić to tak;
    Code: vbnet
    Log in, to see the code

    Ale kompilator przy tym się wykłada;
    (Label not found [_PRINTSDECW ]).
    Co robię nie tak?

    Jeżeli zadeklaruję zmienne I, S jako Byte wszystko jest OK ale wartości odczytu temp. nie zmieszczą się w zmiennej Byte.

    edit

    Zamieniłem bibliotekę $lib "mcsbyte.lbx" na $lib "mcsbyteint.lbx" i program się kompiluje tyle, że zamiast zaoszczędzić miejsca kod spuchł z 97% do 99%.
    Jak to zrobić inaczej?
  • Helpful post
    #4
    SylwekK
    Level 32  
    Można też, gdyby Ci zabrakło kilka bajtów, odzyskać je zamieniając warunki IF...AND... na łączone IF...IF... Taka zamiana czyni program nieco mniej czytelnym ale czasem ratuje skórę :)
  • Helpful post
    #5
    Mundi1970
    Level 24  
    Można trochę bajtów zaoszczędzić :)

    Dodaj bibliotekę obsługującą hardwarowe TWI:

    Code: vbnet
    Log in, to see the code


    Odczyt danych z EEPROMU, zamiast:
    Code: vbnet
    Log in, to see the code


    można tak ;):
    Code: vbnet
    Log in, to see the code


    W liniach 257-274 i 323-351 w każdym Case używasz instrukcji Locate 2,1. Czy nie lepiej będzie umiejscowić instrukcje Locate 2,1 przed Select Case ? :)

    Te instrukcje przy konfiguracji portów wydają mi się niepotrzebne:

    Code: vbnet
    Log in, to see the code


    Zamiast 10 bajtów:

    Code: vbnet
    Log in, to see the code


    mogą być tylko 2 bajty :):

    Code: vbnet
    Log in, to see the code


    W paru miejscach tak sprawdzasz stan portu:

    Code: vbnet
    Log in, to see the code


    Wydaje mi się że krócej będzie tak:

    Code: vbnet
    Log in, to see the code


    Po wprowadzeniu tych zmian masz do dyspozycji około 200 dodatkowych bajtów :D.
  • Computer Controls
  • #6
    stayout
    Level 14  
    Po zastosowaniu większości zmian Mundi1970 wynik kompilacji to 7780B z poprzednich 7942B. Nie zmieniłem jeszcze operacji na eeprom - jakoś nie mogę tego ogarnąć - co z zapisem do eeprom czy w takim przypadku pozostaje bez zmian?

    SylwekK wrote:
    Można też, gdyby Ci zabrakło kilka bajtów, odzyskać je zamieniając warunki IF...AND... na łączone IF...IF...

    Mógłbyś podać przykład takiego zastosowania poleceń?

    Code: vbnet
    Log in, to see the code
  • #7
    Mundi1970
    Level 24  
    Resztę zostawiasz bez zmian, chodzi tylko o zastąpienie tych 12 readeeprom. Trzeba dopisać 2 zmienne i readeeprom w pętli. Przetestuj a uzyskasz jeszcze parę bajtów :)

    EDIT:

    Małe narzędzie testujące ;) do sprawdzania długości kawałka kodu. W odpowiednie miejsce wstawiasz zmienne, kod i uruchamiasz w symulatorze:

    Code: vbnet
    Log in, to see the code


    Readeeprom w pętli zajmuje 60 bajtów, a dwanaście Readeeprom jeden za drugim zajmują 144 bajty :).
  • #8
    stayout
    Level 14  
    Operacje na eeprom poprawione. Wynik; 7706B. Czy można przenieść znaki specjalne [Chr] do pamięci eeprom?
  • Helpful post
    #9
    SylwekK
    Level 32  
    Np. ta linia:

    Code: vbnet
    Log in, to see the code


    wyglądała by tak:

    Code: vbnet
    Log in, to see the code


    i w tym konkretnym przypadku nie będzie żadnych problemów. Gorzej by było jeśli w lini występowały by jeszcze inne operatory wtedy nici z rozpiski...

    A jak już szczypiemy się o każdy bajt to zastąp For..Next przez Do..Loop i inkrementuj zmienną ręcznie... znowu kila bajtów do przodu :)
  • #10
    stayout
    Level 14  
    "Sztuczka" z IF podziałała. Wynik;7610B.
    Czy tak będzie poprawnie?;

    Code: vbnet
    Log in, to see the code
  • Helpful post
    #12
    Mundi1970
    Level 24  
    Trzeba przed Do ... Loop dopisać Licznik=1, i wtedy pętla zajmuje 58 bajtów zamiast 60 jak For ... Next :)
  • #13
    Jaca
    Level 31  
    Zamiast "bawić się" z Readeeprom można to zrobić tak:

    Code: vbnet
    Log in, to see the code


    Trzeba tylko pamiętać, aby przed użyciem zmiennej umieszczonej w EEPROMie, skopiować ją do zmiennej umieszczonej w RAMie.
  • #14
    stayout
    Level 14  
    Chciałbym jeszcze przenieść znaki specjalne do eeprom.
    Próbowałem takiego kodu;
    Code: vbnet
    Log in, to see the code


    Co w całości wygląda tak;
    Code: vbnet
    Log in, to see the code


    ...ale zamiast znaków specjalnych na wyświetlaczu mam czarne prostokąty.
    Popełniłem gdzieś błąd i nie mogę go zlokalizować. Może jest prostsza metoda na przeniesienie znaków specjalnych definiowanych przez deflcdchar?
  • Helpful post
    #15
    Mundi1970
    Level 24  
    Wydaje mi się że nie opłaca się ładować tych 32 bajtów do eepromu , pewnie procedura odczytująca zajmie więcej miejsca. Ale :) można by tam coś innego władować, w eepromie masz coś około 500 bajtów wolnych. Wolne miejsce można by wykorzystać na teksty wyświetlane na LCD. Niektóre łańcuchy też się powtarzają. Często masz np .

    Code: vbnet
    Log in, to see the code


    Można by to troszkę inaczej rozwiązać, cześć tekstów można by dać do eeprom np.:

    Code: vbnet
    Log in, to see the code


    i dodać podprogram wyświetlający stringi z eepromu:

    Code: vbnet
    Log in, to see the code


    Troszkę nie wygodnie będzie rozpisać stałe z adresami łańcuchów, ale można napisać sobie programik w Bascomie żeby na podstawie danych z eppromu wygenerował adresy. Wiem niektórzy powiedzą żeby stworzyć tablice z adresami do łańcuchów lub używać Loadlabel, ale teraz chodzi o oszczędność miejsca :).

    Jeszcze jedna rzecz po, Writeeeprom sprawdzasz bit w rejestrze:

    Code: vbnet
    Log in, to see the code


    Nie musisz tego robić, bo to jest zawarte w procedurze Writeeeprom. No chyba że jakaś starsza wersja Bascoma tego nie sprawdzała.
  • Helpful post
    #16
    Fredy
    Level 27  
    Te wszystkie sztuczki pozwolą ci zaoszczędzić parę bajtów , ale największe oszczędności przyniesie ci rezygnacja z liczb zmienno przecinkowych. Tu oszczędności będą na poziomie kilkudziesięciu procent , więc jest o co walczyć. Tymabardziej że napewno to się da zrobić i nie jest to takie trudne.
    Przecież zamiast operować na liczbie np 13,45 możesz sztucznie operować na 1345, a dopiero w momencie wyświetlenia jej , zamienić ją na dwie liczby, jedna przed , druga po przecinku. Wyświetlanie zrobić jako dwuetapowe, w środku dopisać przecinek.
    To naprawdę trywialna operacja a korzyści będą w tym przykładzie ogromne.
  • Helpful post
    #17
    SylwekK
    Level 32  
    Dokładnie tak jak mówi Fredy - kiedyś w jednym z projektów na Atmega8 miałem już praktycznie całą pamięć zajętą i po przejściu tylko na liczby całkowite zyskałem ponad 0,5kb
  • #18
    stayout
    Level 14  
    Mundi1970 wrote:

    Można by to troszkę inaczej rozwiązać, cześć tekstów można by dać do eeprom


    Czy tak to ma wyglądać?;

    Code: vbnet
    Log in, to see the code


    Zaoszczędziłem 32bajty.

    Fredy wrote:

    Te wszystkie sztuczki pozwolą ci zaoszczędzić parę bajtów , ale największe oszczędności przyniesie ci rezygnacja z liczb zmiennoprzecinkowych.

    Próbowałem ale nie wiem jak to zrobić w tym konkretnym programie. Chyba za głupi jestem na to.
  • Helpful post
    #19
    Mundi1970
    Level 24  
    stayout wrote:
    Zaoszczędziłem 32bajty.

    A teksty z lini: 45, 47, 304, 373, 477, 517, 519, 566, 568, 614, 616, 663, 665, 713, 715, 761, 763, 798 dlaczego nie są w Eepromie :)? Możesz wykasować spacje w łańcuchach i zmodyfikować początek Display_msg.

    Code: vbnet
    Log in, to see the code



    Fredy wrote:
    Te wszystkie sztuczki pozwolą ci zaoszczędzić parę bajtów , ale największe oszczędności przyniesie ci rezygnacja z liczb zmiennoprzecinkowych.
    stayout wrote:
    Próbowałem ale nie wiem jak to zrobić w tym konkretnym programie. Chyba za głupi jestem na to.


    W swoim programie 2 razy wykonujesz dzielenie na zmiennej typu Single, a następnie formatujesz łańcuch funkcją Fusing. Można to zrobić inaczej, zmienną S i Z należy zamienić na Long i przed dzieleniem dane z termometru pomnożyć przez 10 lub 100 (w zależności czy chcesz mieć 1 lub 2 cyfry po przecinku). Dzielenie przez 16, można zastąpić przesunięciem o 4 bity w prawo. Wynik zostaje zamieniony na łańcuch i odpowiednio sformatowany.

    Code: vbnet
    Log in, to see the code
  • #20
    stayout
    Level 14  
    Kod po zmianach-przeniesienie napisów do eeprom;
    Code: vbnet
    Log in, to see the code


    Próba zmiany sposobu przeliczania temperatury w zaproponowany sposób wymusza zmianę biblioteki msclib.lbx na msc.lbx co przyczynia się do "puchnięcia" kodu. Można to jakoś ominąć?

    EDIT:
    OK. Poradziłem sobie z tym. Zamieniłem Long na Integer (powinno wystarczyć na dane z ds18b20) i zastosowałem bibliotekę mscbyteint.lbx.
    Kod po zmianach;
    Code: vbnet
    Log in, to see the code

    ...i zaskakujący wynik!!! - 6812B :)
    Muszę tylko sprawdzić kod w docelowym urządzeniu po tych zmianach bo symulacja nie trawi ds1307.
  • #21
    Mundi1970
    Level 24  
    stayout wrote:

    Muszę tylko sprawdzić kod w docelowym urządzeniu po tych zmianach bo symulacja nie trawi ds1307.

    Tylko wyciągnij rybki z akwarium ;).
  • #22
    stayout
    Level 14  
    W urządzeniu docelowym próba wejścia do menu kończy się resetem lub po unieruchomieniu watchdoga - zawieszeniem programu.
    Wydaje się że coś jest nie tak z podprogramem wyświetlającym łańcuchy na lcd.
    Tylko co?

    Code: vbnet
    Log in, to see the code
  • #23
    Mundi1970
    Level 24  
    Pierwsza rzecz sprawdź czy masz wgrane dane do eeproma, druga ustaw stosy na początku programu np:

    Code: vbnet
    Log in, to see the code


    EDIT:

    Błąd. Co robi ten kawałek w Display_msg :) ? Wykasować:

    Code: vbnet
    Log in, to see the code
  • #24
    stayout
    Level 14  
    Ech, chyba zmęczenie daje się we znaki. EEprom był pusty. Teraz wszystko chodzi ale napisy wyglądają jakby pływały. Czy da się coś z tym zrobić?
    Jeśli chodzi o stosy to ciemna masa jestem - ustawiam tak jak Podałeś.
    Quote:
    Błąd. Co robi ten kawałek w Display_msg Smile ? Wykasować:

    Tego kawałka tam nie ma, wkradł się na listing przy kopiowaniu :)
    EDIT:
    Mruganie, pływanie itp. wyświetlanego tekstu powoduje ten kawałek kodu:
    Code: vbnet
    Log in, to see the code

    Tak ustawiony - na linii 2,1 mrugania brak. Chyba czekają mnie zmiany tablic w eepromie.
  • #25
    Mundi1970
    Level 24  
    stayout wrote:
    Teraz wszystko chodzi ale napisy wyglądają jakby pływały. Czy da się coś z tym zrobić?

    Nie rozumiem, może zamieścisz jakieś zdjęcie.

    EDIT:
    A teraz rozumiem :)
  • #26
    SylwekK
    Level 32  
    Z tym pływaniem to pewnie chodzi, że spacje naprzemiennie wyświetlają się z tekstem i stąd ten efekt. Miałem kiedyś podobnie jak źle wyliczyłem pozycję nowego tekstu i się to jakoś nakładało w pętli.
  • #27
    r3w4rd
    Level 15  
    Zwróciłem uwagę, że często powtarzasz pętle "if prawo = 0", "if lewo = 0", "if wyjdz = 0" z tym samym warunkiem:
    można by od razu dać, np:

    Code: vbnet
    Log in, to see the code
  • #28
    stayout
    Level 14  
    Takie powtarzanie ma na celu eliminację drgań styków a co za tym idzie niechcianych przypadkowych uruchomień.