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] Uruchamianie timera na np.2sek

xamrex 29 Gru 2010 21:16 1636 16
REKLAMA
  • #1 8931469
    xamrex
    Poziom 28  
    Witam,
    Chciałbym napisać sobie taki program.
    Jeśli Pind.6 zewrzemy do masy (Pind.6 =0) to wtedy zostanie wyświetlony komunikat SUPER,
    Jeśli w ciągu następnych 2 sekund drugi raz zewrzemy go do masy, to otrzymamy komunikat EXTRA,
    Jeśli zaś zewrzemy ten pind.6 po upływie 2 sekund, to nic się nie stanie.

    Mam taki ogólny zarys tego w Bascomie
    
    $regfile = "attiny2313.dat"
    $crystal = 1000000
    
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portd.1 , Rs = Portd.0
    Config Timer1 = Timer , Prescale = 64
    Portd.6 = 1
    Dim Cosik As Byte
    Przycisk Alias Pind.6
    Enable Interrupts
    
    
    
    Cls
    
    
    Do
    If Przycisk = 0 Then
    Start Timer1
    Lcd "SUPER"
    Gosub Dalej
    Waitms 100
    End If
    Loop
    End
    
    
    Dalej:                                                      ' TUTAJ JEST ZLE, TRZEBA TO POPRAWIC
    If Timer1 < 34286 Then
    Cls
    Lcd "EXTRA"
    End If
    Return
    End
    


    Jak widać mam problem z Timerem,
    Gdyż on leci sobie cały czas,
    I po tych 2 sekundach, jak rośnie od 34286 w górę do 65535, to potem znowu przyjmuje wartość 1. i znowu leci w górę i znowu można uzyskać teoretycznie czas mniejszy niż 2 sek (gdyż timer leci w kółko)

    Bardzo proszę o jakieś nakierowanie :)
  • REKLAMA
  • #2 8931549
    piotrva
    VIP Zasłużony dla elektroda
    a instrukcje start timer1 i stop timer1?
    to tak najprościej, bo wogóle to to można zrobić na timerze0, przerwaniu i jednym liczniku programowym...
  • REKLAMA
  • #3 8931762
    Fredy
    Poziom 27  
    1) linia portu D.6 nie jest zadeklarowana jako wejście ( w sumie nie musi być bo tak jest defaultowo ale wypada to zrobić )
    2) nie masz nigdzie kasowania timiera1
    3) jak robisz ifa to powinieneś odwrócić warunek

    to tylko kilka z wielu błędów które tu są. Pomyśl nad logiką programu bo trochę tu jej brak.
  • #4 8932101
    xamrex
    Poziom 28  
    Ok,
    Mam coś takiego
    
    $regfile = "attiny2313.dat"
    $crystal = 1000000
    
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portd.1 , Rs = Portd.0
    Config Timer1 = Timer , Prescale = 64
    Config Pind.6 = Input
    Portd.6 = 1
    Przycisk Alias Pind.6
    On Timer1 Zatrzymaj
    
    
    
    Cls
    
    
    Do
    If Przycisk = 0 Then
    
    Enable Interrupts
    Enable Timer1
    
    Start Timer1
    Lcd "SUPER"
    Waitms 200
    Gosub Dalej
    End If
    Loop
    
    End
    
    
    
    Dalej:
    Do
    If Timer1 < 34286 Then
    If Przycisk = 0 Then
    Locate 2 , 1
    Lcd "EXTRA"
    Stop Timer1
    End If
    End If
    Loop
    Return
    
    
    
    Zatrzymaj:
    Disable Timer1
    Do
    Loop
    Return
    End
    
    

    I prawie działa,
    Ale jeśli na samym początku poczekamy (dłużej niż kilka sekund) z zewrzeniem pinud.6 do masy, to program potem nie działa. (Nie chce nic wyświetlić na wyświetlaczu)

    Tak jakby od razu załączał Timer1, i po 2 sekundach, wpadał do pętli Zatrzymaj:, która zatrzumuje działanie programu.
  • #5 8932378
    landy13
    Poziom 31  
    1 "Enable Interrupts" i "Enable Timer1" pisze się przed pętlą główną.
    2 Timer zaczyna liczyć od momentu ustawienia preskalera, tzn linia: "Config Timer1 = Timer , Prescale = 64". Jeśli tego nie potrzebujesz daj od razu Stop Timer1.
    3 Program nigdy nie wyjdzie z procedury "Dalej" (tak ma być?).
    4 Jaki jest cel przerwania "Zatrzymaj"?

    Właściwą odpowiedzią na Twoje pytanie jest punkt 2.
  • #6 8932447
    Fredy
    Poziom 27  
    landy13 napisał:
    1 "Enable Interrupts" i "Enable Timer1" pisze się przed pętlą główną.


    a niby czemu?
    Można odblokowywać i blokować przerwania w dowolnym momencie.
  • REKLAMA
  • #7 8932474
    landy13
    Poziom 31  
    Fredy napisał:
    Można odblokowywać i blokować przerwania w dowolnym momencie.
    Można. Ale po co w tym programie?
    Uważasz, że powinno się je odblokowywać za każdym obiegiem pętli głównej?
  • #8 8932500
    Fredy
    Poziom 27  
    landy13 napisał:
    Fredy napisał:
    Można odblokowywać i blokować przerwania w dowolnym momencie.
    Można. Ale po co w tym programie?
    Uważasz, że powinno się je odblokowywać za każdym obiegiem pętli głównej?


    często blokuje się przerwania nawet na czas trwania jednej instrukcji aby chwilę po tym odblokować je ponownie .
  • #9 8932550
    landy13
    Poziom 31  
    Fredy napisał:
    często blokuje się przerwania nawet na czas trwania jednej instrukcji aby chwilę po tym odblokować je ponownie .
    No i dobrze. Nikt temu nie zaprzecza. Wyjaśnij mi tylko, po co je co chwilę odblokowywać, skoro ich się nigdzie nie blokuje.
  • #10 8932664
    Fredy
    Poziom 27  
    Przeczytaj sobie co napisałeś to zrozumiesz czemu ci tak odpowiedziałem.

    Wracając do tematu:
    Ten program ma wiele błędów. Po co wogóle używasz tu przerwania skoro z niego nie korzystasz?

    Zrób coś takiego:

    Do
    If Przycisk = 0 Then Gosub Sprawdzenie                      'nacisnieto 1 raz
    
    Loop
    
    Sprawdzenie:
          Lcd "SUPER"
          Timer1 = 0
          Start Timer1
    
          do
           Loop Until Timer1 > 35000 Or Przycisk = 0
          If Przycisk = 0 Then
             Waitms 100
             Locate 2 , 1
             Lcd "EXTRA"
          End If
    Return
    
  • #11 8932763
    landy13
    Poziom 31  
    Fredy napisał:
    Przeczytaj sobie co napisałeś to zrozumiesz czemu ci tak odpowiedziałem.

    Odwracanie kota ogonem. Ja wiem co napisałem. To forum techniczne a nie poetyckie. Nie każ się domyślać, co autor (Ty) miał na myśli. Powiedz wprost. Albo chociaż odpowiedz na to: "Wyjaśnij mi tylko, po co je co chwilę odblokowywać, skoro ich się nigdzie nie blokuje."

    Przypominam tylko, że moje wypowiedzi dotyczą aktualnych problemów użytkowników i mają być doraźnym na nie lekarstwem. Nie prowadzi się na forum szeroko pojętych kursów programowania mikrokontrolerów od podstaw. Przynajmniej ja ich nie prowadzę, bo ani bym umiał ani chciał.
    Z mojej strony EOT.
  • #12 8933139
    Fredy
    Poziom 27  
    OK to przytoczę ci tok dyskusji , chociaż uważam to za zbędne:

    landy13 napisał:
    1 "Enable Interrupts" i "Enable Timer1" pisze się przed pętlą główną.


    pisząc coś takiego , chyba każdy początkujący przyjmie to za znak że tak się robi zawsze - nie uważasz?

    dlatego odpisałem na to w ten sposób:

    Fredy napisał:

    a niby czemu?
    Można odblokowywać i blokować przerwania w dowolnym momencie.


    Czy nie uważasz że to naturalna odpowiedź?
    Myślę że teraz zrozumiesz i zakończymy tą zbędną dyskusję.

    Pozdrawiam
  • REKLAMA
  • #13 8934335
    xamrex
    Poziom 28  
    Fredy napisał:

    Zrób coś takiego:

    Do
    If Przycisk = 0 Then Gosub Sprawdzenie                      'nacisnieto 1 raz
    
    Loop
    
    Sprawdzenie:
          Lcd "SUPER"
          Timer1 = 0
          Start Timer1
    
          do
           Loop Until Timer1 > 35000 Or Przycisk = 0
          If Przycisk = 0 Then
             Waitms 100
             Locate 2 , 1
             Lcd "EXTRA"
          End If
    Return
    


    Loop Until Timer1 > 35000 Or Przycisk = 0

    Wg. mnie ten warunek jest zły , bo jest tam OR,
    Czyli jeśli przycisk będzie=0, to waruenk z czasem (timer >35000) można pominąć.

    Teraz

    landy13 napisał:

    3 Program nigdy nie wyjdzie z procedury "Dalej" (tak ma być?).
    4 Jaki jest cel przerwania "Zatrzymaj"?

    3. Tak tak ma być
    4. Cel przerwania Zatrzymaj jest taki, że jeśli przepełni się Timer1, to nie będzie on zliczał ponownie od wartości 0 w górę (do 65535)

    A mój program wygląda teraz tak:
    $regfile = "attiny2313.dat"
    $crystal = 1000000
    
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portd.1 , Rs = Portd.0
    Config Timer1 = Timer , Prescale = 64
    Stop Timer1
    Config Pind.6 = Input
    Portd.6 = 1
    Dim Cosik As Byte
    Przycisk Alias Pind.6
    On Timer1 Zatrzymaj
    
    
    
    Cls
    
    
    Do
    If Przycisk = 0 Then
    
    Enable Interrupts
    Enable Timer1
    Start Timer1
    Lcd "SUPER"
    Waitms 200
    Gosub Dalej
    End If
    Loop
    
    End
    
    
    
    Dalej:
    Do
    If Timer1 < 34286 Then
    If Przycisk = 0 Then
    Locate 2 , 1
    Lcd "EXTRA"
    Stop Timer1
    End If
    End If
    Loop
    Return
    
    
    
    Zatrzymaj:
    Disable Timer1
    Do
    Loop
    Return
    End
    
    
    
    
    

    I działa poprawnie.
    Jeśli ma ktoś jakieś zastrzeżenia to proszę pisać
  • #14 8942421
    Konto nie istnieje
    Poziom 1  
  • #15 8942616
    Pavlik71
    Poziom 15  
    Program będzie źle działał. Gdy przycisk będzie przyciśnięty dłużej niż 200 ms.

    Taki scenariusz:

    1. Włączamy zasilanie.
    2. Przyciskamy przycisk i trzymamy go.
    3. Wyświetli się SUPER
    4. A za około 200 ms EXTRA.
    5. I trzymając dalej przycisk, będzie nadpisywany tekst EXTRA.
    6. Po puszczeniu przycisku program nadal będzie w podprogramie "Dalej"
  • #16 8943986
    Fredy
    Poziom 27  
    Skoro autor jest zadowolony to to jest najważniejsze. A że program jest w kilku miejscach do bani to już inna sprawa.
    Napisałem mu fragment programu pod wytyczne takie jak napisał na początku to był też niezadowolony.
  • #17 8946307
    xury
    Specjalista automatyka domowa
    Widzę, że koledze spodobała się pętla Do...Loop, bo używa pętli nieskończonej nawet w przerwaniu :) Moje gratulacje, no bo mimo tego dla Ciebie program działa prawidłowo. Nigdy bym nie wpadł na pomysł, by zapętlić program w pętli nieskończonej właśnie w przerwaniu :)
REKLAMA