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.

Poszukuje sprawny zegar [Bascom][Atmega8]

biglolo94 27 Mar 2010 20:55 7451 15
  • #1
    biglolo94
    Level 16  
    Witam wszystkich,

    Tak jak w temacie:
    Poszukuje sprawnego programu aby zrobić zegar LCD na ATMEGA8. Program musi być w języku bascom.

    Znalazłem coś takiego ale nie działa :/
    Opoźnienie sekundy wynois jakies 4s


    Code:
    'Program zegara wykorzystującego przerwania od Timer1 
    
    'Przerwanie przepełnienia Timer1 jest generowane co 1 s
    '8 MHz/256/31250 = 1 s
    'Przycisk S1 ustawia minuty, a S2 godziny

    $regfile = "m8def.dat"                                      'informuje kompilator o pliku
          'dyrektyw mikrokontrolera
    $crystal = 8000000                                          'informuje kompilator
          'o częstotliwości oscylatora
          'taktującego mikrokontroler
    Config Pinb.1 = Input                                       'linia PB1 jako wejściowa
    Config Pinb.2 = Input                                       'linia PB2 jako wejściowa
    Config Lcd = 16 * 2                                         'konfiguracja typu wyświetlacza
          'LCD
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5       'konfiguracja linii
          'mikrokontrolera, do których
          'dołączono wyświetlacz
          'LCD
    Config Timer1 = Timer , Prescale = 256
          'konfiguracja Timer1 jako timer
          'z podziałem preskalera przez
          '256

    Declare Sub Wysw_czas                                       'procedura wyświetlająca czas na
          'LCD w formacie gg:mm:ss
    On Timer1 Odmierz_1s                                        'przerwanie od przepełnienia
          'Timer1 o etykiecie Odmierz_1s



    Dim Sekundy As Byte                                         'zmienna zliczająca sekundy
    Dim Minuty As Byte                                          'zmienna zliczająca minuty
    Dim Godziny As Byte                                         'zmienna zliczająca godziny
    Dim Nowa_w As Bit                                           'flaga zezwolenia aktualizacji
          'czasu na LCD
    Dim Wart_bcd As Byte                                        'zmienna pomocnicza, w której
          'jest zapisywana wartość BCD
          'czasu

    S1 Alias Pinb.2                                             'przypisanie nazwie Pinb.2
          'nazwy S1
    S2 Alias Pinb.1                                             'przypisanie nazwie Pinb.1
          'nazwy S2

    Enable Interrupts                                           'odblokowanie globalnego systemu
          'przerwań
    Enable Timer1                                               'odblokowanie przerwania od
          'przepełnienia Timer1
    Counter1 = 34286                                            'wartość początkowa wpisywana do
          'Timer1 (65536 - 31250 = 34286)

    Set Nowa_w                                                  'zezwolenie na wyświetlenie
          'aktualnego czasu
    Set Portb.1                                                 'dołączenie do linii PB1
          'rezystora podciągającego
    Set Portb.2                                                 'dołączenie do linii PB2
          'rezystora podciągającego
    Do                                                          'pętla główna programu
     Call Wysw_czas                                             'wywołanie procedury
          'wyświetlającej aktualny czas
     If S1 = 0 Then                                             'jeśli przyciśnięty S1, to
      Waitms 25                                                 'opóźnienie dla eliminacji drgań
          'styków
      If S1 = 0 Then                                            'sprawdzenie, czy przycisk S1
          'dalej naciśniety, jeśli tak, to
       Incr Minuty                                              'zwiększenie wartości minut
       Sekundy = 0                                              'wyzerowanie zmiennej Sekundy
       If Minuty = 60 Then                                      'jeśli wartość Minuty = 60, to
        Minuty = 0                                              'zerowanie wartości Minuty
       End If
       Set Nowa_w                                               'zezwolenie na wyświetlenie
          'czasu
       Call Wysw_czas                                           'wywołanie procedury
          'wyświetlenia aktualnego czasu
       Waitms 200                                               'opóźnienie 200 ms
      End If                                                    'koniec instrukcji warunkowej
     End If
     If S2 = 0 Then                                             'jeśli przyciśnięty S2, to
      Waitms 25                                                 'opóźnienie dla eliminacji drgań
          'styków
      If S2 = 0 Then                                            'sprawdzenie czy przycisk S2
          'dalej naciśniety, jeśli tak, to
       Incr Godziny                                             'zwiększenie wartości Godziny
       If Godziny = 24 Then                                     'jeśli wartość Godziny = 24, to
        Godziny = 0                                             'wyzerowanie wartości Godziny
       End If
       Set Nowa_w                                               'zezwolenie na wyświetlenie
          'czasu
       Call Wysw_czas                                           'wywołanie procedury
          'wyświetlenia aktualnego czasu
       Waitms 200                                               'opóźnienie 200 ms
      End If                                                    'koniec instrukcji warunkowej
     End If
    Loop
    End                                                         'koniec programu


    Sub Wysw_czas                                               'procedura wyświetlająca czas
     If Nowa_w = 1 Then                                         'jeśli flaga Nowa_w = 1, to
      Cls                                                       'czyszczenie LCD
      Wart_bcd = Makebcd(godziny)                               'zamiana wartości Godziny na
          'wartość w kodzie BCD
      Lcd Bcd(wart_bcd) ; ":"                                   'wyświetlenie wartości godzin
          'w kodzie BCD zamienionych na
          'tekst oraz znaku :
      Wart_bcd = Makebcd(minuty)                                'zamiana wartości Minuty na
          'wartość BCD
      Lcd Bcd(wart_bcd) ; ":"                                   'wyświetlenie wartości minut
          'w kodzie BCD zamienionych na
          'tekst oraz znaku :
      Wart_bcd = Makebcd(sekundy)                               'zamiana wartości Sekundy na
          'wartość w kodzie BCD
      Lcd Bcd(wart_bcd) ;                                       'wyświetlenie wartości sekund
          'w kodzie BCD zamienionych na
          'tekst
      Reset Nowa_w                                              'zerowanie flagi Nowa_w
     End If
    End Sub                                                     'koniec procedury

    Odmierz_1s:                                                 'podprogramu obsługi przerwania
          'przepełnienia od Timer1
     Counter1 = Counter1 + 34286                                'wpisanie wartości początkowej
          'licznika
     Incr Sekundy                                               'zwiększenie o 1 wartości
          'Sekundy
     Set Nowa_w                                                 'zezwolenie na wyświetlenie
          'czasu
     If Sekundy = 60 Then                                       'jeśli Sekundy = 60, to
      Sekundy = 0                                               'wyzerowanie wartości Sekundy
      Incr Minuty                                               'zwiększenie o 1 wartości Minuty
      If Minuty = 60 Then                                       'jeśli Minuty = 60, to
       Minuty = 0                                               'zerowanie wartości Minuty
       Incr Godziny                                             'zwiększenie o 1 wartości
          'Godziny
       If Godziny = 24 Then                                     'jeśli Godziny = 24, to
        Godziny = 0                                             'zerowanie wartości Godziny
       End If                                                   'koniec warunków
      End If
     End If
    Return                                                      'powrót z przerwania


    Za działający program dam 15 Pkt

    Pozdrawiam
  • #2
    tadzik85
    Level 38  
    A z jakim kwarcem działa twój procesor.
  • #3
    biglolo94
    Level 16  
    Z wbudowanym ;) zewnetrznego nie dalem bo nie mam kondensatorow 33pF :D
  • #4
    tadzik85
    Level 38  
    Może masz w Fuse bitach ustawiony podział zegara przez 8.
  • #5
    biglolo94
    Level 16  
    mam na internal RC oscilator 1MHz - to jest fusebit A987

    To o ten chodzi ???
    mam go zmienic na 8 mHz ???
  • #6
    tadzik85
    Level 38  
    Ten zegarek taktowany jest zegarem procesora, kod jest poprawne wobec czego masz źle ustawiony zegar procesora w fusach. Dla lepszej dokładności wykorzystaj zewnętrzny kwarc. A obecnie poprawnie ustaw zegar wewnętrzny. procesor MUSI być taktowany 8MHz.
  • #7
    biglolo94
    Level 16  
    ok tadzik juz dziala :D
    Pomogles znaczy doradziles z tymi fusebitami
    Nalaeza ci sie te pkt ale jak bys jeszcze pomogl mi w polaczeniu tych kodow :

    Code:

    $regfile = "m8def.dat"                                      'informuje kompilator o pliku
          'dyrektyw mikrokontrolera
    $crystal = 8000000                                          'informuje kompilator
                                         'linia PB2 jako wejściowa
    Config Lcd = 16 * 1a                                        'konfiguracja typu wyświetlacza
          'LCD
    Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0       'konfiguracja linii


    Config 1wire = Portb.0

    Dim I1 As Integer , Ss As String * 6
    Dim I2 As Integer

    Dim Dsid1(8) As Byte
    Dim B As Byte                                               'deklaracja zmiennej do odczytu kodów ID
    Dim W As Byte                                               'deklaracja zmiennej do odczytu ilośc czujników

    Deflcdchar 0 , 8 , 20 , 11 , 4 , 4 , 4 , 3 , 32             'znak stopnia Celsjusza

    Cursor Off                                                  'Wyłącza kursor
    W = 1wirecount()
    Locate 2 , 1
    Lcd W
    Wait 2

    Cls                                                         'Znajdź pierwszy czujnik podpięty do portu
    Dsid1(1) = 1wsearchfirst()                                  'Znajdź kolejny czujnik podpięty do portu                                 'Znajdź kolejny czujnik podpięty do portu

                                                             'pętla główna programu

    If Dsid1(8) = Crc8(dsid1(1) , 7) Then                       'ta opcja pojawia się tylko przy włączaniu urządzenia
     Locate 2 , 1
     Lcd "Cz.1 OK  "
     Wait 2
     Locate 2 , 1
     For B = 1 To 8
     Lcd Hex(dsid1(b))
     Next
     Wait 2
     End If



     Do


     1wreset
       1wwrite &H55
       1wverify Dsid1(1)                                        'wysyłamy adres pierwszego czujnika
       1wwrite &HBE
       I1 = 1wread(2)
    ' - - - - - - - - - - - - - - -

    '--------konwersja temp dla wszystkich dsow
       1wreset
       1wwrite &HCC
       1wwrite &H44
    Wait 1
    '****** Wyswietlanie temperatury *****
       If W = 1 Then
       I1 = I1 * 10
       I1 = I1 / 16
       'If I1 > 0 Then Cls                                       'korekta przesuniecia znaku st C przy przejściu z temp ujemnej na dodatnią
       Ss = Str(i1)
       Ss = Format(ss , " 0.0")                                 'Pozycja wyświetlania nazwy i temperatury (1.1 -> 1 linia 1 kolumna, 2.10 -> 2 linia 10 kolumna itd)
       Locate 2 , 1
       Lcd "T: " ; Ss ; Chr(0) ;
       End If

    Loop
    End                                                         'koniec programu



    Tego i tamtego.
    Probuje ale nie dziala :/

    Posty scaliłem.
    [zumek]

    A co do programu zegarka to troche sie spieszy :/
    Znaczy co jakas godzine spieszy sie o kazde 5 minut .

    Moze zastosowanie zewnetznego kwarcu naprawiloby ten problem ???
    Jesli tak to jaki kwarc zastosowac ?
  • #8
    tadzik85
    Level 38  
    8MHz. Inną opcją jest kalibracja pracy licznika.
  • #9
    biglolo94
    Level 16  
    8MHz hmhmm

    ale skoro teraz mam ustawiona Atmege na 8MHz to czy jak dam 8Mhz na zewnatrz to bedzie OK ???

    A powiedz jak skalibrowac ten licznik ???
  • #10
    tadzik85
    Level 38  
    Wewnętrzny oscylator jest niedokładny. A licznik możesz skalibrować zmieniając wartość w następującej linii kodu:
    Code:
     Counter1 = Counter1 + 34286     


    oraz:
    Code:
     Counter1 = 34286  
  • #11
    biglolo94
    Level 16  
    OK

    Pokombinuje tym licznikiem moze pomoze a jesli nie to pozostaje mi dac zewnetrzny kwarc :/

    Naprawde mi pomogles na Twoje konto przelewam obiecane 15 PKT

    ale jak bys jeszcze pomogl polaczyc mi te dwa kody. Jak ja je lacze to cos nie dziala :/
  • #12
    tadzik85
    Level 38  
    Z tym połączeniem kodów nie jest tak hop hop, łatwiej napisać całość od nowa. A od dawna nie siedzę już w BASCOMIE.
  • #14
    sorex86
    Level 15  
    Na kwarcu 8Mhz zawsze będziesz miał nie dokładny zegar. Jak się bawiłem zegarem to na 40min koło 1s już przekłamywało.
    Byś musiał zainteresować się "REZONATOR KWARCOWY 32.768kHz ZEGARKOWY".

    Kwarc wewnętrzny jest strasznie niestabilny, daj sobie z nim spokój.


    Wpisz sobie w google:
    Bascom real time clock atmega


    Gdzieś na elektrodzie krąży taki kod, zacznij od niego
    Code:
    $regfile = "m8def.dat"
    
    $crystal = 8000000

    Config Lcdpin = Pin , Db4 = Portd.5 , Db5 = Portd.4 , Db6 = Portd.1 , Db7 = Portd.0 , E = Portd.6 , Rs = Portd.7
    Config Lcd = 16 * 2


    Dim Sek As Byte
    Dim Mint As Byte
    Dim Godz As Byte

    Config Timer1 = Timer , Prescale = 256
    Enable Interrupts
    Enable Timer1
    Timer1 = 32000
    On Timer1 Czas:
    Start Timer1

    Cls
    Cursor Off

    Sek = 0
    Lcd "" ; Godz ; ":" ; Mint ; ":" ; Sek ; " "
    Do

    'Incr Sek

    If Sek = 59 Then
    Sek = 0
    Incr Mint
    End If

    If Mint = 59 Then
    Mint = 0
    Incr Godz
    End If

    Loop Until Godz = 24

    Czas:
    Timer1 = 32000
    Incr Sek
    Cursor Off
    Cls

    Lcd "" ; Godz ; ":" ; Mint ; ":" ; Sek ; " "
    Return


    Jak nauczysz się poprawnie zliczać czas - stoper. Dopiero potem bierz się za dodawanie takich funkcji jak: ustawienia godziny, alarm itd
  • #15
    biglolo94
    Level 16  
    Znalazłem coś takiego:
    Link

    ale nie mam ani kwarcow ani magistrali RS232 , chyba jak by przerobic to na switche zeby nie bylo tej magistrali a kwarce moze jutro bym zalatwil
  • #16
    marcinosko
    Level 14  
    Witam ja dopiero zaczyna zabawe z avrami ale zegarek udało mi się zrobić może ci się przyda, tylko nie ma jeszcze ustawiania godziny, trzeba w programie ustwic aktualną i jest to na wewnętrznym kwarcu (mało dokładny ale do zabawy wystarczy) bo nie chciałem zepsuć sobie megi jak bym coś poplątał w fusbitach :D

    Code:

    $regfile = "m8def.dat"
    $crystal = 8000000

    Config Pind.0 = Output
    Config Pinb.1 = Input
    Config Pinb.2 = Input

    Set Portb.1
    Set Portb.2

    Up Alias Portb.1
    Down Alias Portb.2





    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Portc.3 , Db5 = Portc.2 , Db6 = Portc.1 , Db7 = Portc.0 , E = Portc.4 , Rs = Portc.5

    Config Timer0 = Timer , Prescale = 256
    Dim Licz_8ms As Byte
    Dim Godzina As Byte
    Dim Minuta As Byte
    Dim Sekunda As Byte
    Dim Dzien As Byte
    Dim Z As Byte
    Dim Y As Byte
    Dim Pozycja As Byte
    Dim Test As Byte



    Deflcdchar 0 , 31 , 31 , 32 , 32 , 32 , 32 , 32 , 32
    Deflcdchar 1 , 31 , 31 , 32 , 32 , 32 , 32 , 32 , 31
    Deflcdchar 2 , 31 , 31 , 31 , 31 , 31 , 31 , 31 , 31
    Deflcdchar 7 , 32 , 32 , 32 , 32 , 32 , 32 , 31 , 31
    Deflcdchar 3 , 32 , 32 , 32 , 32 , 14 , 14 , 14 , 32

    Cursor Off Noblink
    Minuta = 45
    Godzina = 23

    Sekunda = 0

    Cls
    Gosub Godzina

    On Timer0 Odmierz_1s

    Enable Interrupts
    Enable Timer0
    Load Timer0 = 250

    Do
    Loop
    End


    Godzina:
    Cls
    Gosub Wyswietl
    'Lcd Godzina ; ":" ; Minuta ; ":" ; Sekunda
    If Sekunda = 60 Then
       Incr Minuta
       Sekunda = 0
            If Minuta = 60 Then
            Minuta = 0
            Incr Godzina
                 If Godzina = 24 Then
                 Godzina = 0
                 Incr Dzien
                 End If
            End If
       End If
    Return


    Odmierz_1s:
    Load Timer0 = 250
    Incr Licz_8ms

    If Licz_8ms = 16 Then
       Licz_8ms = 0
       Sekunda = Sekunda + 1
       If Sekunda = 60 Then Gosub Godzina

    End If

    Return

    Wyswietl:
    Z = Godzina Mod 10
    Y = Godzina - Z
    Y = Y / 10
    Pozycja = 5
    Select Case Z
    Case 1 : Gosub Z1
    Case 2 : Gosub Z2
    Case 3 : Gosub Z3
    Case 4 : Gosub Z4
    Case 5 : Gosub Z5
    Case 6 : Gosub Z6
    Case 7 : Gosub Z7
    Case 8 : Gosub Z8
    Case 9 : Gosub Z9
    Case 0 : Gosub Z0
    End Select
    Pozycja = 1
    Select Case Y
    Case 1 : Gosub Z1
    Case 2 : Gosub Z2
    Case 3 : Gosub Z3
    Case 4 : Gosub Z4
    Case 5 : Gosub Z5
    Case 6 : Gosub Z6
    Case 7 : Gosub Z7
    Case 8 : Gosub Z8
    Case 9 : Gosub Z9
    Case 0 : Gosub Z0
    End Select
    Z = Minuta Mod 10
    Y = Minuta - Z
    Y = Y / 10
    Pozycja = 10
    Select Case Y
    Case 1 : Gosub Z1
    Case 2 : Gosub Z2
    Case 3 : Gosub Z3
    Case 4 : Gosub Z4
    Case 5 : Gosub Z5
    Case 6 : Gosub Z6
    Case 7 : Gosub Z7
    Case 8 : Gosub Z8
    Case 9 : Gosub Z9
    Case 0 : Gosub Z0
    End Select

    Pozycja = 14
    Select Case Z
    Case 1 : Gosub Z1
    Case 2 : Gosub Z2
    Case 3 : Gosub Z3
    Case 4 : Gosub Z4
    Case 5 : Gosub Z5
    Case 6 : Gosub Z6
    Case 7 : Gosub Z7
    Case 8 : Gosub Z8
    Case 9 : Gosub Z9
    Case 0 : Gosub Z0
    End Select

    Locate 1 , 9
    Lcd Chr(3)
    Locate 2 , 9
    Lcd Chr(3)



    Return

    Z1:
    Locate 1 , Pozycja
     Lcd Chr(0) ; Chr(2)
    Locate 2 , Pozycja
      Lcd Chr(7) ; Chr(2) ; Chr(7)
    Return

    Z2:
    Locate 1 , Pozycja
    Lcd Chr(0) ; Chr(1) ; Chr(2)
    Locate 2 , Pozycja
    Lcd Chr(2) ; Chr(7) ; Chr(7)
    Return

    Z3:
    Locate 1 , Pozycja
    Lcd Chr(1) ; Chr(1) ; Chr(2)
    Locate 2 , Pozycja
    Lcd Chr(7) ; Chr(7) ; Chr(2)
    Return

    Z4:
    Locate 1 , Pozycja
    Lcd Chr(2) ; Chr(7) ; Chr(2)
    Locate 2 , Pozycja
    Shiftcursor Right
    Shiftcursor Right
    Lcd Chr(2)
    Return

    Z5:
    Locate 1 , Pozycja
    Lcd Chr(2) ; Chr(1) ; Chr(0)
    Locate 2 , Pozycja
    Lcd Chr(7) ; Chr(7) ; Chr(2)
    Return

    Z6:
    Locate 1 , Pozycja
    Lcd Chr(2) ; Chr(1) ; Chr(0)
    Locate 2 , Pozycja
    Lcd Chr(2) ; Chr(7) ; Chr(2)
    Return

     Z7:
     Locate 1 , Pozycja
    Lcd Chr(0) ; Chr(2)
    Locate 2 , Pozycja
    Shiftcursor Right
    Lcd Chr(2)
    Return

    Z8:
    Locate 1 , Pozycja
    Lcd Chr(2) ; Chr(1) ; Chr(2)
    Locate 2 , Pozycja
    Lcd Chr(2) ; Chr(7) ; Chr(2)
    Return

    Z9:
    Locate 1 , Pozycja
    Lcd Chr(2) ; Chr(1) ; Chr(2)
    Locate 2 , Pozycja
    Lcd Chr(7) ; Chr(7) ; Chr(2)
    Return

    Z0:
    Locate 1 , Pozycja
    Lcd Chr(2) ; Chr(0) ; Chr(2)
    Locate 2 , Pozycja
    Lcd Chr(2) ; Chr(7) ; Chr(2)
    Return

    Return