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

Dziwne wariowanie ATMEGA8. Błądzenie w programie.

06 Kwi 2007 11:08 1431 6
  • Poziom 20  
    Witam.

    Mam straszny problem z ATMEGA8 (zresztą podobne rzeczy działy się w ATMEGA16).

    Mianowicie, robię sobie prosty sterownik. Posiada on m.in. 4 przyciski, zrobione w ten sposób, że są one z jednej strony podłączone do wejść PIND.0 – PIND.3. Wejścia te podłączyłem również przez rezystory 4,7k do masy, oraz równolegle do tych rezystorów dałem kondensatory 100nF. Z drugiej strony przycisków znajduje się plus zasilania (5V).

    Gdy wchodzę do funkcji fun1, przyciskami PIND.1 i PIND.2 zmieniam wartość zmiennej minopal. I tutaj występuje co jakiś czas problem. Mianowicie, podczas przyciskania tych przycisków czasem program wariuje i wskakuje do funkcji fun0. W innym programie, powodowało to całkowite wariowanie programu, włącznie z atrakcjami na wyświetlaczu (krzaki itp.).

    Co może być tego powodem? To jest jakieś chore! Siedzę nad tym już kilkanaście godzin, czytam pdf’y itp.

    Poniżej zamieszcza kod źródłowy.

    Z góry bardzo dziękuję za pomoc.

    Code:

    $dbg
    $regfile = "m8def.dat"
    $crystal = 8000000

    Disable Int0
    Disable Int1
    Reset Ucr.3
    Reset Ucr.4

    Config Portd = Input
    Portd = &B00000000

    'timer zegara
    Config Timer1 = Timer , Prescale = 256                      'timer zagara
    On Ovf1 Zegar
    Load Timer1 , 31250

    Enable Interrupts

    Config Lcd = 16 * 2
    Cursor Off

    Dim Sekunda As Integer
    Dim Minuta As Integer

    Dim Minopal As Integer At 202

    Dim X As Integer
    Dim Jakiknefel As Integer
    Dim Nrfun As Integer At 200

    Declare Sub Beep(byval Dlugosc As Integer)
    Declare Sub Knefel
    Declare Sub Fun0                                            'oczekiwanie na seans lub na parametry
    Declare Sub Fun1                                            'nastawa czasu opalania

    Cls
    Sekunda = 0
    Enable Timer1
    Stop Timer1

    Nrfun = 0

    'ustawienia poczatkowe
    Minopal = 10

    Poczatek:
    Do
    Knefel

    If Nrfun = 0 Then Fun0
    If Nrfun = 1 Then Fun1

    Waitms 100
    Loop
    Return

    Sub Beep(dlugosc As Integer)
       Set Portb.0
       For X = 1 To Dlugosc
          Waitms 50
       Next X
       Reset Portb.0
    End Sub

    Zegar:
    Load Timer1 , 31250
    Incr Sekunda
    If Sekunda > 59 Then
                      Incr Minuta
                      Sekunda = 0
                    End If
    Return

    Sub Knefel
    If Pind.0 = 1 Then
                      Waitms 50
                      If Pind.0 = 1 Then
                                        Jakiknefel = 1
                                        Call Beep(1)
                                    End If
                  End If

    If Pind.1 = 1 Then
                      Waitms 50
                      If Pind.1 = 1 Then
                                        Jakiknefel = 2
                                        Call Beep(1)
                                    End If
                  End If

    If Pind.2 = 1 Then
                      Waitms 50
                      If Pind.2 = 1 Then
                                        Jakiknefel = 3
                                        Call Beep(1)
                                    End If
                  End If
    If Pind.3 = 1 Then
                      Waitms 50
                      If Pind.3 = 1 Then
                                        Jakiknefel = 4
                                        Call Beep(1)
                                    End If
                  End If

    End Sub

    Sub Fun0                                                    'oczekiwanie na seans lub na parametry
    Cls
    Lcd "    Solarium"
    Lowerline
    Lcd "     WOLNE"
    Do
    Knefel
    If Jakiknefel = 2 Then Nrfun = 1                            'funkcja nastawa czasu opalania
    If Jakiknefel = 1 Then Nrfun = 10                           'parametry
    If Nrfun <> 0 Then Goto Poczatek
    Waitms 100
    Loop
    End Sub

    Sub Fun1
    Cls
    Do
    Jakiknefel = 0
    Home
    Lcd "Ustaw czas"
    Lowerline
    Lcd "     " ; Minopal ; "min"
    Knefel
    If Jakiknefel = 3 Then Incr Minopal
    If Jakiknefel = 4 Then Decr Minopal
    If Minopal < 1 Then Minopal = 1
    If Minopal > 60 Then Minopal = 60
    If Jakiknefel = 2 Then Nrfun = 2
    If Jakiknefel = 1 Then Nrfun = 0
    'If Nrfun <> 1 Then Goto Poczatek
    Waitms 50
    Loop
    End Sub
  • Pomocny post
    Poziom 14  
    Najprawdopodobniej kondesatory 100n ładują się przez wew pullup-y i wtedy jest na porcie logiczna "1".
    Jeżeli możesz, daj przyciski do masy a porty podciągnij rezystorami do +. Kondesatory raczej nie są potrzebne.
    Pozdrawiam.

    P.S. Nie przeglądałem programu.
  • Pomocny post
    Poziom 39  
    Całemu zamieszaniu , winna jest instrukcja Goto Poczatek :( Jej użycie , powoduje przepełnienie stosu i w efekcie "wariowanie" procka :D Jeśli chcesz zakończyć działanie podprogramu , to pozwól programowi "dojść" do End Sub , użyj Reurtn , lub warunkowej pętli Do ... Loop Until.Nawiasam mówiąc , taki styl pisania kodu bardzo mi się nie podoba , bo "zaciemnia obraz programu" :(

    Piotrek
    PS
    Ja bym go (ten kod) "wyciepnął na hasiok" ;)
  • Pomocny post
    Poziom 34  
    Jak wyżej.
    GOTO unikaj jak ognia - szczególnie jeśli wyskakuje z podprogramu, funkcji itp. do pętli głównej. Spróbuj użyć w tym miejscu Exit Do. Program wyjdzie z pętli Do - Loop, przemknie przez End Sub lub Return, oczyści stos i prędzej czy później trafi na Początek.
  • Poziom 20  
    Zrobiłem tak jak napisał WaldekPrzybyłek - chyba pomogło. Na wszelki wypadek zrobiłem też tak jak napisali inni. Wykorzystałem funkcję Exit Sub. Czy mogę wychodzić za pomocą tej funkcji z procedury, w której znajduje się pętla DO...LOOP, a funkcja ta, właśnie zostanie użyta w tej pętli?
  • Pomocny post
    Poziom 14  
    Osobiście najpierw wychodzę z pętli Do-Loop - Exit Do - a następnie za loop jest polecenie Exit Sub.
    Ale zapewne "spece"dają znać czy można też tak, jak proponujesz.
    Pzdr.
  • Poziom 20  
    OK. Poradziłem sobie ze wszystkim. Wygląda na to, że sterownik pracuje stabilnie. Co do stylu pisania programu, jest to po prostu mój styl :) Piszę programy od ok. 15 lat, zaczynałem na atari i commodorku (BASIC), potem amiga (pascal), następnie PC (pascal, delphi, qbasic). Od ok. roku piszę również w Bascom AVR. Nigdy nie sądziłem, że GOTO może robić takie problemy...
    Dziękuję wszystkim za pomoc.

    Wesołych Świąt !

    Pozdrawiam.