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

[BASCOM] - Jak poprawnie i cyklicznie wyświetlać na LCD

02 Wrz 2010 23:27 4526 10
  • Poziom 39  
    Popełniłem taki oto kod jak poniżej. W założeniu ma to być zegarek stawiany pilotem, oraz z dwoma DS18B20.
    Założyłem sobie, że nie użyję żadnego Wait, ani Gosub.
    Mam jednak jeden problem z odświeżaniem czasu na LCD. Niby dwukropki migają co sekundę, ale sekundy nie są wyświetlane poprawnie. Przez pewien czas jest niby dobrze, ale czasem jakby pomija niektóre sekundy. Np jest 21,22,23,26,27,31 itp.

    Nie wiem jak to rozwiązać. Kompletne zaciemnienie jakieś mnie dopadło.
    Może mi coś doradzicie ? Może też znacie inne sposoby na cykliczne wyświetlanie
    na LCD używając sekundowegoprzerwania od timera ?

    Code:
    '$sim
    
    $regfile = "m8def.dat"
    $crystal = 8000000
    $hwstack = 64
    $swstack = 16
    $framesize = 32
    Config Pind.7 = Output                                      'przekaźnik
    Config 1wire = Portb.0
    Config Rc5 = Pind.2
    Config Timer1 = Timer , Prescale = 256
    Config Lcd = 16 * 1a
    Config Lcdpin = Pin , Db4 = Portb.1 , Db5 = Portb.2 , Db6 = Portb.3 , Db7 = Portb.4 , E = Portb.5 , Rs = Portc.5
    On Int0 Rc5get
    On Timer1 Odmierz_1s
    Dim Sekunda As Byte                                         'zmienne czasu
    Dim Minuta As Byte
    Dim Pauza As Byte
    Dim I As Byte
    Dim Godzina As Byte
    Dim Dsilosc As Integer
    Dim Tempa As Single
    Dim Tempw As Integer
    Dim Address As Byte                                         'adres RC5
    Dim Command As Byte                                         ' nr komendy RC5
    Dim Tekst1 As String * 10
    Dim Tekst2 As String * 10
    Dim Tgodzina As String * 4
    Dim Tminuta As String * 4
    Dim Tsekunda As String * 4
    Dim Dsadres1(8) As Byte
    Dim Dsadres2(8) As Byte
    Dim Lsb As Byte
    Dim Msb As Byte
    Dim Rc5flag As Bit                                          'zmienna isr INT0
    Dim Capture As Bit
    Dim Odd As Bit                                              'zmienna zmieniająca stan na przeciwny co 1 s
    Dim Show As Bit
    Dim Wyswietlanie As Byte

    Enable Timer1
    Enable Int0
    Enable Interrupts
    Cursor Off Noblink
    Counter1 = 34286

    '-----------------------Inicjalizacja czujnikow---------------------------------
    'Dsilosc = 1wirecount()
    'If Dsilosc = 2 Then
    '   Lcd "Czujniki obecne"
    ' Else
    '   Lcd "Brak czujnika"
    'End If
    Dsadres1(1) = 1wsearchfirst()
    1wverify Dsadres1(1)
    If Err = 1 Then
       Lcd "Brak czujnika"
       Err = 0
    End If


    For I = 1 To 8
    Lcd Hex(dsadres1(i))
    Next
    Dsadres2(1) = 1wsearchnext()
    1wverify Dsadres2(1)
    If Err = 1 Then
       Lcd "Brak czujnika"
       Err = 0
    End If
    'Deflcdchar 0 , 2 , 5 , 5 , 2 , 32 , 32 , 32 , 32            ' replace ? with number (0-7)

    '----------------------Pętla główna---------------------------------------------
    Do
    If Odd = 0 And Capture = 0 Then
       Disable Int0
       1wreset
       1wwrite &HCC                                             'skip ROM
       1wwrite &H44
       Capture = 1
       Enable Int0
    End If                                                      'start konwersji
    If Odd = 1 And Capture = 1 Then                             'sprawdzanie flagi
       Disable Int0
       1wreset
       1wwrite &H55
       1wwrite Dsadres1(1) , 8
       1wwrite &HBE
       Tempw = 1wread(2)
       Tempw = Tempw * 10
       Tempw = Tempw / 16
       Tekst1 = Str(tempw)
       Tekst1 = Format(tekst1 , "+0.0")

       1wreset
       1wwrite &H55
       1wwrite Dsadres2(1) , 8
       1wwrite &HBE
       Tempw = 1wread(2)
       Tempw = Tempw * 10
       Tempw = Tempw / 16
       Tekst2 = Str(tempw)
       Tekst2 = Format(tekst2 , "+0.0")
       1wreset
       Capture = 0
       Enable Int0
    End If



    If Rc5flag = 1 Then                                         'odbior RC5
    Getrc5(address , Command)
    If Address = 5 Then
         Command = Command And &B01111111
    End If
       Select Case Command                                      'ustawianie czasu pilotem
          Case 32 : Incr Godzina
          Case 33 : Decr Godzina
          Case 16 : Incr Minuta
          Case 17 : Decr Minuta
          Case 12 : Toggle Portd.7
          Case 13 : Sekunda = 0
          Case 1 : Incr Wyswietlanie


       End Select
     Reset Rc5flag
     Command = 0
    End If
        Tgodzina = Str(godzina)                                 'zmiana liczb na tekst
        Tminuta = Str(minuta)
        Tsekunda = Str(sekunda)
        Tgodzina = Format(tgodzina , "00")
        Tminuta = Format(tminuta , "00")
        Tsekunda = Format(tsekunda , "00")

    If Wyswietlanie = 0 Then                                    'wyświetlanie na LCD
      If Odd = 0 And Show = 0 Then                              '
          Cls
          Lcd "W " ; Tekst1 ; " " ; "Z " ; Tekst2

          Set Show

          Elseif Odd = 1 And Show = 1 Then
          Cls
    '   Lcd "Z " ; Tekst2 ; Chr(0) ; "C"
          Lcd "   " ; Tgodzina ; ":" ; Tminuta ; ":" ; Tsekunda
          Reset Show
      End If

    End If
    If Wyswietlanie = 1 Then

        If Odd = 0 And Show = 0 Then
           Cls
           Lcd "W " ; Tekst1 ; " " ; "Z " ; Tekst2
          Set Show
        Elseif Odd = 1 And Show = 1 Then
          Cls
          Lcd "W " ; Tekst1 ; " " ; "Z " ; Tekst2
          Reset Show

        End If
    End If

    If Wyswietlanie = 2 Then                                    'wyświetlanie czasu na LCD
       If Odd = 0 And Show = 0 Then                             ' w założeniu miało wyświetlać na przemian co sekundę


          Set Show                                              'no i "niby działa" ale sekundy są dziwne
          Cls
          Lcd "   " ; Tgodzina ; ":" ; Tminuta ; ":" ; Tsekunda 'ale czas generowany jest dobry

       Elseif Odd = 1 And Show = 1 Then                         ' i na dobę nie różni się nawet o sekundę
          Cls
          Reset Show
          Lcd "   " ; Tgodzina ; " " ; Tminuta ; " " ; Tsekunda

       End If
    End If

    Enable Int0
    If Wyswietlanie = 3 Then
    Wyswietlanie = 0
    End If

    Loop
    End
    '---------------------------Koniec pętli ---------------------------------------

    '--------------------------Obsługa Isr timera1 ---------------------------------
    Odmierz_1s:
     Counter1 = Counter1 + 34286

    Incr Sekunda
    Toggle Odd                                                  ' tego używam do wykrywania zmian sekundy
    If Sekunda >= 60 Then
          Sekunda = 0
          Incr Minuta

    End If

    If Minuta >= 60 Then
          Minuta = 0
          Incr Godzina

    End If

    If Godzina >= 24 Then
       Godzina = 0
    End If
    Return
    '-----------------------Odbiór RC5----------------------------------------------
    Rc5get:
    Disable Int0
    Enable Interrupts
    Set Rc5flag
    Return
  • Relpol przekaźniki
  • Pomocny post
    Poziom 38  
    Masz waitms- tylko ukryte.
    Każdy Cls musi mieć przynajmniej 2ms.
    A nie wiem czy w Bascomie nie więcej- na zapas.
    Jeśli masz oscyloskop- to wstaw na końcu pętli do-loop jakiś toogle na któryś pin i zmierz czas.
    A w przerwaniu Odmierz1s użyj CTC i tylko ustaw jakąś flagę.
    I wyrzuć wszystkie obliczenia do głównej pętli.
  • Relpol przekaźniki
  • Pomocny post
    Poziom 27  
    Twoim podstawowym błędem jest to że ciągle czyścisz ekran. Ta operacja zajmuje prawie 2 ms Nie wiem po co to robisz ? Wystarczy zdefiniować bufor w który bedziesz wpisywać swoje wyniki i ten bufor cyklicznie wyświetlać ale tylko wtedy kiedy to będzie konieczne czyli w zależności od ustwienia ew. flag sygnalizujących np. zmianę czasu. Inna sprawa czy dokładność upływu czasu rzędu 1 sekundu jest tobie do czegokolwiek potrzebna ? Nie zdążysz tego nawet zanotować :) Ja nie jestem specem od bascoma ale tam mi się zdaje że jeśli czas służy tylko do jego wyświetlenie to zbędną jest zamiana (str) na wartość tekstową wystarczy z każdą zmianą sekund,minut i godzin (bo zdaje się że sam ten czas sobie obliczasz co sekundę a nie pobierasz z jakiegoś układu RTC) zwiększyć wartość w buforze tekstowym na miejscu odpowiadającym odpowiednim cyfrą. Wyjdzie na to samo a nie bedzie trzeba dokonywać ciągłej zamiany.
  • Poziom 39  
    O dziwo po dobie testowania, tak naprawdę czas nie różnił się ani sekundę.
    Jedynie wyświetlanie szwankuje.
    Chciałbym jednak użyć CTC, ale kompletnie nie wiem jak się za to zabrać w Bascomie. Nie znalazłem na forum żadnych przykładów.

    Co do dziwnego wyświetlania to chyba właśnie będzie problem przekształcania zmiennych czasu na tekst. Poszedłem po łatwości, bo łatwiej jest formatować zmienne tekstowe by je wyświetlić.
    Jak by ktoś poczęstował przykładem kodu dla z CTC w Bascom to byłbym niezmiernie wdzięczny :)
  • Pomocny post
    Poziom 36  
    xury napisał:

    Chciałbym jednak użyć CTC, ale kompletnie nie wiem jak się za to zabrać w Bascomie. Nie znalazłem na forum żadnych przykładów.

    Jak by ktoś poczęstował przykładem kodu dla z CTC w Bascom to byłbym niezmiernie wdzięczny :)


    Jakieś kilka dni temu, nie dłużej jednak niż tydzień, ‘gaskoin’ podal dokładną procedurę konfiguracji CTC. Jeżeli przeoczyłeś ten temat to go odszukaj. Nie ma potrzeby tego powtarzać. /Nie pamiętam tematu.
    Przykładowy program wygląda mniej więcej tak:

    Code:

    '1 second code

    $regfile = "m8def.dat"   ' or "m88def.dat"  or "m168def.dat"
    $crystal = 4000000
    $baud = 9600

    $hwstack = 32
    $swstack = 16
    $framesize = 40

    Dim Seconds_count As Long

    ' ===================================================
    '  Timer1 initialization
    '
    '  Mode: Clear Timer1 on Compare Match (CTC mode TOP = OCR1A)
    '  System clock: 4 MHz
    '  Clock source: I/O Clock / 256

    TCCR1A = &H00  'See datasheet for details
    TCCR1B = &H0C  'See datasheet for details

    ' In CTC mode the counter is cleared to zero when
    ' the counter value (TCNT1) matches OCR1A.
    ' We will load the value 0x3D09 (15625) in OCR1A so that
    ' we will have an interrupt every second.

    OCR1AH = &H3D  'Set OCR1A.
    OCR1AL = &H09  'Set OCR1A.

    On Oc1a Oc1a_isr
    Enable Compare1a

    ' Reset the Timer1 count
    TCNT1H = &H00 'Set Timer1 count to 0
    TCNT1L = &H00 'Set Timer1 count to 0

    Enable Interrupts

    Do

      Print "Elapsed seconds: " ; Seconds_count
      Waitms 250

    Loop

    End

    ' ===================================================
    ' Timer1 Compare Match Interrupt service routine
    Oc1a_isr:

       Incr Seconds_count

       If Seconds_count >= 86400 Then   '86400 seconds = 1 day
          Seconds_count = 0
       End If


    Return
    ' ==================================================



    Reszta jest w Datasheet

    e marcus
  • Pomocny post
    Poziom 38  
    No,ale nie podałeś jaki procesor.
    W Bascomie można ustawić rejestry Timera "ręcznie"- a nie przez config.
    Zamiast czegoś takiego:
    "TCCR1A = &H00 'See datasheet for details
    "TCCR1B = &H0C 'See datasheet for details
    można ustawić to po "bascomowemu"- patrząc w DS.
    set TCCR1A.cs12
    set TCCR1A.wgm12
    Itp.
    Zamiast config ustawiasz poszczególne bity w rejestrach i masz dostęp do wszystkich ustawień procesora- i chodzi jak chcesz.
    W timerach, ADC i we wszystkim.
    Ale DS jest najważniejszy.
  • Poziom 16  
    Pozwolę przyłączyć się do tematu. Przeglądając kod natrafiłem na deklaracje zmiennych w dziwny sposób

    Dim Tekst1 As String * 10
    Dim Tekst2 As String * 10
    Dim Tgodzina As String * 4
    Dim Tminuta As String * 4
    Dim Tsekunda As String * 4

    Co oznaczają te znaki mnożenia? Czy można z takimi zmiennymi wykonywać operacje arytmetyczne jeśli tak to jak? ja jak biorę w bascomie np.
    tekst1=tekt1*2
    to wyskoczy błąd.
    Z góry dzięki.[code]
  • Moderator na urlopie...
    Te deklaracje (gdyby Kolega otworzył choćby na moment manuala) to deklaracje łańcuchów znakowych (tekstów) a liczby po gwiazdce oznaczają maksymalną długość napisu + 1 (znak zerowy zakończenia tekstu), czyli np. w zmiennej Tekst1 można zapisać maksymalnie 9 znaków. Oczywiście na tekstach NIE MOŻNA dokonywać operacji matematycznych. Jedyne co można robić to "dodawać" teksty, czyli łączyć je ze sobą, np:
    Code:

    Dim S As String * 20
    Dim A As String * 6
    Dim B As String * 6
    A="Piotr"
    B=" ABC"
    S=A+B
    'po tym zapisie zmienna S będzie zawierać napis Piotr ABC
  • Poziom 36  
    piotrva napisał:
    Te deklaracje (gdyby Kolega otworzył choćby na moment manuala) to deklaracje łańcuchów znakowych (tekstów) a liczby po gwiazdce oznaczają maksymalną długość napisu + 1 (znak zerowy zakończenia tekstu), czyli np. w zmiennej Tekst1 można zapisać maksymalnie 9 znaków.
    [/code]


    - czyli np. w zmiennej Tekst1 można zapisać maksymalnie 10 znaków (!)
    Zajmie to w pamięci 11 bytes.
    Wpisując np. do EEPROM zmieną STRTING o długości 10 i rozpoczynając od pamięci loc. 1, to kolejna zmienną można wpisać do loc.12.

    e marcus