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

Zegar - problem z odświeżaniem wyswietlacza

jaroslawk 22 Wrz 2007 18:04 1586 14
  • #1 22 Wrz 2007 18:04
    jaroslawk
    Poziom 21  

    Witam,
    Jestem początkujący w technice mikroprocesorowej. Napisałem program zegara z PCF8583. Na wyświetlaczu pojawia się godzina (godzina, minuta sekunda) ale widać jakby to skakało. Jak się przyjrzeć to widać jak po kolei pojawiają się cyfry. Czy jest jakaś możliwość przyśpieszenia odświeżania wyświetlacza tak aby pokazywana godzina sprawiała złudzenie ze jest na stałe. W chwili obecnej sekundy pokazywane są (przeskakuja)co 2 lub3.

    Mój zestaw to Atmega 162. Mam domyślne fusebit.

    Pozdrawiam

    Code:
    $regfile = "m162def.DAT"
    
    $crystal = 8000000
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.3 , Rs = Portb.2
    Config Sda = Porta.0
    Config Scl = Porta.1

    Declare Sub Odczyt_rtc(sekundy As Byte , Minuty As Byte , Godziny As Byte)
    Declare Sub Wyswietl

    Dim Sekundy As Byte
    Dim Minuty As Byte
    Dim Godziny As Byte


    Do
    Call Odczyt_rtc(sekundy , Minuty , Godziny)
    Waitms 50
    Call Wyswietl

    Loop
    End

    Sub Odczyt_rtc(sekundy As Byte , Minuty As Byte , Godziny As Byte)
       I2cstart
       I2cwbyte 160
       I2cwbyte 2
       I2cstart
       I2cwbyte 161
       I2crbyte Sekundy , Ack
       I2crbyte Minuty , Ack
       I2crbyte Godziny , Nack
       I2cstop
    Sekundy = Makedec(sekundy)
    Minuty = Makedec(minuty)
    Godziny = Makedec(godziny)
    End Sub

    Sub Wyswietl
    Cls
    Cursor Off
    Lcd "TIME " ; Godziny ; ":" ; Minuty ; ":" ; Sekundy
    End Sub

    0 14
  • Pomocny post
    #2 22 Wrz 2007 18:15
    mariuz
    Poziom 32  

    Spróbuj w drugiej linijce

    Code:

    $crystal = 1000000

    Większość mniejszych atmeli ma standardowo fusy ustawione na 1MHz, ale nie dam głowy jak to jest z ATM162 ;)

    0
  • #3 22 Wrz 2007 18:21
    jaroslawk
    Poziom 21  

    Który kwadracik zaznaczyć aby działał z zewnętrznym rezonatorem kwarcowym?.

    0
  • Pomocny post
    #4 22 Wrz 2007 18:21
    crazy_phisic
    VIP Zasłużony dla elektroda

    Zamiast polecenia "Cls" wykorzystaj "Locate x.y".

    0
  • Pomocny post
    #5 22 Wrz 2007 18:33
    mariuz
    Poziom 32  

    Przestawiać na zewnętrzny rezonator jeszcze się nie nauczyłem, a już parę układów popełniłem ;)

    Poszukaj na samej górze działu są poradniki ;) Mi to jeszcze nie było potrzebne do szczęścia

    0
  • Pomocny post
    #6 22 Wrz 2007 18:41
    crazy_phisic
    VIP Zasłużony dla elektroda

    Jeśli upierasz się przy 8MHz wtedy musisz "zanegować/odhaczyć" informacje przy bicie CKDIV8. Albo po prostu zmień deklaracje w programie na 1MHz.

    0
  • #7 22 Wrz 2007 19:21
    jaroslawk
    Poziom 21  

    Witam,
    Wszystko zaczęło działać. Metody są dwie. Pierwsza to ustawienie

    Code:
    $crystal = 1000000
    Drugie rozwiązanie to ustawienie pracy z zewnętrznym generatorem
    Code:
     w fusebit CKDIV8 trzeba odhaczyć ptaszek


    pozdrawiam

    0
  • Pomocny post
    #8 22 Wrz 2007 20:28
    Mad Bekon
    Poziom 23  

    Ja mam jeszcze taką dodatkową propozycję.
    Sprawdzaj zawartość wyświetlacza. Jeśli się nie zmienia to jej nie nadpisuj na nowo. Po Co?

    I tak jak Crazy Physic napisał, CLS zmień na Locate.

    0
  • #9 22 Wrz 2007 21:16
    BoskiDialer
    Poziom 34  

    Nie znam się na bascomie, ale widze, że wartości odczytane z zegarka są przypisywane do zmiennych, które są argumentami funkcji. Jeśli argumenty przekazywane są przez wartość, to wtedy dane z zegarka zostaną wpisane do lokalnych kopii tych zmiennych, przy kończeniu funkcji zostaną utracone. Jak wygląda przekazywanie zmiennych przez referencję? Jest coś takiego? Bascom jest case-sensitive? Jeśli tak, to wtedy tylko globalna zmienna "Sekundy" będzie aktualizowana (jeśli przekazywanie przez wartość). Co do skakania - nadpisywać wartości zamiast czyścić i wpisywać.

    0
  • Pomocny post
    #10 22 Wrz 2007 21:23
    crazy_phisic
    VIP Zasłużony dla elektroda

    Domyślnie w Bascomie parametry przekazywane są przez referencje, chyba że w deklaracji funkcji/podprogramu wykorzysta się parametr "byval".

    0
  • #11 23 Wrz 2007 09:45
    jaroslawk
    Poziom 21  

    Czy może mi ktoś napisać w/w program tak jako powinien być napisany.

    Faktycznie Locate x,y poprawiło komfort wyświetlania. Wyświetlacz nie miga, czas jest pokazywany bardzo płynnie. Pojawił się problem z wyświetlaniem pojedynczych cyfr. Jeżeli cyfra jest pojedyncza to wyświetlana jest wartość cyfry podwójnej. Jak napisać mechanizm aby dodawał do np. 1 wartość 01.

    Może mi ktoś wytłumaczyć jaka jest różnica pomiędzy przekazywania referencją a przekazywaniem przez wartość.

    Code:

    $regfile = "m162def.DAT"
    $crystal = 8000000
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.3 , Rs = Portb.2
    Config Sda = Porta.0
    Config Scl = Porta.1

    Declare Sub Odczyt_rtc

    Dim Sekundy As Byte
    Dim Minuty As Byte
    Dim Godziny As Byte

    Cls
    Lcd "TIME "

    Do
    Call Odczyt_rtc
    Locate 1 , 7
    Cursor Off
    Lcd Godziny ; ":" ; Minuty ; ":" ; Sekundy

    Loop
    End

    Sub Odczyt_rtc
       I2cstart
       I2cwbyte 160
       I2cwbyte 2
       I2cstart
       I2cwbyte 161
       I2crbyte Sekundy , Ack
       I2crbyte Minuty , Ack
       I2crbyte Godziny , Nack
       I2cstop
    Sekundy = Makedec(sekundy)
    Minuty = Makedec(minuty)
    Godziny = Makedec(godziny)
    End Sub

    0
  • Pomocny post
    #12 23 Wrz 2007 09:59
    crazy_phisic
    VIP Zasłużony dla elektroda

    Polecenie "Cursor off" możesz umieścić przed pętlą "Do - loop", przecież wyłączasz go tylko raz.
    Polecenie "Locate" możesz zastosować do każdej zmiennej - "Godziny", "Minuty", "Sekundy". Sprawdzasz przed wyświetleniem czy zmienna jest mniejsza od 10, jeśli tak ustawiasz odpowiednią pozycję za pomocą "Locate x.y" i wyświetlasz. Jeśli nie to wyświetlasz w domyślnym miejscu.

    Inny sposób to skorzystanie z funkcji "Space". Szczegóły jak zwykle w pliku pomocy.

    0
  • Pomocny post
    #13 23 Wrz 2007 13:53
    zumek
    Poziom 39  

    crazy_phisic napisał:
    ... Sprawdzasz przed wyświetleniem czy zmienna jest mniejsza od 10, jeśli tak ustawiasz odpowiednią pozycję za pomocą "Locate x.y" i wyświetlasz. Jeśli nie to wyświetlasz w domyślnym miejscu.

    Sposób dobry, tylko trochę kłopotliwy(ciągłe porównywanie zmiennych) :(
    Inny sposób to:
    Code:

    'Zmienne odczytane z PCF-a i skonwertowane instrukcją makedec() .
          Lcd Hex(makebcd(Godziny)) ; ":" ; Hex(makebcd(Minuty)) ; ":" ; Hex(makebcd(Sekundy));

    'Zmienne odczytane bezpośrednio z PCF-a ( BCD )
          Lcd Hex(Godziny) ; ":" ; Hex(Minuty) ; ":" ; Hex(Sekundy);


    Piotrek

    0
  • #14 23 Wrz 2007 22:53
    jaroslawk
    Poziom 21  

    Zegar działa poprawnie. Zarówno odczyt jak i ustawianie. Jak można w Bascom’ie zrobić Menu. Planuje rozbudowę o funkcje temperatury , daty, budzika i chciałbym mieć te funkcje ustawiane z menu.

    Code:

    $regfile = "m162def.DAT"
    $crystal = 8000000
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.3 , Rs = Portb.2
    Config Sda = Porta.0
    Config Scl = Porta.1

    Declare Sub Odczyt_rtc_pcf8583(sekundy As Byte , Minuty As Byte , Godziny As Byte)
    Declare Sub Zapisz_rtc_pcf8583(sekundy_zapisz As Byte , Minuty_zapisz As Byte , Godziny_zapisz As Byte)

    Dim Sekundy As Byte
    Dim Minuty As Byte
    Dim Godziny As Byte
    Dim Sekundy_zapisz As Byte
    Dim Minuty_zapisz As Byte
    Dim Godziny_zapisz As Byte
    Dim Blok_m As Bit
    Dim Blok_g As Bit

    Cursor Off
    Cls

    ' Petla glowna programu '
    Do
    Call Odczyt_rtc_pcf8583(sekundy , Minuty , Godziny)
    Locate 1 , 1
    Cursor Off
    Lcd Hex(makebcd(godziny)) ; ":" ; Hex(makebcd(minuty)) ; ":" ; Hex(makebcd(sekundy));

    If Pina.2 = 0 Then
    Gosub Menu
    End If
    Loop
    End


    Menu:

                Call Odczyt_rtc_pcf8583(sekundy , Minuty , Godziny)
                Minuty_zapisz = Minuty
                Godziny_zapisz = Godziny
                Cls
                Do
                If Pina.3 = 0 And Blok_m = 0 Then
                   Incr Minuty_zapisz
                   Blok_m = 1
                End If
                If Pina.3 = 1 Then Blok_m = 0

                If Pina.4 = 0 And Blok_g = 0 Then
                   Incr Godziny_zapisz
                   Blok_g = 1
                End If
                If Pina.4 = 1 Then Blok_g = 0

                Locate 1 , 1
                Lcd "Zegar SETUP "
                Locate 2 , 0
                Lcd "TIME " ; Hex(makebcd(godziny_zapisz)) ; ":" ; Hex(makebcd(minuty_zapisz))
                If Godziny_zapisz = 24 Then Godziny_zapisz = 0
                If Minuty_zapisz = 60 Then Minuty_zapisz = 0
                If Pina.5 = 0 Then
                Call Zapisz_rtc_pcf8583(sekundy_zapisz , Minuty_zapisz , Godziny_zapisz)
                Cls
                Return
                End If
                Loop



    ' Odczty godziny z układu PCF 8583 '
    Sub Odczyt_rtc_pcf8583(sekundy As Byte , Minuty As Byte , Godziny As Byte)
       I2cstart
       I2cwbyte 160
       I2cwbyte 2
       I2cstart
       I2cwbyte 161
       I2crbyte Sekundy , Ack
       I2crbyte Minuty , Ack
       I2crbyte Godziny , Nack
       I2cstop
       Sekundy = Makedec(sekundy)
       Minuty = Makedec(minuty)
       Godziny = Makedec(godziny)
    End Sub


    ' Zapis godziny do ukladu PCF8583
    Sub Zapisz_rtc_pcf8583(sekundy_zapisz As Byte , Minuty_zapisz As Byte , Godziny_zapisz As Byte)
        Sekundy_zapisz = Makebcd(sekundy_zapisz)
        Minuty_zapisz = Makebcd(minuty_zapisz)
        Godziny_zapisz = Makebcd(godziny_zapisz)
        I2cstart
        I2cwbyte 160
        I2cwbyte 0
        I2cwbyte 6
        I2cstop
        I2cstart
        I2cwbyte 160
        I2cwbyte 2
        I2cwbyte Sekundy_zapisz
        I2cwbyte Minuty_zapisz
        I2cwbyte Godziny_zapisz
        I2cstop
    End Sub

    0
  • Pomocny post
    #15 26 Wrz 2007 11:27
    Jdsoul
    Poziom 23  

    Żeby zrobić menu - potrzebujesz dodać kolejne funkcje obsługi odczytu i wyświetlania temperatury. Obsługę wyświetlania i poruszania się po menu itd.

    Ponadto istniejącą procedure obsługi PCF musisz rozszerzyć o procedury odczytu i zapisu daty oraz obsługę budzika.

    Kolejna sprawa to wprowadzenie przerwań. Tzn. Ustawiasz w PCF odpoowiednią datę budzika i podłączasz do procesora wyjścia INT z PCF .

    W obsłudze tego przerwania możesz wykonać jakiś alarm i czekać na skasowanie alarmu {np. rzut budzikiem o ziemię ADXL 102 jak znalazł - mierzysz przyspieszenie i siłę uderzenia o podłogę - jak za słabo machnięty to jeszcze raz :)}.

    Na pewno byłoby wskazane albo rozbudowanie obsługi klawiatury, albo wprowadzenie klawisza Menu i klawisza kasowania Alarmu :)

    0