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

Atmega16: Brak reakcji na zmianę stanu portu A w Bascomie, pętla Do Loop

slaweek_22 02 Maj 2008 11:04 1648 8
REKLAMA
  • #1 5097552
    slaweek_22
    Poziom 16  
    Posty: 233
    Pomógł: 5
    Ocena: 14
    Witam. Mam problem z porgramemem w Bascomie, Do tej pory wszystko działało poprawnie aż do poewnego momentu zaczeły sie jakies anomalie. Mianowicie, program nie reaguje na zminanę na porcie A w podprogramie zamkanie_awaryjne, zamykanie i otwieranie, gdy wciskam przycski i wysyłam stam przez RS232 to odczytuje poprawnie ale w Do Loopp Until Kpz=1 nie reaguje. W pętli zamykania awaryjnego przy pierwszej pętli Do Loop Until... kręci sie w niej do momentu zliczenia pierwszej sekundy a ptem z niej wykskuje. Ma ktoś może jakieś pomysły co może być przyczyną tego dzwnego zachowania. Dodam jeszcze, że wczesniej na tym samym kodzie wszystko działało poprawnie stąd moje zdziwienie.



    
    $regfile = "m16def.dat"
    $crystal = 8000000
    Baud = 115200
    
    Config Watchdog = 16
    
     Porta = 255
    
    'KONFIGURACJA PORTÓW
    Config Porta = Input
    
    Config Portd = Output
    Config Pinc.0 = Output
    
    Portd.4 = 0
    Portd.5 = 0
    
    
    Set Porta.0
    Set Porta.1
    Set Porta.2
    Set Porta.3
    Set Porta.4
    Set Porta.5
    Set Porta.6
    'Set Portc.0
    'Set Portd.3
    
    
     Dir_l Alias Portd.7
     Dir_p Alias Portd.6
     Trafo Alias Portc.0
     Lampa Alias Portd.3
    
       Klo Alias Pina.0                                         'KP2
       Klz Alias Pina.1                                         'KP1
       Kpo Alias Pina.2                                         'KL2
       Kpz Alias Pina.3                                         'KL1
      Irda Alias Pina.4                                         'IR
     Przec Alias Pina.5                                         'PRZEC_STAN
    Startt Alias Pina.6                                         'START
    '=========================
    
    
    
    
    
    
    
    
    Enable Interrupts
    On Timer0 Przerwanie
    Stop Watchdog
    
    
    
    Config Timer0 = Timer , Prescale = 1024
    Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 256       'PWM=250Hz
    Load Timer0 = 195
    
    
    
    
    Dim Stan As Byte
    Dim Temp As Byte                                            'Dim Niezamykac As Bit  Dim Przejazd As Bit
    Dim Czas As Byte
    Dim Lampa_ As Bit
    Dim Licz40 As Byte
    Dim Portt As Byte
    Dim Zmiana As Byte
    Dim Port1 As Byte
    Dim Predkosc_dojazdu As Byte
    Dim Przejechal As Bit
    Dim Czas1 As Byte
    
    
    
    
    Lampa = 0
    Lampa_ = 0
    Trafo = 0
    Zmiana = 0
    Predkosc_dojazdu = 120
    Przejechal = 0
    
    
    Pwm1a = 0
    Pwm1b = 0
    
    
    '(
    Dir_p = 1
    Dir_l = 1
    
    Do
    
    For Pwm1b = 0 To 254
       Pwm1a = Pwm1b
       Waitms 50
    
       Print Pwm1b
    Next
    
    
    For Pwm1b = 255 To 0 Step -1
       Pwm1a = Pwm1b
       Waitms 50
       Print Pwm1b
    Next
     Toggle Dir_l
     Toggle Dir_p
    
    Loop
    ')
    Enable Timer0
    Enable Timer1
    Print "ELO"
    Enable Interrupts
    
    
    'MAIN  =========================================================================
    Do
    
    
    
    
    Loop
    'END MAIN ======================================================================
    
    
    
    
    
    
    '(
    
      Stan :
      1 - Zamknięta
      2 - Otwarta
      3 - Polozenie Srodkowe Obie Lub Jedna
    
      4 - Zamykanie
      5 - Otwieranie
      6 - Zamykanie Awaryjne
    
    
      Kierunki Dir_l Dir_p
      0 - Zamykanie
      1 - Otwieranie
    
    ')
    
    
    
    
    
    'INT_TIMERA=====================================================================
    Przerwanie:                                                 'Oscylator/prescaler/load timera/dzielnik dodatkowy
       Load Timer0 , 195                                        '8M/1024/195/40=1.001sec
       Incr Licz40                                              'tyle trzeba na przerwanie 1sekundowe
    
       'detekcja zmian na krytycznych portach
       If Port1.4 <> Pina.4 Then : Port1.4 = Pina.4 : Zmiana.4 = 1 : End If
       If Port1.5 <> Pina.5 Then : Port1.5 = Pina.5 : Zmiana.5 = 1 : End If
       If Port1.6 <> Pina.6 Then : Port1.6 = Pina.6 : Zmiana.6 = 1 : End If
    
    
    
       'odliczanie sekundy
       If Licz40 = 40 Then
          Licz40 = 0
          Incr Czas
          Print Czas
          Print Pina
          If Lampa_ = 1 Then : Toggle Lampa : End If            'Lampa ostrzegawcza
       End If
    
       'przerwanie fotokomorki
       If Zmiana.4 = 1 Then                                     'tutaj trzeba dodać bajer z zamykaniem po przejechaniu samochodu
          Zmiana.4 = 0
          If Pina.4 = 0 Then
             If Stan > 3 Then : Print "IRDA====" : Gosub Stop_reset : End If
             If Stan = 2 Then : Print "Przejechal" : Przejechal = 1 : End If
          End If
       End If
    
       'preciazenie silnika
       If Zmiana.5 = 1 Then
         Zmiana.5 = 0
         If Pina.5 = 1 Then
           If Stan > 3 Then
              Print "PRZECIAZENIE===="
              Gosub Stop_reset
    
           End If
         End If
        End If
    
        'wcisniecie startu
        If Zmiana.6 = 1 Then
           Zmiana.6 = 0
           If Pina.6 = 0 Then
              If Stan > 3 Then : Print "S>3" : Gosub Stop_reset : End If
                 Print "PRZERWANIE STARTEM======================="
                 Temp = Pina And &B00001111                     'po wcisnieciu startu identyfikacja stanu bramy
                    If Temp = &B00001010 Then
                       Stan = 1
                    Else
                         If Temp = &B00000101 Then
                            Stan = 2
                         Else
                            Stan = 3
                         End If
                    End If
    
    
                    If Irda = 1 Then                            ' jak cos jest w bramie to nie zareaguje na pilota
    
                            If Stan = 1 Then : Print "-> Otwieranie" : Gosub Otwieranie : End If
                            If Stan = 2 Then : Print "-> Zamykanie" : Gosub Zamykanie : End If
                            If Stan = 3 Then : Print "-> Zamykanie awaryjne" : Gosub Zamykanie_awaryjne : End If
                            If Stan = 4 Then : Print "Pilot na zamykaniu" : Gosub Stop_reset : End If
                            If Stan = 5 Then : Print "Pilot na otwieraniu" : Gosub Stop_reset : End If
                            Gosub Zamykanie_awaryjne
                    End If
              End If
          End If
    
    
    
    
    
    Return
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    'ZAMYKANIE =====================================================================
    Zamykanie:
    
    
          Trafo = 1
          Waitms 500                                            'czas zeby trafo wystartował nieobciązony
          Stan = 4
          Lampa_ = 1
    
         ' Enable Interrupts
         ' Enable Timer0
    
    
          If Irda = 1 Then
             If Przec = 0 Then
    
                   Czas = 0
                   Dir_l = 0
                   Dir_p = 0
    
                   Do : Pwm1a = Pwm1a + 2 : Waitms 24 : Loop Until Pwm1a > 252       'rozpędzanie jednej przez 3 sec   (3sec/255/2)
                   Do : Pwm1b = Pwm1b + 2 : Waitms 24 : Loop Until Pwm1b > 252       'rozpędzanie drugiej przez 3 sec    po 3 sec od rzpedzenia pierwszej
    
                   Do
                      Waitms 1
                                                      'musi być opuznienie bo sie porcek w tm miejscu resetowal
                      If Czas = 12 Then : Pwm1a = Predkosc_dojazdu : Pwm1b = Predkosc_dojazdu : Print "zwolnilo" : End If       'dobrać te czas (12) w rzeczywistości i prędkości najazdu do skraju
                      If Kpz = 1 Then : Pwm1b = 0 : Print "KPZ" : End If       'czekanie az brama dojedzie do konca i sie wylaczy
                      If Klz = 1 Then : Pwm1a = 0 : Print "KLZ" : End If
                   Loop Until Klz = 1 And Kpz = 1
    
                   Lampa_ = 0                                   'pozwolenie na lampe
                   Lampa = 0                                    'stan lampy
             End If
          End If
    
    
    
    
          'automtyczne zamykanie po przejechaniu samochodu
    
    
    
          Do
    
             If Czas > 120 Then
    
                Do
                Loop Until Czas = 130 Or Przejechal = 1
                Gosub Zamykanie
            End If
    
    
          Loop Until Przejechal = 1
          Czas1 = Czas
          Lampa = 1
          Lampa_ = 1
    
          Do
          Czas1 = Czas1 + 15
          Loop Until Czas = Czas1
    
          Gosub Zamykanie
    
    
    
    
         Trafo = 0
         Gosub Stop_reset
    Return
    'END ZAMYKANIE==================================================================
    
    '(
    
    
    
    
    
    ')
    'OTWIERANIE ====================================================================
    Otwieranie:
    
    
          Trafo = 1
          Waitms 500                                            'czas zeby trafo wystartował nieobciązony
          Stan = 5
          Lampa_ = 1
    
          Enable Interrupts
          Enable Timer0
    
    
          If Irda = 1 Then
             If Przec = 0 Then
    
                   Czas = 0
                   Dir_l = 1
                   Dir_p = 1
    
                   Do : Pwm1b = Pwm1b + 2 : Waitms 24 : Loop Until Pwm1b > 252       'rozpędzanie jednej przez 3 sec   (3sec/255/2)
                   Do : Pwm1a = Pwm1a + 2 : Waitms 24 : Loop Until Pwm1a > 252       'rozpędzanie drugiej przez 3 sec    po 3 sec od rzpedzenia pierwszej
    
                   Do
                      Waitms 1                                  'musi być opuznienie bo sie porcek w tm miejscu resetowal
                      If Czas = 12 Then : Pwm1a = Predkosc_dojazdu : Pwm1b = Predkosc_dojazdu : End If       'dobrać te czas (12) w rzeczywistości i prędkości najazdu do skraju
                      If Klo = 1 Then : Pwm1a = 0 : End If      'czekanie az brama dojedzie do konca i sie wylaczy
                      If Kpo = 1 Then : Pwm1b = 0 : End If
                   Loop Until Klo = 1 And Kpo = 1
    
                   Lampa_ = 0                                   'pozwolenie na lampe
                   Lampa = 0                                    'stan lampy
             End If
          End If
    
    
    
    
    
    
    
    
    
    
         Trafo = 0
         Gosub Stop_reset
    Return
    'END OTWIERANIE=================================================================
    
    
    
    
    
    
    
    'ZAMYKANIE AWARYJNE=============================================================
    Zamykanie_awaryjne:
    
          Print "zamykanie awaryjne"
          Trafo = 1
          Waitms 500                                            'czas zeby trafo wystartował nieobciązony
          Stan = 6
          Lampa_ = 1
    
          Enable Interrupts
          Enable Timer0
    
    
          If Irda = 1 Then
    
             If Przec = 0 Then
    
                   Czas = 0
                   Dir_l = 0
                   Dir_p = 0
    
                   'Do : Pwm1a = Pwm1a + 2 : Waitms 24 : Loop Until Pwm1a > 252       'w awaryjnym na razie bez rozpedzania
                   'Do : Pwm1b = Pwm1b + 2 : Waitms 24 : Loop Until Pwm1b > 252
                   Pwm1a = 100
                                                 'zamyka tylko pierwsze skrzydlo
                   Do : Waitms 100 : Print " L1" : Loop Until Kpz = 1
    
    
    
                   Print "jedna OK"
    
                   Pwm1a = 0
    
    
                   Pwm1b = 100
             Print "ZA7"                                        'zamyka drugie skrzydlo
    
    
                   Do : Waitms 100 : Print "L2" : Loop Until Klz = 1
    
    
    
    
                   Pwm1b = 0
    
                   Lampa_ = 0
                   Lampa = 0
             End If
          End If
    
         Trafo = 0
    
       Print "ZA=OK"
         Gosub Stop_reset
    Return
    'END ZAMYKANIE AWARYJNE ========================================================
    
    
    
    
    
    
    
    'RESET PROCKA ==================================================================
    Stop_reset:
    
       Print "reset @" ; Czas ; "s"                             '>>>>>>>>>>>>>>>>>>
       Pwm1a = 0
       Pwm1b = 0
       Start Watchdog
       Waitms 20
    
    Return
    'END RESET PROCKA ==============================================================
  • REKLAMA
  • Pomocny post
    #2 5098204
    elektronik000
    Poziom 19  
    Posty: 456
    Pomógł: 17
    Ocena: 52
    Jeśli masz w obudowie DIP to czy masz połączone piny do masy (pin 11, 31) i do zasilania (pin 10,30)?
  • REKLAMA
  • #3 5099147
    slaweek_22
    Poziom 16  
    Posty: 233
    Pomógł: 5
    Ocena: 14
    Oczywiście mam podłaczone te piny (za wjątkeim 30 bo nie używam ADC, też go podłaczyłem ale nie przyniosło to żadnych zmian).
  • Pomocny post
    #4 5099959
    dawid512
    Poziom 32  
    Posty: 1439
    Pomógł: 229
    Ocena: 6
    Może uszkodziłeś PortA przez to ze wczesniej nie miałeś napiecia na AVCC ale raczej w to watpie, sprawdzales na innym porcie? Po pierwsze sprobuj zapalic zwyklego LEDa na kazdym pinie tego portu.
  • REKLAMA
  • Pomocny post
    #5 5100852
    Balu
    Poziom 38  
    Posty: 4397
    Pomógł: 323
    Ocena: 48
    Jak działało poprawnie wsta drugą megę i zobacz czy będzie dobrze:>

    Oczywiście w FUSEach nie dłubałeś i przypadkiem Ci się jtag nie włączył?:> (PORTC)
  • REKLAMA
  • #6 5101265
    slaweek_22
    Poziom 16  
    Posty: 233
    Pomógł: 5
    Ocena: 14
    W Fusach mam porządek, nie zmieniałęm nic od poprzedniego razu. Co dziwne na poniższym programiku który napisąłm żeby sprawdzić port wszytsko dzial poprawnie (reaguje na nacisnięcie przycisku), więc według mnei powinno ównie dzialac na kodzie powyżej.


    
    $regfile = "m16def.dat"
    $crystal = 8000000
    Baud = 115200
    
    
    
    
    
    Config Porta = Input
    Do
    
    
    
    
    
    
    
    
    Print "========================"
    Print Pina.0
    Print Pina.1
    Print Pina.2
    Print Pina.3
    Print Pina.4
    Print Pina.5
    Print Pina.6
    Print Pina.7
    
    
    
    Waitms 500
    
    
    
    If Pina.0 = 1 Then
    Print "~~~~~~~~~~~~~~~~~~~~~~~"
    End If
    
    
    
    Loop




    Doadam jesze zę program poprawnie odczytuje stan posru na początku bo w zalleżnośći od stanu przycisków poprwanie włącza albo otwieranie albo zamykanie itd.
  • Pomocny post
    #7 5101358
    Balu
    Poziom 38  
    Posty: 4397
    Pomógł: 323
    Ocena: 48
    hmmm

    Przede wszystkim:
    
    
    
    Enable Interrupts
    On Timer0 Przerwanie
    Stop Watchdog
    
    
    
    Config Timer0 = Timer , Prescale = 1024
    Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 256       'PWM=250Hz
    Load Timer0 = 195
    
    
    

    To włączenie przerwania jest wstrętne w tym miejscu:P

    Co do wniosków...
    może spróbuj zwiększyć stos o parę, parę naście bajtów:>

    Dodano po 2 [minuty]:

    No i 500ms opóźnienia w przerwaniu:>
  • #8 5101406
    slaweek_22
    Poziom 16  
    Posty: 233
    Pomógł: 5
    Ocena: 14
    500ms dałem po to aby duży toroid mógł wystartować bez obciążenia. A jak można zwiększyć rozmiar stosu?

Podsumowanie tematu

✨ Problem dotyczy mikrokontrolera Atmega16 programowanego w Bascomie, gdzie program przestał reagować na zmianę stanu portu A w podprogramie zamkanie_awaryjne, mimo że odczyt przez RS232 działa poprawnie. Występuje sytuacja, w której pętla Do Loop Until Kpz=1 nie reaguje na zmianę stanu portu, a w pierwszej iteracji pętli zamykania awaryjnego program zatrzymuje się na około sekundę, po czym wychodzi z pętli. Sprawdzono poprawne podłączenie pinów zasilania i masy (pin 10, 11, 30, 31) oraz brak zmian w ustawieniach fuse, w tym wyłączenie JTAG. Testy na prostym programie potwierdziły poprawne działanie portu A. Sugerowano możliwe uszkodzenie portu A z powodu braku napięcia na AVCC, jednak to zostało wykluczone. Wskazano, że włączenie przerwań i konfiguracja timerów w obecnym miejscu kodu może powodować problemy, a także zasugerowano zwiększenie rozmiaru stosu, co może wpłynąć na stabilność działania programu. Autor pytał o sposób zwiększenia stosu, otrzymując wskazówki dotyczące dokumentacji i link do pomocy AVR.
REKLAMA