Elektroda.pl
Elektroda.pl
X
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 7505 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


    '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 :

    
    $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 ???
  • #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
    $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

    
    $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