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

[Bascom][Atmega8] Problem z opóźnieniem wykonania programu

Strzala86 27 Wrz 2010 13:35 2618 12
REKLAMA
  • #1 8555809
    Strzala86
    Poziom 10  
    Mój problem przedstawia się następująco:
    używam 4 przycisków, po wciśnięciu pierwszych trzech wykonuje się podprogram, natomiast po wciśnięciu czwartego przycisku wykonuje się podprogram, a po 5 min kolejny podprogram, tylko że nie wiem jak zrealizować to 5 minutowe opóźnienie. Tymczasowo dałem funkcję "wait", no ale ona blokuje mikrokontroler i w tym czasie nie można wcisnąć np pierwszego czy drugiego przycisku. Ma ktoś może pomysł jak to rozwiązać? Ja niestety mam małe doświadczenie z Bascomem i nie wiem jak to zrobić...
  • REKLAMA
  • #2 8555845
    MirekCz
    Poziom 35  
    Musisz ustawić timer. Nie wiem czy dasz radę na 5minut, ale możesz np zrobić go na 10sekund i wywołać 30razy (w timerze będziesz zliczał kolejne wywoływania i ponownie ustawiał timer, jak dojdzie zmienna do 30 to wyłączysz timer i wywołasz podprogram).

    Nie będzie to nic blokowało :)
  • REKLAMA
  • #3 8556115
    Strzala86
    Poziom 10  
    Hmm, czy takie coś by się sprawdziło? :D

    $crystal 1000000
    dim 5min as byte
    Config Timer1 = Timer, Prescale = 1024
    On Timer1 Opoznienie
    On Interrupts
    	
    	Enable Timer1
    	Load Timer1 = 65535
    
    
    Opoznienie
    	
    	Load Timer1 = 65535
    	incr 5min
    
    		If 5min = 5 Then
    		
    		***********
    
    		5min = 0
    	End If
    Return
  • #4 8556432
    11111olo
    Poziom 42  
    Ja robiłem to tak.

    $map
    $regfile = "ATtiny2313.dat"
    $crystal = 1000000
    Dim ...
    Config Timer1 = Timer , Prescale = 8       ' ustawienie przerwań
    
    Enable Interrupts
    Enable Timer1
    On Timer1 Przerwanie
    
    Do
    
    program glowny
    
    Loop
    
    
    '***********************************
    Przerwanie:
    Timer1 = 64287                ' okolo 1 setna
    
    program przerwania
    
    Return


    W przerwaniu musisz zliczać odpowiednią wartość, tak aby uzyskać odpowiednie przerwy między kolejnymi etapami programu.
    Ten prosty szkielet programu powinien Ci pomóc.
  • REKLAMA
  • #5 8557059
    Strzala86
    Poziom 10  
    Hmm
    On Timer1 Nazwa_podprogramu

    nie muszę wcisnąć do podprogramu tego 4 przycisku?

    Powiedzmy, że dam
    $crystal = 1000000 do tego prescale=1024, przez 60 sekund Timer1 powinien doliczyć do 58594 (zakładając, że 1 takt licznika trwa 1,024ms), więc potrzebowałbym 5 przepełnień.
    Tylko jak zliczyć te przepełnienia?
  • REKLAMA
  • #6 8557125
    11111olo
    Poziom 42  
    To się nie robi jak myślisz.

    Najprościej jest zrobić to na "przepełnieni" licznika czyli jak doliczy do zera.

    Na początku ustawiasz mu np. 64287 i podział przez 256. Po dokładnie 0,01s nastąpi przepełnienie i włączenie przerwania. W przerwaniu pierwszą rzeczą jaką musisz zrobić jest ponowne ustawienie licznika na 64287.

    Jak chcesz jednocześnie sprawdzać przyciski to raz na sekundę to zdecydowanie za mało - optymalnie jest sprawdzać 100 razy i po 10 poprawnych sprawdzeniach (czy tylko pięciu) uznać że przycisk jest wciśnięty - zapobiega to drganiu przycisku (zmniejsza prawdopodobieństwo kilkukrotnego wciśnięcia przycisku).
  • #7 8557219
    Strzala86
    Poziom 10  
    Znaczy się chciałem dać Load Timer1 = 58594, wtedy chyba działałoby to przepełnienie o którym mówię?

    Do przycisków daje Debounce, więc myślę, że starczy

    Może wkleję tu resztę

    $regfile = "m8def.dat"
    
    $crystal = 1000000
    
    Config Pinb.1 = Input
    Config Pinb.2 = Input
    Config Pinb.3 = Input
    Config Pinb.4 = Input
    Config Pinc.0 = Output
    Config Pinc.1 = Output
    
    Przek1 Alias Portc.0
    Przek2 Alias Portc.1
    
    S1 Alias Pinb.1
    S2 Alias Pinb.2
    S3 Alias Pinb.3
    S4 Alias Pinb.4
    
    Set Portb.1
    Set Portb.2
    Set Portb.3
    Set Portb.4
    Set Portc.0
    Set Portc.1
    
    Do
       Debounce S1 , 0 , Pr1 , Sub
       Debounce S2 , 0 , Pr2 , Sub
       Debounce S3 , 0 , Pr3 , Sub
       Debounce S4 , 0 , Pr4 , Sub
    Loop
    End
    
    Pr1:
       Set Portc.0
       Set Portc.1
    Return
    
    Pr2:
       Przek1 = 0
       Set Portc.1
    Return
    
    Pr3:
       Przek1 = 0
       Przek2 = 0
    Return
    
    Pr4:
       Przek1 = 0
       Przek2 = 0
      
    Tu ma być te 5 minut opóźnienia, a następnie wykonuje to:
    
       Przek1 = 1
       Przek2 = 1
    Return
  • #8 8557242
    11111olo
    Poziom 42  
    Dalej nie rozumiesz!
    Ciągłe sprawdzanie w przerwaniu jest po to aby mikrokontroler "miał czas" aby sprawdzić inne rzeczy ani przez 5 minut być zajęty tylko odliczaniem jakiegoś opóźnienia.

    DEBOUNCE wnosi opóźnienie 20ms - czyli dość dużo - i nie jest to najlepsza metoda na sprawdzanie przycisków, ale do tego dojdziesz jak trochę opanujesz Bascom, który jest niestety bardzo wolny :/
  • #9 8557435
    xury
    Specjalista automatyka domowa
    Strzala86. Zmień myślenie o istocie działania programu. Program nie powinien czekać na jakieś zdarzenie. Za pomocą timera oraz zmiennych, które potocznie nazywane są flagami można napisać program tak, żeby cały czas działał bez opóźnień. Przykład takiego programu masz poniżej:
    https://www.elektroda.pl/rtvforum/topic1758870.html
    Jest tam nawet przyład zastosowania timera. Przyjrzyj się konstrukcjom, w których wykorzystuję zmienne bitowe jako flagi.
  • #10 8557481
    arktik1
    Poziom 27  
    Zrobił bym jeszcze inaczej, jeśli czas nie jest potrzebny co do milisekundy.
    Ustawił bym:
    
    Config Debounce = 25
    

    masz 4 Debounce ,czyli opóźnienie 100ms.
    Zadeklarował bym 2 zmienne:
    1 pomocnicza do włączenia naliczania po Pr4 i druga do naliczania 5 min.
    Po naliczaniu do X=5 min skoczył bym do drugiej części Pr4.
    Oczywiście wartość X dobrał bym eksperymentalnie np.stoperem.
  • #11 8557483
    landy13
    Poziom 31  
    Strzala86 napisał:
    Znaczy się chciałem dać Load Timer1 = 58594, wtedy chyba działałoby to przepełnienie o którym mówię?

    Działałoby, gdybyś zastosował właściwą składnię, tzn. "LoadTimer , 58594"

    Strzala86 napisał:
    Do przycisków daje Debounce, więc myślę, że starczy

    Jak najbardziej wystarczy.

    11111olo napisał:
    Ciągłe sprawdzanie w przerwaniu jest po to aby mikrokontroler "miał czas" aby sprawdzić inne rzeczy ani przez 5 minut być zajęty tylko odliczaniem jakiegoś opóźnienia.
    Miałbyś rację, gdyby stosował "Waita'. Sprzętowy timer odlicza czas w tle i nie przeszkadza to mikrokontrolerowi w "sprawdzaniu innych rzeczy" ani też innych czynnościach.
  • #12 8558844
    Konto nie istnieje
    Poziom 1  
  • #13 8565232
    piotrva
    VIP Zasłużony dla elektroda
    a ja bym to zrobił na przerwaniu. podpinasz wszystkie przyciski przez diody do jednego z wyprowadzeń (int0) i po problemie ;-)
REKLAMA