Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[atmega8][bascom avr] pcf8583,wyswietlacz siedmiosegmentowy

johnny318 10 Apr 2010 11:00 4368 9
  • #1
    johnny318
    Level 10  
    Witam! Od pewnego czasu usiłuje napisać program do obsługi zegara na pcf8583 i wyświetlaczach siedmiosegmentowych lecz bez efektu. Jest sporo tematów tego typu, ale większość zegarów realizowana jest na LCD. Główny problem polega na wyświetleniu czasu na wyświetlaczach 7segmentowych. Proszę o jakąkolwiek pomoc i podpowiedzi.

    Schemat układu:
    https://obrazki.elektroda.pl/13_1270837171.jpg

    Program:

    '*WEJSCIA I WYJSCIA*
    Config Portc = Output
    Portc = &HFF
    Config Portd = Output
    Portd = &HFF
    Config Portb = Output
    Portb = &HFF
    
    Config Pinb.2 = Input
    Pinb.2 = 1
    Config Pinb.3 = Input
    Pinb.3 = 1
    Config Pinb.4 = Input
    Pinb.4 = 1
    Config Pinb.5 = Input
    Pinb.5 = 1
    
    '*WYSWIETLACZE*
    W1 Alias Portc.3
    W2 Alias Portc.2
    W3 Alias Portc.1
    W4 Alias Portc.0
    
    '*PRZYCISKI*
    P_esc Alias Pinb.3
    P_ent Alias Pinb.2
    P_up Alias Pinb.5
    P_dwn Alias Pinb.4
    
    '*DIODY*
    Led_g Alias Portd.7
    Led_r Alias Portb.1
    Led_y Alias Portb.0
    
    '*****************************************
    
    
    $regfile = "m8def.dat"
    $crystal = 8000000
    
    Config Scl = Portc.5                                          'konfigurowanie linii scl
    Config Sda = Portc.4                                         'konfigurowanie linii sda
    Config Timer0 = Timer , Prescale = 8                    'konfiguracja Timer0 jako timer
    
    Declare Sub Pobr_znaku(cyfra As Byte)          'deklaracja procedury pobierajacej
                                                                  'kod cyfry do wyswietlenia z tablicy
    
    On Timer0 Multi_wysw                                'przerwanie od przepelnienia Timer0,
                                                                  'skok do podprogramu multi_wysw
    
    Dim A As Byte , B As Byte , 
          C As Byte , D As Byte                       'definicje zmiennych w ktorych bedzie
                                                         'przechowywana wartosc do wyswietlenia
    
    Dim Nr_wysw As Byte               'zmienna okreslajaca nr zapalonego wyswietlacza
    Dim Wartm As Byte                  'zmienna przechowujaca liczbe do wyswietlenia
    (minuty)
    
    Dim Warth As Byte                  'zmienna przechowujaca liczbe do wyswietlenia
    (godziny)
    
    Dim S As Byte                                   'deklaracja zmiennej okreslajacej sekundy
    Dim M As Byte                                   'deklaracja zmiennej okreslajacej minuty
    Dim H As Byte                                   'deklaracja zmiennej okreslajacej godziny
    
    Enable Interrupts                            'odblokowanie globalnego systemu przerwan
    
    Enable Timer0                                 'odblokowanie przerwania od Timer0
    
    Load Timer0 , 125                  'zaladowanie do licznika wartosci poczatkowej 131
    
    
    Do                                                'poczatek nieskonczonej petli
    
    I2cstart                                         'inicjalizacja magistrali i2c
    I2cwbyte 162                                 'podanie adresu pcf8583 dla zapisu
    I2cwbyte 2                                    'wybranie drugiego rejestru(sekund)
    I2cstart                                        'ponowna inicjalizacja magistrali
    I2cwbyte 163                                'podanie adresu pcf8583 dla odczytu danych
    I2crbyte S , Ack                            'odczyt sekund z potwierdzeniem transmisji
    I2crbyte M , Ack                            'odczyt minut z potwierdzeniem transmisji
    I2crbyte H , Nack                           'odczyt godzin bez potwierdzenia transmisji
    I2cstop                                         'koniec transmisji i2c
    
    A = M                         'wyswietlenie na pierwszym wyswietlaczu wartosci minut
    
    C = H                            'wyswietlenie na drugim wyswietlaczu wartosci godzin
    
    Wartm = Makebcd(m)       'zmiana wartosci zmiennej m na wartosc zapisana w kodzie bcd
    
    A = Wartm And &B00001111             'wyodrebnienie (przez maskowanie) i
    
    wyswietlenie pierwszej cyfry (jednostki minut) zapisanej w zmiennej wartm
    
    Shift Wartm , Right , 4                    'przesuniecie wartosci drugiej cyfry w
    
    zmiennej wartm na pozycje czterech mniej znaczacych bitow
    
    B = Wartm                      'wyswietlenie na drugim wyswietlaczu cyfry dziesiatek minut
    
    Warth = Makebcd(h)                          'podobnie jak wyzej tylko dla godzin
    C = Warth And &B00001111
    Shift Warth , Right , 4
    D = Warth
    
    Loop                                                 'koniec petli nieskonczonej
    End                                                  'koniec programu
    
    
    
    Sub Pobr_znaku(cyfra As Byte)                 'definicja procedury pobr_znaku
    
    If Cyfra < 10 Then
    Portd = Lookup(cyfra , Kody7seg)
    Else
    Portd = 255                                       'w przeciwnym razie wygas wyswietlacz
    End If
    End Sub
    
    
    Multi_wysw:                          'podprogram obslugi wyswietlania multipleksowego
    
    Load Timer0 , 125
    
    Set W1                                'wygaszenie wyswietlacza 1
    Set W2                                'wygaszenie wyswietlacza 2
    Set W3                                'wygaszenie wyswietlacza 3
    Set W4                                'wygaszenie wyswietlacza 4
    
    Select Case Nr_wysw
    
    Case 0:
    Call Pobr_znaku(a)
    Reset W1
    Case 1:
    Call Pobr_znaku(b)
    Reset W2
    Case 2:
    Call Pobr_znaku(c)
    Reset W3
    Case 3:
    Call Pobr_znaku(d)
    Reset W4
    End Select
    Incr Nr_wysw
    If Nr_wysw = 4 Then
    Nr_wysw = 0
    End If
    Return                                                  'powrot z podprogramu
    
    Kody7seg:                                             'tablica stalych kody7seg
    
    Data &B11000000 , &B11111001 , &B10100100 , &B10110000 , &B10011001
    Data &B10010010 , &B10000010 , &B11111000 , &B10000000 , &B10010000


    Proszę kod umieścić w odpowiednich znacznikach!
    Robak
  • #2
    Krauser
    Level 26  
    W tym układzie zmienne H i M są w kodzie BCD czyli jeśli np. jest 12 to przechowywane jest w postaci 0001 0010. Nie musisz nic robić poza wyłuskaniem połówki bajtu. Makebcd poza tym zamienia właśnie z postaci 0000 1010 (BIN) = 12(DEC) na to co powyżej.
  • #3
    johnny318
    Level 10  
    Hmm, po zlikwidowaniu "makebcd" nie wyświetla się nic. Wcześniej przynajmniej na wyświetlaczach były dwie cyfry 95... Więc nie wiem. A może problem jest w komunikacji z pcf'em? Mi chwilowo brakuje pomysłów.
  • #4
    Krauser
    Level 26  
    Na początek przetestuj samo wyświetlanie podstawiając pod H i M odpowiednie wartości, a jeśli to nie pomoże to nawet pod A, B itd. Możesz pójść jeszcze dalej i zamiast Call Pobor_znaku umieścić Portd = &B...
  • #5
    johnny318
    Level 10  
    Przykładowo zrobiłem coś takiego:

    A = &B00010010
    C = &B00100011
    
    Wartm = A
    A = Wartm And &B00001111                                   
    Shift Wartm , Right , 4                                    
    B = Wartm                                                   
    
    Warth = C
    C = Warth And &B00001111
    Shift Warth , Right , 4
    D = Warth


    i ładnie wyświetla się 23:12
  • #6
    Krauser
    Level 26  
    Na schemacie pin A0 PCF8583 jest dołączony do masy, więc adres powinien być 160 i 161.
  • #7
    johnny318
    Level 10  
    Właśnie adresu nie bylem pewien. Ale po zmianie nie ma efektów, dalej nic nie wyświetla
  • #8
    Krauser
    Level 26  
    Spróbuj dodać Config I2cdelay = 10. Jeśli nie pomoże to trzeba będzie sprawdzić czy nie ma błędu. Taki programik na pewno znajdziesz na elektrodzie np. Link oczywiście trzeba go umiejętnie przerobić i dodać do Twojego kodu. Na początek możesz tylko sprawdzać pojedynczy adres i jeśli jest układ to coś wyświetlić.
  • #9
    johnny318
    Level 10  
    Nie pomogło... No nic, będę jeszcze szukał i próbował, ale dziękuje za pomoc i pomysły. Jeśli uda się uruchomić zegar to dam znać.
  • #10
    johnny318
    Level 10  
    Wystarczyło dodać I2Cinit i układ działa poprawnie. wyświetla się czas. Teraz tylko ustawianie czasu dorzucić i zegarek gotowy. Temat uważam za zamknięty.