logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Bascom][AVR] wyświetlacz 7 seg LED

parklinson 14 Wrz 2010 20:17 4157 4
  • #1 8510772
    parklinson
    Poziom 15  
    Cześć

    Chciałem prosić kogoś o wskazówkę jak poradzić sobie z problemem wyświetlania wartości "Wartosc2" poniższego kodu.

    Mój problem polega na tym że w momencie naciśnięcia przycisku ( w programie to Up, Dwn ) gdy na wyświetlaczach jest np 1.1 wyświetlacze "resetują" się i wskazują wartość 00 po zwolnieniu przycisku wyświetlona zostaje poprawnie kolejna wartość zliczona. W jaki sposób wyeliminować to znikanie poprawnej wartości w chwili trzymania przycisku?

    Z góry dziękuję Michał

    'Program sterujący 2 wyświetlaczami 7-segmentowym LED
    'Napisany by parklinson
    'Wykorzystano fragmenty z książki "Programowanie mikrokontrolerów AVR w języku BASCOM".
    
    
    $regfile = "m16def.dat"                                     'informuje kompilator o pliku
          'dyrektyw mikrokontrolera
    $crystal = 16000000                                         'informuje kompilator
          'o częstotliwości oscylatora
          'taktującego mikrokontroler
    Config Portc = Output
    Config Pinb.0 = Output                                      '
    Config Pinb.1 = Output
    Config Pinb.2 = Input
    Config Pinb.3 = Input
    Config Timer0 = Timer , Prescale = 256                      'konfiguracja Timer0 jako
            'timer z podziałem
            'preskalera przez 256
    On Timer0 Mult_wysw                                         'przerwanie od przepełnienia
            'Timer0‚ skok nastąpi do
            'podprogramu Mult_wysw
    Dim A As Byte , B As Byte                                   'definicje zmiennych A, B,
            'przechowywana wartość do
            'wyświetlenia
    Dim Nr_wysw As Byte                                         'zmienna określająca numer
            'zapalonego wyświetlacza
    Dim Kr1 As Bit , Kr2 As Bit                                 'zmienne bitowe sterujące
                                                                   'kropkami
    W1 Alias Portb.0                                            'przypisanie linii PB0 nazwy W1
    W2 Alias Portb.1                                            'przypisanie linii PB1 nazwy W2
    
    Declare Sub Pobr_znaku(cyfra As Byte)                       'deklaracja procedury
            'pobierającej kod cyfry do
            'wyświetlenia z tablicy
    Declare Sub Liczba
    Dim Wartosc2 As Byte
    Dim Wart As Byte
    Dim Wartosc As Byte                                         
    
    Up Alias Pinb.2
    Dwn Alias Pinb.3
    
    Set Portb.2
    Set Portb.3
    A = 0
    B = 0
    
    Kropka Alias Portc.7                                        'przypisanie bitowi 7 rejestru
          'PORTD nazwy Kropka
    
    Enable Interrupts                                           'odblokowanie globalnego
            'systemu przerwań
    Enable Timer0                                               'odblokowanie przerwania od
            'przepełnienia Timer0
    Load Timer0 , 150                                           'załadowanie do licznika
            'wartości początkowej
    Do                                                          'początek pętli nieskończonej
    
      If Up = 0 Then
       Waitms 25
       If Up = 0 Then
    
       Wartosc = Wartosc + 10
    
       Call Liczba
       Waitms 150
      End If
     End If
    
      If Wartosc > 0 Then
    
       If Dwn = 0 Then
          Waitms 25
    
          If Dwn = 0 Then
    
             Wartosc = Wartosc - 1
    
             Call Liczba
             Waitms 150
             Else
             Wartosc = 0
          End If
       End If
      End If
    
     Loop                                                       'koniec pętli nieskończonej
    End                                                         'koniec programu
    
    Sub Liczba
    
      If Wartosc > 99 Then
             Wartosc2 = Wartosc \ 10
          Else
             Wartosc2 = Wartosc
      End If
    
     Wart = Wartosc2
     Wart = Makebcd(wartosc2)                                   'zamiana wartości zmiennej
            'Wart na wartość zapisaną
            'w kodzie BCD
    
     B = Wart And &B00001111                                    'wyodrębnienie (przez
            'maskowanie) i wyświetlenie
            'pierwszej cyfry zapisanej
            'w zmiennej Wart (cyfra 5)
     Shift Wart , Right , 4                                     'przesunięcie wartości
            'drugiej cyfry w zmiennej
            'Wart na pozycje czterech
            'mniej znaczących bitów
     A = Wart                                                   'wyświetlenie na
            'wyświetlaczu 2 cyfry 3
    
    End Sub
    
    Sub Pobr_znaku(cyfra As Byte)                               'definicja procedury
    
    
            'Pobr_znaku
     If Cyfra < 10 Then                                         'jeżeli wartość otrzymanej do
                                                                       'wyświetlenia cyfry < od 10,
      Portc = Lookup(cyfra , Kody7seg )                         'to wpisanie do portu D
                                                                             'wartość kodu z tablicy
            'stałych Kody7seg
     Else                                                       'w przeciwnym razie
      Portc = 0                                                 'wpisanie do portu D wartości
            '0 która wygasza wyświetlacz
     'Reset Kropka
    
     End If                                                      'koniec warunku If...Then
    End Sub                                                     'koniec procedury
    
    
    Mult_wysw:                                                  'podprogramu obsługi
                                                                      'przerwania od przepełnienia
                                                                      'Timer0 w którym odbywa się
                                                                      'multipleksowanie
    Load Timer0 , 150                                           'załadowanie do licznika
    
                                                                   'wartości początkowej
    
     Set W1                                                     'wygaszenie wyświetlacza 1
     Set W2                                                     'wygaszenie wyświetlacza 2
    
     Select Case Nr_wysw                                        'w zależności od wartości
            'Nr_wysw, wykonaj:
      Case 0:                                                   'gdy Nr_wysw = 0, to
       Call Pobr_znaku(a)                                       'wywołanie procedury
                                                               'pobierającej z tablicy kod
                                                               'znaku dla wartości A
       If Wartosc > 10 Then
        Kropka = 0
          If Wartosc > 99 Then
             Set Kropka
          End If
       End If
    
       Reset W1                                                 'włączenie wyświetlacza 1
      Case 1:                                                   'gdy Nr_wysw = 1, to
       Call Pobr_znaku(b)                                       'wywołanie procedury
                                                                 'pobierającej z tablicy kod
                                                                 'znaku dla wartości B
       Reset W2                                                 'włączenie wyświetlacza 2
    
     End Select                                                 'koniec instrukcji wyboru
     Incr Nr_wysw                                               'zwiększenie o jeden wartości
            'Nr_wysw
     If Nr_wysw = 2 Then                               'jeśli wartość Nr_wysw
            'osiągnie 2, to
      Nr_wysw = 0                                         'zeruj wartość Nr_wysw
     End If
    Return                                                    'powrót z podprogramu
    
    
    
    Kody7seg:                                               'tablica stałych Kody7seg
                                                                'przechowująca kody wyświetlanych
                                                                'cyfr
                                                                'Kody cyfr
    
    Data &B11000000 , &B11111001 , &B10100100 , &B10110000 , &B10011001
    Data &B10010010 , &B10000010 , &B11111000 , &B10000000 , &B10010000
    
  • #2 8519362
    mirekk36
    Poziom 42  
    Trzeba umieć zadawać pytania panie kolego a nie wkleić kobylasty jakiś tam kod i zapytać się o jakiś tam szczegół. Żeby odpowiedzieć to trzeba teraz próbować przeanalizować co poeta miał na myśli pisząc takie "cóś".

    I to to jeszcze jak szybko odpowiedzi oczekujesz?

    Albo sprecyzuj pytanie sam analizując co nieco napisany bądź co bądź przez ciebie kod i spróbuj dość w której części może być błąd żeby dopytać o jakiś szczegół którego nie rozumiesz.

    albo poczekaj może się zdarzy ktoś chętny na analizatora ;)

    Ja mogę tylko podpowiedzieć, że nie pisałeś tego kodu, tylko przepisywałeś z książki jakieś fragmenty i to bez zrozumienia dogłębnego o co w tym chodzi, próbując jednocześnie jakieś swoje modyfikacje robić. Nie tędy droga. Spróbuj najpierw sam bez przepisywania z książki zrobić multipleksowanie od podstaw - wtedy duuuużo ci się od razu rozjaśni a i pytania inne będziesz zadawał. Ot po prostu wszystko po kolei proponuję robić.
  • #3 8519431
    Ilmarinen
    Poziom 14  
    ojejku strasznie zamotany ten kod. Pierwsza poprawka to niepotrzebnie zdublowany warunek
    If Up = 0 Then 
       Waitms 25 
       [b]If Up = 0 Then [/b]
    
       Wartosc = Wartosc + 10 
    
       Call Liczba 
       Waitms 150 
     [b] End If [/b]
     End If
    


    jeżeli warunek pierwszy jest spełniony to automatycznie zagnieżdżony w nim warunek musi być spełniony. Chyba ze tu chodzi o odkłucanie przycisków to jest to jakieś rozwiązanie, chociaż w tym przypadku bezsensowne. Procedura waitms zatrzymuje pracę procesora na określony czas. W tym wypadku lepsza była by procedura debounce skutki uboczne sa takie same, kod staje sie bardziej przejrzysty, i nie musimy wymyślać kola od początku.
  • #4 8519566
    parklinson
    Poziom 15  
    mirekk36 napisał:
    Trzeba umieć zadawać pytania panie kolego a nie wkleić kobylasty jakiś tam kod i zapytać się o jakiś tam szczegół. Żeby odpowiedzieć to trzeba teraz próbować przeanalizować co poeta miał na myśli pisząc takie "cóś".

    I to to jeszcze jak szybko odpowiedzi oczekujesz?

    Albo sprecyzuj pytanie sam analizując co nieco napisany bądź co bądź przez ciebie kod i spróbuj dość w której części może być błąd żeby dopytać o jakiś szczegół którego nie rozumiesz.

    albo poczekaj może się zdarzy ktoś chętny na analizatora ;)

    Ja mogę tylko podpowiedzieć, że nie pisałeś tego kodu, tylko przepisywałeś z książki jakieś fragmenty i to bez zrozumienia dogłębnego o co w tym chodzi, próbując jednocześnie jakieś swoje modyfikacje robić. Nie tędy droga. Spróbuj najpierw sam bez przepisywania z książki zrobić multipleksowanie od podstaw - wtedy duuuużo ci się od razu rozjaśni a i pytania inne będziesz zadawał. Ot po prostu wszystko po kolei proponuję robić.


    Twoim zdaniem który fragment kodu miałem zamieścić skoro nie wiem gdzie tkwi błąd ? Zasadę działania multiplexowania rozumiem a w przepisywaniu czegoś z książki nie widzę nic złego (pod warunkiem że nie próbuje przypisać sobie do tego autorstwa). Po co odkrywać Amerykę na nowo skoro można skorzystać z gotowego rozwiązania. Większość przykładów multiplexowania zamieszczona na elektrodzie jest właśnie z tej książki.
    Mimo wszystko dzięki za zainteresowanie

    Ilmarinen napisał:
    ojejku strasznie zamotany ten kod. Pierwsza poprawka to niepotrzebnie zdublowany warunek
    If Up = 0 Then 
       Waitms 25 
       [b]If Up = 0 Then [/b]
    
       Wartosc = Wartosc + 10 
    
       Call Liczba 
       Waitms 150 
     [b] End If [/b]
     End If
    


    Jeżeli warunek pierwszy jest spełniony to automatycznie zagnieżdżony w nim warunek musi być spełniony. Chyba ze tu chodzi o odkłucanie przycisków to jest to jakieś rozwiązanie, chociaż w tym przypadku bezsensowne. Procedura waitms zatrzymuje pracę procesora na określony czas. W tym wypadku lepsza była by procedura debounce skutki uboczne sa takie same, kod staje sie bardziej przejrzysty, i nie musimy wymyślać kola od początku.


    Warunek na początku ma służyć zabezpieczeniu przed drganiem styków, Przyznaję jednak racje ze debounce lepiej wygląda i kod jest bardziej przejrzysty jednak robi to samo co moja instrukcja warunkowa więc w tym błędu nie ma.
  • #5 8519904
    cepelia
    Poziom 20  
    Zamotane do granic i bez sensu. Chodzi ci o to żeby po naciśnięciu przycisku odbywało się dodawanie wartości albo odejmowanie.
    Kolega napisał ci żeby poznać dobrze zasadę multipleksowania i to bardzo dobra rada. Ja z reguły nie motam tego tak tylko staram się to robić po kolei. Zobacz na ten kod :

    
    'Opoznienie
    Ms = 6
    
    ' PC - segmenty
    Led7 Alias Portb
    
    ' PB0...3 - katody
    Ds4 Alias Portc.0
    Ds3 Alias Portc.1
    Ds2 Alias Portc.2
    Ds1 Alias Portc.3
    
    
    Do
    
      ' display DS1
      Reset Ds4 : Reset Ds3 : Reset Ds2 : Set Ds1
      Led7 = Lookup(poz_1 , Led7s_table)
      Waitms Ms
      ' display DS2
      Reset Ds4 : Reset Ds3 : Set Ds2 : Reset Ds1
      Led7 = Lookup(poz_2 , Led7s_table)
      Waitms Ms
      ' display DS3
      Reset Ds4 : Set Ds3 : Reset Ds2 : Reset Ds1
      Led7 = Lookup(poz_3 , Led7s_table)
      Waitms Ms
      ' display DS4
      Set Ds4 : Reset Ds3 : Reset Ds2 : Reset Ds1
      Led7 = Lookup(poz_4 , Led7s_table)
      Waitms Ms
    Loop
    


    jak widzisz multipleksowanie odbywa się tutaj w pętli głównej programu bo jest na tyle czasu (właściwie to baaardzo dużo). Natomiast licznik robisz na przerwaniu i po wszystkim...

    
    On Int0 Licz                                                ' Nosave
    Enable Int0
    Config Int0 = Falling
    
    Config Timer1 = Timer , Prescale = 1
    On Timer1 Licznik
    Enable Timer1
    
    Enable Interrupts
    
    Licz:
    incr a ' zmienna licznika
    Return
    


    potem tylko rozdzielasz liczbe na cyfry i po wszystkim, tylko matematyka.
    Ten kod do obsługi 7seg możesz równie dobrze wcisnąć w przerwanie i wywoływać go kiedy chcesz (tylko wycinasz z niego opóźnienie, ja zwykle ustawiam czas tak aby katody świeciły 4ms, świeci jasno i wyraźnie). A jeszcze jedno jak widać to kod obsługuje 4 wyświetlacze ale wystarczy skasować dwie ostatnie pozycje i masz multiplex na 2 cyfry.

    [Bascom][AVR] wyświetlacz 7 seg LED [Bascom][AVR] wyświetlacz 7 seg LED
REKLAMA