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

[bascom] atmega 8 problem ze przejsciem w menu

wildchicken 27 Lis 2008 18:39 4435 11
  • #1 5790471
    wildchicken
    Poziom 11  
    Witam mam taki problem mianowicie napis na lcd mi mruga zamiast sie wyświetlać stale dróga zecz ni umiem przejśc do nastepnego menu załączam nizej kod programu i co robie nie tak



    Cytat:



    $regfile = "m8def.dat"

    $crystal = 8000000




    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portc.5 , Rs = Portc.4

    Config Pind.0 = Input
    Config Pind.1 = Input


    Menu1:
    Cls
    Do
    Lcd "MENU 1"
    If Pind.0 = 1 Then
    Gosub Menu2
    Waitms 5
    End If
    Loop
    End


    Menu2:
    Cls
    Do
    Lcd "MENU2"
    If Pind.1 = 0 Then
    Gosub Menu1
    Waitms 5
    End If
    Loop
    End

    Proszę poprawić treść wiadomości - regulamin p.15
    Proszę poprawić tytuł wiadomości - regulamin p.11.1
    [zumek]
  • #2 5790659
    Maciek4141
    Poziom 22  
    Witam
    Po pierwsze podprogram (sub) musi być zdeklarowany "Declare Sub Menu1".
    Następne nie piszesz Menu1: tylko Sub Menu1:.
    Jeżeli chodzi o menu ja osobiście robię tak:
    
    Do
    
    If pind.1=1 then
    Gosub Menu1
    End if
    
    If pind.2=1 then
    Gosub Menu2
    
    Loop
    End
    
    
    Sub Menu1:
    PROGRAM DO WYKONANIA
    End Sub
    
    
    Sub menu2:
    PROGRAM DO WYKONANIA
    End sub
    
    
    


    Robiłem kedyś identycznie jak ty i po pewnym czasie stos pamięci podprogramów się zapełnia i uC się resetuje.

    Pozdrawiam Maciek
  • #3 5790716
    wildchicken
    Poziom 11  
    Zrobiłem tak i dalej mi same przeskakuje za test 1 na test2


    Cytat:
    $regfile = "m8def.dat"

    $crystal = 8000000




    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portc.0 , Db5 = Portc.1 , Db6 = Portc.2 , Db7 = Portc.3 , E = Portc.5 , Rs = Portc.4







    Declare Sub Menu1
    Declare Sub Menu2



    Config Pind.0 = Input
    Config Pind.1 = Input

    Cursor Off
    Do

    If Pind.0 = 1 Then
    Gosub Menu1
    End if

    If Pind.1 = 1 Then
    Gosub Menu2
    End If
    Loop
    End


    Sub Menu1:
    Locate 1 , 1 : Lcd "test1"
    End Sub


    Sub menu2:
    Locate 1 , 1 : Lcd "test2"
    End Sub

  • #4 5790969
    bogdan_p
    Poziom 39  
    zmień sposób wykrywania stanu z wysokiego na niski , podciągając piny portu przyciski do masy

    
    ..........
    Config Pind.0 = Input
    Config Pind.1 = Input 
    Portd = &B00000011
    
    If Pind.0 = 0 Then
    Gosub Menu1
    End if 
    ...........
    
  • #5 5792495
    mirley
    Poziom 17  
    Witam

    Ja osobiście zrobił bym to porządnie czyli z urzyciem przerwań, bez żadnych podprogramow, korzystając z etykiet. Ponizej przedstawiam przykladowy kod. Mogą być w nim literowki gdyż pisałem prosto z palca bez kompilacji:

    
    '************* Konfiguracja uC *****************
    '***********************************************
    $regfile = "m8def.dat"
    $crystal = 16000000
    Config Portb = &B11111111 : Portb = &B11111111
    Config Portc = &B11111111 : Portc = &B11111111
    Config Portd = &B11111100 : Portd = &B11111111
    
    
    Config Lcdpin = Pin , Db4 = Porta.5 , Db5 = Porta.4 , Db6 = Porta.3 , Db7 = Porta.2 , E = Porta.0 , Rs = Porta.1       'tu zmien na odpowiednie piny
    Config Lcd = 16 * 2
    Cls
    Cursor Off Noblink
    
    Config Timer0 = Timer , Prescale = 256
    Enable Timer0 : On Timer0 Prztimer0
    
    Enable Interrupts
    '********** Konfiguracja uC Koniec  ************
    
    '******************  Zmienne *******************
    '***********************************************
    Dim Flaga_4ms as bit
    Dim Licz_sw(2) as byte
    Dim Poz_menu as byte
    '*************  Zmienne Koniec  ****************
    
    '************ Warunki Poczatkowe ***************
    '***********************************************
    Poz_menu = 0
    Gosub wyswietl
    '*******  Warunki Poczatkowe Koniec  ***********
    
    '**************  Petla glowna ******************
    '***********************************************
    Do
    
     if Flaga_4ms =  1 then 'co 4ms wykonywane
       Flaga_4ms = 0
       
       if pind.0 = 0 then 
        incr Licz_sw(1)
        if licz_sw(1) = 50 then
          Licz_sw(1) = 0
          'akcja przycisku
          Poz_menu = 1 
          gosub Wyswietl
        end if 
       else
         Licz_sw(1) = 46
       end if 
    
       if pind.1 = 0 then 
        incr Licz_sw(2)
        if licz_sw(2) = 50 then
          Licz_sw(2) = 0
          'akcja przycisku
          Poz_menu = 2 
          gosub Wyswietl
        end if 
       else
         Licz_sw(2) = 46
       end if 
    
     end if
    
    Loop
    End
    '************ Petla glowna Koniec **************
    
    '************ Przerwanie timer 0 ***************
    '***********************************************
    Prztimer0:
      Timer0 = 5
      Set Flaga_4ms
    Return
    '******** Przerwanie timer 0 Koniec ************
    
    Wyswietl:
      Cls
      Select case Poz_menu
        Case 0:
          Lcd "tekst powitalny"
        Case 1:
          Lcd "Napis menu 1"
        Case 2:
          Lcd "Napis menu 2"
      End select
    Return
    
    
  • #6 5799444
    Roko
    Poziom 11  
    Cześć.
    Pięć groszy z mojej strony a mianowicie. Nadmierne używanie w programie Bascom instrukcji podprogramów SUB prowadzi nieuchronnie do nadbudowy stosu z, którym Bascom sobie nie radzi. Instrukcji podprogramów SUB najlepiej używać tylko z konieczności i przejrzystości kodu. Ja osbiście się wyleczyłem z SUB w pewnym projekcie wykorzystującym wyświetlacz graficzny z rozbudowanym menu. Po różnych kombinacjach z przydzielaniem stosu, które nic nie dały program
    nadal się wykrzaczał. Pozbyłem się więc wielu SUB na rzecz GOSUB-RETURN, a nawet brzydkich GOTO.
    Ja w menu zawsze wstrzymuje stan PINU np:
    
    If Ustaw = 0 Then        ' jeżeli naciśnięty
       Bitwait Ustaw , Set    ' wstrzymanie aż puszczę klawisz
    ' coś tam po puszczuniu np. skok lub wykonanie czegoś
    end if
    

    Używam przerwań opóźnających tylko wtedy gdy mam kilka linii menu 8-10 i trzeba uzyskać płynne jego przewijanie chociaż można i z tego zrezygnować na rzecz Waitms, bo oprócz przewijania program raczej nie robi nic więcej.
    To takie moje spostrzeżenia.
    Dzięki.
    Roko
  • #7 5799801
    ZbeeGin
    Poziom 39  
    Roko napisał:
    Nadmierne używanie w programie Bascom instrukcji podprogramów SUB prowadzi nieuchronnie do nadbudowy stosu z, którym Bascom sobie nie radzi.

    Przykro mi to mówić, ale to programiści - w 90% - sobie nie radzą z właściwym obliczeniem (a nie podaniem na oko) rozmiaru stosu. Wystarczy przecież policzyć ile razy suby się zagłębią (HWStack), ile odłożą parametrów na SWStack i czy skorzystają w tym czasie z ramki.
    Jeśli już piszecie program, to piszcie go świadomie.

    :arrow: http://zbeegin.republika.pl/bashelp/bascom_heaps.html (tymczasowo nie działa)
  • #8 5801033
    Roko
    Poziom 11  
    Cześć.
    Tak oczywiście tylko zajmuje to trochę czasu i nie do końca się sprawdza.
    Takie oto pytanie dla przykładu:
    Co zrobić jeżeli procedurę wywołujemy z procedury np. w wielostopniowym menu, które jest też procedurą. Mamy ograniczyć użytkownikowi ilość wywołań, trochę nie ładnie. Lepszym chyba rozwiązaniem jest rezygnacja z takiej sytuacji na rzecz skou do podprogramu i powrót bo w tym przypadku stos nie jest nadpisywany.
    Z tym stosem to kiedyś wszedłem w maliny i za chiny nie mogłem sobie z tym poradzić. Od czasu kiedy nie szaleje z SUB nie mam problemu ze stosem.
    Napisałem ostatnio programik, który obsługuje wyświetlacz gtaficzny na 0108 z rozbudowanym menu, animacją i innymi bardziej i mniej ważnymi rzeczami z następującymi ustawieniami:

    
    $hwstack = 32
    $swstack = 16
    $framesize = 32
    

    Gdzie w przykładach obsługi wyświetlaczy graficznych spotkałem wartości dla $framesize = 100 i więcej.
    Z wypowiedzi na forum można wyczytać o problemach Bascom a stos.
    Trochę przy tym spędziłem czasu i do końca nie mam pewności, że dobrze policzyłem i na wszelki wypadek sprawdzam w ten sposób, że ustawiam trochę mniej i po trochę zwiększam do momentu kiedy jest dobrze, a następnie robię mały zapas.
    Ale to raczej nie w tym temacie.
    Przepraszam że zaśmiecam.
    Roko.
  • #9 5801924
    ZbeeGin
    Poziom 39  
    Roko napisał:
    Takie oto pytanie dla przykładu:
    Co zrobić jeżeli procedurę wywołujemy z procedury np. w wielostopniowym menu, które jest też procedurą. Mamy ograniczyć użytkownikowi ilość wywołań, trochę nie ładnie. Lepszym chyba rozwiązaniem jest rezygnacja z takiej sytuacji na rzecz skou do podprogramu i powrót bo w tym przypadku stos nie jest nadpisywany.

    Tym sposobem prawie nic nie zmienisz w dalszym ciągu będzie rósł HWStack. Jedyne co, to pozbędziesz się odkładania na SWStack adresów parametrów SUB-ów. Przy procedurach bezparametrowych nic się wtedy nie zmieni.

    Roko napisał:
    Napisałem ostatnio programik, który obsługuje wyświetlacz gtaficzny na 0108 z rozbudowanym menu, animacją i innymi bardziej i mniej ważnymi rzeczami z następującymi ustawieniami:
    
    $hwstack = 32
    $swstack = 16
    $framesize = 32
    

    Nic dziwnego. Mogłeś bez problemu zagłębić się na około 10 poziomów z podprogramami/SUBami bezparametrowymi. Ale wystarczyłoby jedno aktywne przerwanie bez NoSave i ta ilość by stopniała do... ok. 3.

    Roko napisał:
    Gdzie w przykładach obsługi wyświetlaczy graficznych spotkałem wartości dla $framesize = 100 i więcej.

    Jak ktoś chce do każdego SUBa przekazywać sensownie parametry z klauzulą ByVal - nie dotyczy tablic - to prawie jak znalazł.

    Roko napisał:
    Z wypowiedzi na forum można wyczytać o problemach Bascom a stos.

    A ja powtórzę ponownie: to użytkownicy z własnej niewiedzy mają problem. Popatrz na kody powyżej. Kto był taki mądry i wszytkim powiedział, że przez GOSUB się wskakuje do SUB? W helpie pisze wyraźnie jak poprawnie wywoływać procedury i jak je opuszczać warunkowo.
  • #10 5804688
    Roko
    Poziom 11  
    Witam.
    ZbeeGin masz rację. Czytałem sporo twoich postów, bo Twój nik przewija się bardzo często przez forum i można powiedzieć, że w temacie jesteś GURU. W temacie stosu w Bascom poruszam się jak w ciemnym pomieszczeniu i wiem, że na ten problem natrafi w końcu, każdy kto będzie chciał napisać coś większego pod Bascomem.
    Wiem, że ten temat był poruszany wielokrotnie, ale były to informacje szczątkowe i nieusystematyzowane nie tyczące całości zagadnienia.
    W związku z tym mam prośbę czy Możesz założyć temat w którym naświetliłbyś sprawę najczęściej popełnianych błędów przez piszących w Bascomie. Chodzi mi właśnie o bezpieczne używanie procedur, skoków warunkowych co odkłada się na stosie ogólnie jak z tym sobie radzić.
    Wiem, że w każdym języku programowania są zasady i reguły oraz kultura pisania. Z doświadczenia wiem, że zasady i reguły można gwałcić i robi to połowa ludzi, którzy piszą coś pod Bascom'em. Bascom to takie fajne zwierzątko, które trochę przymyka oko na wiele błędów składni programu i program też działa, ale nie do końca jest prawidłowy. Nie dysponuję żadnym przykładem tak z rękawa bo nie o to chodzi. Bawiłem się kiedyś fragmentem programu na kilkadziesiąt sposobów i program po kompilacji ważył więcej lub mniej i zawsze działał wolniej lub szybciej, lepiej lub gorzej. Jest to bardzo elastyczny język o ogromnych możliwościach i program napisamy prawidłowo działa wyśmienicie. Podstawowa zaleta to czas potrzebny na napisanie czegoś działającego.
    Przywołując ś.p. P. Rabe (chyba inaczej się to pisze) jego lekcje i opisy oraz przykłady były fajne tylko brakowało nacisku właśnie na reguły i zasady budowy programów. Trzeba było je wyłapywać samemu z artykułów. Fajnie by było gdybyś Ty lub ktoś kto dobrze się czuje w temacie Bascom te rzeczy naświetlił.

    Za pierwszym razem nie dostałem, że nie w temacie może i teraz się uda.
    Jeszcze raz przepraszam autora tematu, że nie w temacie, ale trafiła się okazja poruszenia tematu STOSU i innych.
    Roko.
  • #11 5809599
    ZbeeGin
    Poziom 39  
    Kol. Roko. Częściowo takie rzeczy pojawiły się już w polskiej pomocy do BASCOM-a On-Line. Obecnie jest jednak ona czasowo niedostępna. Przykład:
    Cytat:
    BASCOM AVR - Tworzenie programu
    W trakcie edycji
    (...)
    Jak nie pisać programów.

    Dość często podczas przeglądania programów udostępnionych przez inne osoby da się zauważyć pewne charakterystyczne i powtarzane wielokrotnie błędy. Poniższa lista powstała właśnie na podstawie takich obserwacji.

    - Trzeba zawsze dbać o styl w pisanym programie. Poprawność stylistyczną zapewnią wcięcia, które oddzielają wykonywane bloki w progamach. Wcięcia stosujemy zwykle w pętlach (FOR..NEXT, DO..LOOP, WHILE..WEND), instrukcjach warunkowych (IF..THEN..END IF, SELECT..CASE), procedurach i funkcjach (SUB..END SUB, FUNCTION..END FUNCTION), przerwaniach i podprogramach rozpoczynających się etykietą (etykieta:..RETURN), blokach ze wstawkami w kodzie maszynowym ($ASM..$END ASM).
    - Zawsze należy pamiętać o komentarzach. Pisanie programu bez nich jest przyczyną poźniejszych kłopotów ze zrozumieniem jak działa program, a jak działać powinien. Zwłaszcza, gdy praca nad pisaniem programu zostanie ostawiona na jakiś dłuższy czas.
    - Wszystkie deklaracje: m.in. użytego procesora, częstotliwość kwarcu, ustawienia stosów; które są ustawiane w opcjach kompilatora, a posiadają swoje odpowiedniki w dyrektywach kompilatora, należy ustawiać za pomocą tych dyrektyw. Ustawienia w opcjach kompilatora są zapisywane w plikach *.CFG, które to często są pomijane przy przenoszeniu programu lub prezentowaniu go w sieci Internet lub w czasopismach. Brak tych ustawień może uniemożliwić późniejszą poprawną kompilację programu przez inne osoby.
    - Jednym z poważnych błędów jest wykorzystywanie instrukcji GOSUB do wywoływania procedur użytkownika SUB..END SUB. Przy procedurach bezparametrowych kompilator nie zgłasza błędu, ale jest to dalej wywołanie niezgodne z zasadami. Do wywoływania tych procedur służy instrukcja CALL.
    - Należy w jak najmniejszym stopniu korzystać z polecenia GOTO. Co prawda nie jest ono całkowicie zakazane, ale powoduje, iż logiczny ciąg programu jest zakłócany poprzez skoki to tu, to tam. Późniejsza analiza takiego programu jest dość kłopotliwa.
    - Stosowanie ciągu następujących po sobie instrukcji CONFIG PINx.y = INPUT/OUTPUT, czy SET/RESET wydłuża program. Warto zatem zainteresować się alternatywnym (z maską bitową) sposobem konfiguracji portu przez CONFIG PORT, oraz z operatorami logicznymi AND, OR, XOR.
    - Przy wykorzystywaniu przerwań, najpierw należy dokonać niezbędnych konfiguracji za pomocą poleceń z gałęzi CONFIG.., a potem dopiero włączać poszczególne przerwania za pomocą ENABLE i na końcu cały system przerwań poprzez ENABLE INTERRUPTS. W takiej kolejności jest mniej prawdopodobne przypadkowe zgłoszenie przerwania podczas zmian ustawień.
    - Procedury osbługi przerwań mają być jak najkrótsze. Wykonywanie w nich poleceń LCD, PRINT, WAIT; stosowanie pętli czy obliczeń na liczbach SINGLE/DOUBLE jest wysoce niepoprawne.
    - Do odmierzania określonych odcinków czasu, których dokładność ma znaczenie w programie należy skorzystać z układów licznikowych TIMER0/1/2, o ile nie są one wykorzystywane przez specyficzne instrukcje. Do cyklicznego odliczania odcinków czasu i przerwań z tym związanych najlepiej skorzystać z dodatkowej opcji CLEAR TIMER=, która wyeliminuje poślizg czasowy pomiędzy zgłoszeniem przerwania a wpisaniem ponownie wartości zliczanych impulsów do licznika.
    - Linie z zapisanymi danymi w programie - instrukcją DATA umieszcza się zawsze na końcu programu. Wyjątkiem są dane jakie są zawarte pomiędzy $EEPROM.. $DATA, które trafią podczas programowania procesora do pamięci EEPROM, a nie do pamięci programu.

    Najczęstsze błędy początkujących.

    Pierwszym najczęstszym błędem jest brak zrozumienia mechanizmu działania portów procesora, które w rodzinie AVR są traktowane nieco inaczej. Dlatego też wielu początkujących podczas próby odczytu stanu jakiegoś portu odwołuje się do zmiennej PORTx. Jest to błędem gdyż PORTx przedstawia zawartość rejestru wyjściowego danego portu, a nie stanu jego wejść. Nie można zagwarantować, że to co zostało zapisane w PORTx pojawi się na wejściu - dana linia może przecież być wysterowana innym stanem z zewnętrznego urządzenia. Dlatego też, aby odczytać stan wejść należy obowiązkowo użyć zmiennej PINx, która odzwierciedla bezpośrednio stan końcówki procesora.

    Drugim najczęstszym błędem jest źle zdefiniowane taktowanie procesora. Wszystkie obecnie produkowane procesory z rodziny AVR mają domyślnie włączony wewnętrzny generator RC, który taktuje procesor z częstotliwością 1MHz. Dlatego tez jeśli program nie działa poprawnie (czasy są dłuższe) należy: albo skorygować wartość w dyrektywie $CRYSTAL na 1000000 (domyślne taktowanie w Hz), albo przestawić w fuse-bitach odpowiednie opcje by procesor był taktowany zgodnie z zapisaną wartością w $CRYSTAL.

    Kolejnym dość często widzianym błędem jest warunkowe wyskakiwanie z procedur SUB lub funkcji FUNCTION nie za pomocą polecenia EXIT SUB lub EXIT FUNCTION ale przez GOTO. Takie postępowanie powoduje przepełnianie się stosów - zwłaszcza sprzętowego HWStack i w konsekwencji zawieszeniem się programu (z reguły występujące po czasie).
    (...)


    Koniec off-topa.
  • #12 5811523
    Roko
    Poziom 11  
    Cześć.
    Dzięki ZbeeGin poczekam na polską pomoc do BASCOM-a On-Line.
    Dzięki, że jest tam trochę o zasadach pisania w Bascom.
    Pozdrawiam
    Roko.
REKLAMA