Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[Bascom] Pomoc w napisaniu programu.

marcinwrc2 12 Sep 2010 18:30 3336 32
  • #1
    marcinwrc2
    Level 12  
    Witam.
    Robię dwa proste urządzenia na at 2313 (czyli dwa osobne programiki), jeden załącza przekaźniki 2szt z opóźnieniem kolejno 25s i 30s po podaniu zasilania na układ.
    Drugi zaś wynalazek to załączenie przekaźnika przyciskiem s1 na 60s i możliwość w trackie czasu pracy wyłączyć go przez s2.
    Ten pierwszy prawie działa tz załącza mi jeden przekaźnik po czasie 25s ale nie wiem jak dopisać w bascomie czas na ten drugi.
    Z tymi przyciskami trochę gorzej bo w tym nie wiem jak rozwiązać wyłączenie przekaźnika podczas pracy.
    Jestem początkujący i proszę o wyrozumiałość, staram się to jakoś pojąć ale niem mam się do kogo zgłosić o pomoc.
    Kamery 3D Time of Flight - zastosowania w przemyśle. Darmowe szkolenie 16.12.2021r. g. 10.00 Zarejestruj się
  • #3
    marcinwrc2
    Level 12  
    Code:
    $regfile = "2313def.dat"
    
    $crystal = 800000
    Config Pind.0 = Output
    Config Pind.1 = Output
    Przekaznik Alias Portd.0
    Przekaznik Alias Portd.1
     Do
        Wait 25
    Set Przekaznik
    Loop
    End

    $regfile = "2313def.dat"
    $crystal = 800000
    Config Pind.0 = Output
    Config Pinb.1 = Input
    Config Pinb.2 = Input
    Przekaznik Alias Portd.0
    S1 Alias Pinb.2
    S2 Alias Pinb.1
    If S1 = 0 Then
    If S2 = 0 Then
    End
  • Helpful post
    #4
    xury
    Automation specialist
    No właśnie podejrzewałem , to że użyjesz Wait, który tak jakby "zawiesza" procesor na 25 sekund.
    Najlepiej by było użycie timera do ustalania czasu, ale wiem, że dla początkującego to za trudne. Podpowiem więc inne rozwiązanie:
    Daj w pętli głównej wait1. Następnie zwiększaj zmienną i napisz warunek kiedy osiągnie ona 25 (if then endif) oraz kolejny warunek kiedy osiągnie 30.
    Drugi wynalazek też już będziesz mógł wyłączyć po 60 sekundach stosując ten prymitywny pseudo timer.
  • Helpful post
    #5
    ShEvU_elektro
    Level 25  
    Przede wszystkim musisz zacząć kolego od poznania timerów. Do odmierzenia czasu używamy timerów ponieważ zlicza nam czas w tle działania procesora. Używając polecenia wait zatrzymujesz kompletnie uC na ten czas.

    Konfiguracja dla AtMega8 8Mhz u mnie wygląda tak:

    Code:
    Config Timer1 = Timer , Prescale = 256  ''''konfiguracja timera
    
    On Timer1 1s                                             ''''przy przerwaniu skocz do "1s"

    Counter1 = 34286                                       ''''wartość początkowa dla licznika
    Enable Timer1

    1s:
    Counter1 = Counter1 + 34286                       
    Incr Sekundy                          ''''zwiększ o jeden wartość zmiennej sekundy

    Return




    Teraz w programie wystarczy sprawdzić czy zmienna sekundy osiągnęła 25. Jeśli tak to coś wykonać i np. zresetować tą zmienną.
    Do obsługi timera możesz użyć poleceń
    Code:
    stop timer1
    i analogicznie
    Code:
    start timer1
  • #6
    marcinwrc2
    Level 12  
    No to muszę trochę poczytać o tych timerach. Tylko nie wiem jak to sklecić do kupy w całość.
  • #7
    marcinwrc2
    Level 12  
    No niby wiadomo o co chodzi z tymi timerami, tylko jak napisać instrukcje żeby z opóźnieniem odpalić dwa przekaźniki w różnym czasie.Tego nie wiem czytam szukam i nic.
  • #8
    xury
    Automation specialist
    Skoro już wiesz jak zwiększać zmienną sekund to co za problem ?
    Np.
    Code:

    dim sekunda as byte
    przekaznik1 alias port.d0    ' przykład
    przekaznik2 alias portd.1
    If sekunda = 25 then
              set przekaznik1
     elseif sekunda = 30 then
            set przekaźnik2
    endif
  • #9
    marcinwrc2
    Level 12  
    Cudowałem dziś z tymi programami i na razie nic nie działa.Napisałem coś takiego:

    Code:
    $regfile = "2313def.dat"
    
    $crystal = 800000
    Config Pind.0 = Output
    Config Pind.1 = Output
    Config Timer0 = Timer , Prescale = 256
    Enable Timer0
    Dim Licz_8ms As Byte
    Enable Timer0
    Load Timer0 = 250
    Dim Sekunda As Byte
    Przekaznik1 Alias Portd.0
    Przekaznik2 Alias Portd.1
    If Sekunda = 2 Then
              Set Przekaznik1
     Elseif Sekunda = 3 Then
            Set Przekaznik2
    End If
                                                            'end program


    chyba coś namotałem
  • #10
    landy13
    Level 30  
    Konfiguracja dobra. Brakuje jeszcze: pętli głównej, obsługi przerwania i globalnego włączenia przerwań. Load Timer ma inną składnię.
  • #11
    xury
    Automation specialist
    Nie namieszałeś tylko nie dopisałeś. Po pierwsze nie Load timer0 = 250 tylko Load timer0, 6
    Po drugie , brak deklaacji do podprogramu np. On Timer0 licz_1s
    po trzecie trzeba napisać co ma się wykonywać w podprogramie, czyli dokładnie policzyć ile razy musi się przepełnić licznik od timera 0 by uzyskać sekundę.
  • #12
    marcinwrc2
    Level 12  
    Code:
    $regfile = "2313def.dat"
    
    $crystal = 800000
    Config Pind.0 = Output
    Config Pind.1 = Output
    Config Timer0 = Timer , Prescale = 256
    On Timer0 Odmierz_1s
    Dim Licz_8ms As Byte
    Enable Interrupts
    Enable Timer0
    Load Timer0 = 6
    Dim Sekunda As Byte
    Przekaznik1 Alias Portd.0
    Przekaznik2 Alias Portd.1
    If Sekunda = 2 Then
              Set Przekaznik1
     Elseif Sekunda = 3 Then
            Set Przekaznik2
    End If
                                                            'end program


    A teraz jak?
  • #13
    xury
    Automation specialist
    A gdzie pętla główna, a gdzie podprogram obsługi przewania ?
    Jak ci się ma ta sekunda liczyć ?
    Zamiast się pytać nie lepiej sprawdzić czy się program kompiluje ?
    Najpiew musisz zrozumieć jak ta sekunda ma ci się zwiększać. No bo teraz liczycz na to, że w jakiś magiczny sposób się to stanie.
    Zanim podasz kod z pytaniem, pzynajmniej sprawdz czy się on kompiluje.
  • #14
    marcinwrc2
    Level 12  
    Dopisałem co trzeba, tylko się nie kompiluje wywala 3 błędy.
    Code:
    $regfile = "2313def.dat"
    
    $crystal = 800000
    Config Pind.0 = Output
    Config Pind.1 = Output
    Config Timer0 = Timer , Prescale = 256
    On Timer0 Odmierz_1s
    Dim Licz_8ms As Byte
    Enable Interrupts
    Enable Timer0
    Load Timer0 = 250
    Dim Sekunda As Byte
    Przekaznik1 Alias Portd.0
    Przekaznik2 Alias Portd.1
    If Sekunda = 2 Then
    Set Przekaznik1
    Elseif Sekunda = 3 Then
    Set Przekaznik2
    Do
    Loop
    End
    Odmierz_1s:
    Load Timer0 = 250
    Incr Licz_8ms
    If Licz_8ms = 125 Then
    Licz_8ms = 0
    End If
     Return



  • #15
    ShEvU_elektro
    Level 25  
    Kolego, przed "do...Loop" brakuje Ci "End if"
  • #16
    landy13
    Level 30  
    1 Nadal źle napisane Load Timer.
    2 Brak inkrementacji zmiennej Sekunda.
    3 Sprawdzanie warunków powinno być w pętli lub (gorsze rozwiązanie) w przerwaniu.
  • #17
    marcinwrc2
    Level 12  
    Zrobiłem zgodnie z opisem i kompilacja poszła ale nie działa przekaznik.

    Dodano po 1 [minuty]:

    landy13 wrote:
    1 Nadal źle napisane Load Timer.
    2 Brak inkrementacji zmiennej Sekunda.
    3 Sprawdzanie warunków powinno być w pętli lub (gorsze rozwiązanie) w przerwaniu.

    To jak to rozwiązać?
  • #18
    landy13
    Level 30  
    1 Load Timer0 , 250
    2 Incr Sekunda (dopisać w przerwaniu po wyzerowaniu Licz_8ms)
    3 Może by tak samodzielnie?
  • #19
    marcinwrc2
    Level 12  
    Zastosowałem się do instrukcji i dalej nic mi nie wychodzi.Przepraszam ,że zawracam głowe ale ja dopiero się uczę i to moje pierwsze pisanie.

    Dodano po 7 [minuty]:

    Teraz wygląda to tak:
    Code:
    $regfile = "2313def.dat"
    
    $crystal = 800000
    Config Pind.0 = Output
    Config Pind.1 = Output
    Config Timer0 = Timer , Prescale = 256
    On Timer0 Odmierz_1s
    Dim Licz_8ms As Byte
    Enable Interrupts
    Enable Timer0
    Load Timer0 = 250
    Dim Sekunda As Byte
    Przekaznik1 Alias Portd.0
    Przekaznik2 Alias Portd.1
    If Sekunda = 2 Then
    Set Przekaznik1
    Elseif Sekunda = 3 Then
    Set Przekaznik2
    End If
    Do
    Loop
    End
    Odmierz_1s:
    Load Timer0 , 250
    Incr Licz_8ms
    If Licz_8ms = 125 Then
    Incr Sekunda
    Licz_8ms = 0
    End If
     Return


  • #20
    landy13
    Level 30  
    marcinwrc2 wrote:
    Zastosowałem się do instrukcji

    Nieprawda. Punkt pierwszy wykonałeś połowicznie, drugi niedokładnie (to akurat nie przeszkadza) a trzeci wcale.

    marcinwrc2 wrote:
    ja dopiero się uczę i to moje pierwsze pisanie
    To czemu nie czytasz Helpa? Kolega ZbeeGin męczył się kilka lat nad tłumaczeniem, a Ty to olewasz.
  • #21
    marcinwrc2
    Level 12  
    landy13 wrote:
    marcinwrc2 wrote:
    Zastosowałem się do instrukcji

    Nieprawda. Punkt pierwszy wykonałeś połowicznie, drugi niedokładnie (to akurat nie przeszkadza) a trzeci wcale.

    marcinwrc2 wrote:
    ja dopiero się uczę i to moje pierwsze pisanie
    To czemu nie czytasz Helpa? Kolega ZbeeGin męczył się kilka lat nad tłumaczeniem, a Ty to olewasz.


    Siedzę nad książką Marcina Wiązani Programowanie w jezyku Bascom.Czytam o timerach ale nie wiem jak praktycznie je zastosować w programie.
  • Helpful post
    #22
    landy13
    Level 30  
    Timer już masz zastosowany. Jeśli tylko przeniesiesz warunki sprzed pętli do pętli wszystko będzie działać.
    Już niebezpiecznie zbliżyłem się do podania gotowca, więc z mojej strony na razie koniec.
  • #23
    marcinwrc2
    Level 12  
    Zrobiłem jak piszesz i nie kompiluje. Bo ten warunek to chyba to ....
    If Sekunda = 2 Then
    Set Przekaznik1
    Elseif Sekunda = 3 Then
    Set Przekaznik2
    ????
  • Helpful post
    #24
    emarcus
    Level 38  
    marcinwrc2 wrote:
    Zastosowałem się do instrukcji i dalej nic mi nie wychodzi.Przepraszam ,że zawracam głowe ale ja dopiero się uczę i to moje pierwsze pisanie.

    Dodano po 7 [minuty]:

    Teraz wygląda to tak:
    Code:
    $regfile = "2313def.dat"
    
    $crystal = 800000
    Config Pind.0 = Output
    Config Pind.1 = Output
    Config Timer0 = Timer , Prescale = 256
    On Timer0 Odmierz_1s
    Dim Licz_8ms As Byte
    Enable Interrupts
    Enable Timer0
    Load Timer0 = 250
    Dim Sekunda As Byte
    Przekaznik1 Alias Portd.0
    Przekaznik2 Alias Portd.1
    If Sekunda = 2 Then
    Set Przekaznik1
    Elseif Sekunda = 3 Then
    Set Przekaznik2
    End If
    Do
    Loop
    End
    Odmierz_1s:
    Load Timer0 , 250
    Incr Licz_8ms
    If Licz_8ms = 125 Then
    Incr Sekunda
    Licz_8ms = 0
    End If
     Return



    No i nie zastosowałeś się do wskazówek!
    Powinno być:
    ...........
    Load Timer0, 250 'a NIE Load Timer0 = 250
    Dotyczy to tej pierwszej sekundy tez.
    'Jeżeli preferujesz używac znak = wtedy równorzędny zapis (syntax) byłby 'Timer0= 6' czyli (256-250)

    ...............
    Do
    If Sekunda = 2 Then
    Set Przekaznik1
    Elseif Sekunda = 3 Then
    Set Przekaznik2
    End If
    Loop

    Nie wystarczy tylko jeden raz na samym początku sprawdzić stan zmiennych/.
    Skoro ich wartość się zmienia, wiec należy ciągle sprawdzać czy oczekiwana zmiana nastąpiła. Właśnie pętla 'Do...Loop' jest jednym ze sposobów tego procesu i egzekucji dalszych dyrektyw.
    Mało tego, sprawdzanie wartości zmiennych przy starcie programu nie ma sensu, bo z góry wiadomo ze maja one wartość zerowa i taki proces nic nie wnosi do programu.

    Poza tym, jakie to są przekaźniki i jak je łączysz do uC?

    e marcus
  • #25
    marcinwrc2
    Level 12  
    No i układ działa, wielkie dzięki.Tylo co mam i gdzie pozmieniać bo czas niby 2 sek a przekaźnik załącza się po 16sek.???
    Kod teraz jest ok.
    Code:
    $crystal = 800000
    
    Config Pind.0 = Output
    Config Pind.1 = Output
    Config Timer0 = Timer , Prescale = 256
    On Timer0 Odmierz_1s
    Dim Licz_8ms As Byte
    Enable Interrupts
    Enable Timer0
    Load Timer0 , 250
    Dim Sekunda As Byte
    Przekaznik1 Alias Portd.0
    Przekaznik2 Alias Portd.1
     Do
    If Sekunda = 2 Then
    Set Przekaznik1
    Elseif Sekunda = 3 Then
    Set Przekaznik2
    End If
    Loop
    End
    Odmierz_1s:
    Load Timer0 , 250
    Incr Licz_8ms
    If Licz_8ms = 125 Then
    Incr Sekunda
    Licz_8ms = 0
    End If
     Return



    Dodano po 8 [minuty]:

    Rozwiązałem problem-Fusebity były źle ustawione.Dzięki Wam za pomoc.
  • #26
    zipp
    Level 14  
    marcinwrc2 wrote:

    Robię dwa proste urządzenia na at 2313 (czyli dwa osobne programiki), jeden załącza przekaźniki 2szt z opóźnieniem kolejno 25s i 30s po podaniu zasilania na układ.


    Czy ja czegoś nie rozumie? Po co timery? Chyba tylko po to, żeby się czegoś nauczyć.
    Jeżeli pierwszy przekaźnik ma się załączać po 25 sekundach od włączenia zasilania, a drugi po 30 sekundach i procesor nie ma nic innego wykonywać, to proponuję o wiele prostszy kod, wręcz trywialny i nie kombinować.
    Podaj też w deklaracji $crystal odpowiednią wartość, bo nie wierzę, że masz kwarc 0,8 MHz.

    Code:

    $crystal = 8000000
    Config Pind.0 = Output
    Config Pind.1 = Output
    Przekaznik1 Alias Portd.0
    Przekaznik2 Alias Portd.1

    Wait 25
    Set Przekaznik1
    Wait 5
    Set Przekaznik2

    Do
    Loop
  • #27
    janbernat
    Level 38  
    No i tak się wchodzi w ślepą uliczkę złych nawyków.
    Potem do tego programu dodaj cokolwiek.
    Wyświetlanie na LCD albo LED, odczyt temperatury albo czegokolwiek innego.
  • #28
    zipp
    Level 14  
    janbernat wrote:
    No i tak się wchodzi w ślepą uliczkę złych nawyków.


    No i tak ludzie komplikują sobie życie.
    Marcinwrc2 chce dwa razy klapnąć przekaźnikiem a wszyscy wyjeżdżają z przerwaniami. Za chwilę ktoś zaproponuje OS-a czasu rzeczywistego.
    Opanujcie się trochę.

    Quote:
    Potem do tego programu dodaj cokolwiek.


    A co może tam chcieć dodać? Trzeci przekaźnik? Widzisz w tym jakiś problem?
    Nic nie pisał o dodawaniu czegokolwiek. Była konkretna potrzeba i prosta odpowiedź.
  • #29
    emarcus
    Level 38  
    zipp wrote:
    marcinwrc2 wrote:

    Robię dwa proste urządzenia na at 2313 (czyli dwa osobne programiki), jeden załącza przekaźniki 2szt z opóźnieniem kolejno 25s i 30s po podaniu zasilania na układ.


    Czy ja czegoś nie rozumie? Po co timery? Chyba tylko po to, żeby się czegoś nauczyć.


    Bez urazy, .....
    Tak, nie rozumiesz bo nie czytasz do końca wypowiedzi, którą cytujesz.
    Cała myśl (to co Marcin chciał osiągnąć w tym ćwiczeniu) jest zawarta w ostatnim zdaniu jego pierwszego postu. Odszukaj i skonfrontuj.
    Po tym było co najmniej 2 tuziny różnych wypowiedzi, których nie zauważyłeś, a tymczasem Marcin nauczył się dużo. Wierzę że z czasem dowie się że istnieją inne tryby pracy timerów, że istnieją interrupty, które mógłby ewentualnie wykorzystać w drugiej części ćwiczenia; do wyłączenia przekaźnika, itd.
    Nawet wielcy i sławni pianiści zaczynali swoją karierę artystyczną od wystukania gamy C-dur na klawiaturze – nieprawdaż?
    A to że popełnił ‘lekki’ błąd podczas przepisywania zer (być może nawet nie kopiował) listingu z Bascom do swojego listu, oraz że wpisał w programie nieco inny processor niż faktycznie ma w tym ćwiczeniu, to odpuść to sobie, bo to jest w zasadzie bez większego znaczenia. Przecież napisał że osiągnął przynajmniej częściowy cel.

    e marcus
  • #30
    zipp
    Level 14  
    Wszystko co napisałeś jest prawdą. Nauczyliście Marcina jak stosować timery. Nie nauczyliście go tylko, kiedy trzeba je stosować. Ale to sobie sam może doczytać.
    Mam nadzieję, że rozumiesz o co mi chodzi.