Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Problem z ujarzmieniem wyświetlaczy led. - BASCOM

hubertfab 01 Aug 2009 19:21 2648 11
IGE-XAO
  • #1
    hubertfab
    Level 21  
    Witam.

    Mam problem z wyświetlaczami LED.
    Nie wiem za bardzo jak liczbę np. 1993 rozłożyć na cyfry 1;9;9;3.



    Na tym filmie można zauważyć, że liczby nie są tak super wyświetlane. Coś przeskakuje...

    Wracając do problemu wiem, że trzeba liczbę 1993 podzielicz przez 1000 później przez 100 ; 10. Odejmować reszty z tych dzieleń. Tylko czy może mi ktoś przetłumaczyć na BASCOM'a ?

    Pozdrawiam i proszę o pomoc. Z góry dzięki. :idea:
  • IGE-XAO
  • #2
    Jacek31
    Conditionally unlocked
    Trochę sobie komplikujesz życie, można to robić na piechotę, ale w BASCOM są do tego specjalne instrukcje jak MAKEBCD, która zamienia liczbę zapisaną w postaci binarnej na jej odpowiednik w BCD. Potem wystarczy już tylko prosta operacja wyłuskania pół bajtu. i na jej podstawie trzeba wygenerować odpowiedni znak.
    Problem z ujarzmieniem wyświetlaczy led. - BASCOM.
    Wygląda to mniej więcej tak, choć to nie jest kompletny algorytm, bo trzeba potem jeszcze dla danej liczby z jakieś tablicy stałych przypisać kod sterujący do wyświetlacza, chyba że korzystasz ze scalonych dekoderów BCD.
    Natomiast da się napisać uniwersalną procedurę która z liczby ze zmiennej typu word (ale od 0 do 9999), wygeneruje ci liczbę w BCD ( a właściwie ciąg danych do sterowania wyświetlaczem) i umieści wynik w 4 elementowej tablicy typu byte, gdzie będą po kolei liczby od miejsca 1 do 4.
  • #3
    Paweł Es.
    VIP Meritorious for electroda.pl
    Można też to robić metodą wielokrotnego odejmowania:
    Code:

    X - liczba wejściowa typu integer (zakładamy, że z zakresu 0-9999)


    Sub Int2Bcd(X AS INTEGER)

    Local X1 AS INTEGER

    ' zmienne typu BYTE globalna zadeklarowane w programie głównym

    CT=0 ' Cyfra tysięcy
    CS=0 ' Cyfra setek
    CD=0 ' Cyfra dziesiątej
    CJ=0  ' Cyfra jednostek

    IF X=0 THEN RETURN

    IF X>9999 THEN
    ' Obsługa błędu nadmiaru np.
    CT=10 ' sygnalizuje, że trzeba wyświetlić kod błędu
     RETURN
    END IF

    X1=X

    ' Przetwarzanie

    IF X1>1000 THEN

       DO
          X1=X1-1000
          CT=CT+1
       LOOP UNTIL  X1<1000

    END IF

    IF X1>100 THEN

       DO
          X1=X1-100
          CS=CS+1
       LOOP UNTIL X1<100

    END IF

    IF X1<10 THEN

       DO
          X1=X1-10
          CD=CD+1
       LOOP UNTIL X1<10

    END IF

    CJ=X1

    RETURN


  • #4
    hubertfab
    Level 21  
    Paweł Es. ->> Dzięki wielkie. Zrozumiałem jak to działa. Prawdopodobnie z tego będę korzystał.


    Jacek31 ->> Tobie również dziękuję, ale jeszcze musisz mi coś wytłumaczyć.
    1. Co na tej notatce oznaczają "MSB" ; "LSB" ?
    2. Możesz bardziej dokładniej opisać jak "wyłuskać": cyfrę jedności, dziesiątek, setek, tysięcy ?
    3. Czy ta metoda mniej "katuje" mikrokontroler ?

    Do wszystkich:
    4. Gdzie są przyciski "POMÓGŁ" ?

    Pozdrawiam.
  • IGE-XAO
  • #5
    Jacek31
    Conditionally unlocked
    Odpowiadając na pytania kolegi. Otóż i tak w najbliższym czasie w BASCOM AVR będę pisał na nowo soft do zestawu J-239 Jabela (dziecinada ten oryginał :not:), bo mam zamiar wywalić z niego oryginalny proc (AT89C2051 nie wiadomo po co taktowany 12MHz :?: ) i wstawić ATTiny 2313, bo się da, i będę i tak zmuszony pisać procedury translacji liczby z bin, na taką która wyświetla sie na wyświetlaczu LED, to wrzucę tu takową procedurę z opisem jej działania.
  • #7
    Jacek31
    Conditionally unlocked
    Dobra zgodnie z zapowiedzią mały porządek w poście. Jak widać na załączonym obrazku procedura wreszcie mi działa tak jak trzeba. Problemy wynikały z mojej sklerozy :yes: , procedury tego typu pisałem jakieś 2 lata temu i się zapomniało to i owo o BASCOM.
    Problem z ujarzmieniem wyświetlaczy led. - BASCOM
    A oto kod samej procedury:
    Code:

    'zmienne
    const null = 255
    Dim Poz_wys As Byte
    Dim Licz As Word
    Dim Temp As Word
    Dim Dzielnik As Word
    Dim Vram(4) As Byte
    Dim I As Word
    Dim J As Byte
    Dim Licz_pom As Byte
    Dim Czy_zero_fiz As Bit

    Sub Konwert
       Temp = 0
       Temp = Licz
       Czy_zero_fiz = 0
       Dzielnik = 1000
       Licz_pom = 1
       While Dzielnik > 0
          If Temp >= Dzielnik Then
              Czy_zero_fiz = 1
              I = Temp \ Dzielnik 'oblicz ile razy dzielnik mieści się w liczbie
              For J = 1 To I          ' odejmij dzielnik od liczby n-razy
                 Temp = Temp - Dzielnik
              Next J
              Vram(licz_pom) = Lookup(i , Cgrom) 'przypisz ile razy dzielnik się mieścił
          Else
            If Czy_zero_fiz = 0 Then 'jeżeli nie ma zera w liczbie to dany wyświetlacz ma być pusty
              Vram(licz_pom) = Null
            Else 'jeżeli jest Zero fizyczne w liczbie np. 102 to wstaw w odpowiednie miejsce faktycznie znak 0.
              Vram(licz_pom) = Lookup(0 , Cgrom)
            End If
          End If
          Dzielnik = Dzielnik \ 10 ' oblicz nowy dzielnik
          Incr Licz_pom
        Wend
        If Licz = 0 Then
          Vram(4) = Lookup(0 , Cgrom)
       End If
    End Sub

    'Generator Znaków.
    Cgrom:
    Data &B00010001            '0
    Data &B01110111            '1
    Data &B01001001            '2
    Data &B01000011            '3
    Data &B00100111            '4
    Data &B10000011            '5
    Data &B10000001            '6
    Data &B01010111            '7
    Data &B00000001            '8
    Data &B00000011            '9
    Data &B10001101            'F
    Data &B00110001            'U
    Data &B10111001            'L
    Data &B01110000            'J.
    Data &B10000010            'S
    Data &B00000101            'A

    Jak to działa :?: Otóż tak najpierw wartość zmiennej Licz jest przepisywana do zmiennej pomocniczej Temp. Jest to zabieg konieczny w moim przypadku ponieważ algorytm procedury jest stratny, i po jej zakończeniu w przeciwnym przypadku w zmiennej Licz znalazło by się Zero. Potem następuje następuje zainicjowanie zmiennych operacyjnych dzielnik oraz Czy_zero_fiz. Ta zmienna, a właściwie Bit kontrolny wymaga trochę wyjaśnień. Otóż czym jest to ów "Zero Fizyczne". W skrócie chodzi tu o wykrycie faktu ile miejsc na wyświetlaczu zajmuje liczba i wygaszanie niepotrzebnych cyfr na wyświetlaczu aby nie uzyskać wyniku klasy np."0485" tylko "485". Gdy Zero Fizyczne nie zostało wykryte to wpisywany jest tgz. NULL, czyli znak pusty, zdeklarowany tutaj jako stała, w przeciwnym razie do VRAM (od Video RAM) wpisywany na odpowiedniej pozycji wskazanej przez Licz_pom jest odpowiedni znak z CGROM, który stanowy generator znaków, czyli tablicę kodów sterujących dla poszczególnych segmentów wyświetlacza. Jak widać VRAM jest 4 elementowę tablicą typu BYTE, w której pozycji 1 odpowiada skrajny lewy wyświetlacz, a pozycji 4 skrajny prawy wyświetlacz. Wyświetlaniem danych z tej tablicy w moim przypadku zajmuje się procedura wywoływana 250 razy/sek przerwaniami od T0. która po kolei w każdym przerwaniu wyświetla kolejny element z tablicy.
    UWAGI !!! Tablicę CGROM trzeba sobie stworzyć wg, własnych potrzeb. Pomocny może być EXCEL w którym można napisać prosty arkusz przeliczający odpowiednio wartości, to tylko przykład z mojej aplikacji. To samo dotyczy procedur odświeżania wyświetlacza i wyświetlania danych z pamięci VRAM. procedura jest sprawdzona, napisałem ją jakieś 2 lata temu jeszcze na AT89C2051 i teraz zmieniłem tylko na AVRa (są małe różnice w obsłudze CGROMa w obu przypadkach).
    Co do pytania kolegi, o jak to ujął "katowanie mikroprocesora". w informatyce nie ma takiego pojęcia. Każdy procesor to tylko szybki idiota, który potrafi wykonywać tylko rozkazy. Nie ważne czy program będzie napisany tak czy siak, on i tak będzie jak szalony latał w kółko po programie z szybkością wyznaczoną przez zegar taktujący.
    A tak twój problem ze znikającymi cyframi przy naciskaniu guzika, jest spowodowany tym że masz źle napisaną obsługę wyświetlacza. Albo nie używasz do tego Timera i robisz to programowo co powoduje zaprzestanie obsługi w momentach naciskania przycisku, albo źle gdzieś sterujesz portami CPU. Ale bez schematu elektrycznego trudno coś doradzić, bo nie wiadomo jak napisać program sterujący.
  • #8
    hubertfab
    Level 21  
    Dzięki wielkie za odpowiedzi.

    Paweł Es. ->> Z twojego sposobu będę korzystać, ponieważ jest prosty do zrozumienia.

    Jacek31 ->> Dziękuję za twój wysiłek włożony w to aby mi to wytłumaczyć. Ta procedura jest bardziej skomplikowana i potrzeba do tego więcej pamięci SRAM. Użyto tu dużo zmiennych, które nie pomagają ograniczyć zużycie pamięci.

    Pozdrawiam Hubert.
  • #9
    Jacek31
    Conditionally unlocked
    No cóż nigdzie nie napisałeś że chcesz procedury zoptymalizowanej pod kątem wykorzystania RAM.
  • #10
    Master Dragon
    Level 12  
    A ma ktoś taki kod w C albo umie to przetłumaczyć na c
  • #11
    Tomekddd
    Level 23  
    Jak wyświetlić te wyliczone cyfry na wyświetlaczu? i która zmienna jest tą obliczaną?
  • #12
    gucio1
    Level 12  
    W C nie, ale może asm???

    Tak w skrócie - sprawdzasz po kolei bity i dodajesz do komórek 92 93 94 95 96 już gotową wartość bitu z rozdzieleniem na cyfry... i powtarzasz 16X za do 1 bitu

    później sprawdzenie, czy wartość danej "cyfry" nie wylazła ponad 9 - jeśli tak to ją -10 a następną +1 - (aż będzie mniejsza do 9)

    Na końcu do każdej przydałoby się dodać 30H - żeby miała wartość nie liczbową, a wartość odpowiadającą znakowi....
    teraz tylko wrzucić na ekran

    Code:


    ld a,#00
    ld 92,a
    ld 93,a
    ld 94,a
    ld 95,a
    ld 96,a

    ld a,90
    push a

    ;25025 +50
    and a,#80
    cp a,#00
    jz 1e
    ld a,92
    add a,#02
    ld 92,a

    ld a,93
    add a,#05
    ld 93,a

    ld a,94
    add a,#00
    ld 94,a

    ld a,95
    add a,#07
    ld 95,a

    ld a,96
    add a,#05
    ld 96,a

    pop a
    push a

    ;12512
    and a,#40
    cp a,#00
    jz 1e
    ld a,92
    add a,#01
    ld 92,a

    ld a,93
    add a,#02
    ld 93,a

    ld a,94
    add a,#05
    ld 94,a

    ld a,95
    add a,#01
    ld 95,a

    ld a,96
    add a,#02
    ld 96,a

    pop a
    push a

    ;6256
    and a,#20
    cp a,#00
    jz 1e
    ld a,92
    add a,#00
    ld 92,a

    ld a,93
    add a,#06
    ld 93,a

    ld a,94
    add a,#02
    ld 94,a

    ld a,95
    add a,#05
    ld 95,a

    ld a,96
    add a,#06
    ld 96,a

    pop a
    push a

    ;3128
    and a,#10
    cp a,#00
    jz 1e
    ld a,92
    add a,#00
    ld 92,a

    ld a,93
    add a,#03
    ld 93,a

    ld a,94
    add a,#01
    ld 94,a

    ld a,95
    add a,#02
    ld 95,a

    ld a,96
    add a,#08
    ld 96,a

    pop a
    push a

    ;1564
    and a,#08
    cp a,#00
    jz 1e
    ld a,92
    add a,#00
    ld 92,a

    ld a,93
    add a,#01
    ld 93,a

    ld a,94
    add a,#05
    ld 94,a

    ld a,95
    add a,#06
    ld 95,a

    ld a,96
    add a,#04
    ld 96,a

    pop a
    push a

    ;782
    and a,#04
    cp a,#00
    jz 1e
    ld a,92
    add a,#00
    ld 92,a

    ld a,93
    add a,#00
    ld 93,a

    ld a,94
    add a,#07
    ld 94,a

    ld a,95
    add a,#08
    ld 95,a

    ld a,96
    add a,#02
    ld 96,a

    pop a
    push a

    ;391
    and a,#02
    cp a,#00
    jz 1e
    ld a,92
    add a,#00
    ld 92,a

    ld a,93
    add a,#00
    ld 93,a

    ld a,94
    add a,#03
    ld 94,a

    ld a,95
    add a,#09
    ld 95,a

    ld a,96
    add a,#01
    ld 96,a

    pop a

    ;195
    and a,#01
    cp a,#00
    jz 1e
    ld a,92
    add a,#00
    ld 92,a

    ld a,93
    add a,#00
    ld 93,a

    ld a,94
    add a,#01
    ld 94,a

    ld a,95
    add a,#09
    ld 95,a

    ld a,96
    add a,#05
    ld 96,a

    ;92 93 94 95 96 /10

    nop
    ld a,96
    cp a,#0a
    jg 0c
    sub a,#0a
    ld 96,a
    ld a,95
    inc a
    ld 95,a
    rcf
    jnc ee

    nop
    ld a,95
    cp a,#0a
    jg 0c
    sub a,#0a
    ld 95,a
    ld a,94
    inc a
    ld 94,a
    rcf
    jnc ee

    nop
    ld a,94
    cp a,#0a
    jg 0c
    sub a,#0a
    ld 94,a
    ld a,93
    inc a
    ld 93,a
    rcf
    jnc ee

    nop
    ld a,93
    cp a,#0a
    jg 0c
    sub a,#0a
    ld 93,a
    ld a,92
    inc a
    ld 92,a
    rcf
    jnc ee

    nop


    ld a,92
    add a,#30
    ld 86,a

    ld a,93
    add a,#30
    ld 88,a

    ld a,94
    add a,#30
    ld 89,a

    ld a,95
    add a,#30
    ld 8a,a

    ld a,96
    add a,#30
    ld 8B,a