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

[bascom][atmega8] jak wyświetlić 3 cyfrową wartość zmiennej

Tomekddd 20 Wrz 2009 12:02 4054 30
REKLAMA
  • #1 7037478
    Tomekddd
    Poziom 23  
    Witam wszystkich.
    Robię sterownik silnika na podczerwień i mam problem z kodem. napisałem kod do sterowania silnikiem który po każdym obrocie silnika zwiększa wartość zmiennej "obroty" o jeden lub zmniejsza zależnie od kierunku obrotów. Wartosć tej zmiennej chcę wyświetlic na wyświetlaczu led trzy cyfry i jeden jako znak jeżeli wartość będzie ponizej zera. Korzystam z książki M. Wiązani i tam znalazłem kod obsługi wyświetlaczy ale nie wiem jak go powiązać z moim programem.

    oto kod sterowania silnikiem
    $regfile = "m8def.dat"
    $crystal = 8000000
    
    
    Config Rc5 = Pind.0
    Config Pind.5 = Output
    Config Pind.6 = Output
    Config Pind.7 = Input
    
    Set Portd.7
    
    
    Enable Interrupts
    
    
    Dim Address As Byte , Command As Byte
    Dim Obroty As Integer
    
    
    Do
    Getrc5(address , Command)
    Command = Command And &B01111111
    If Command = 19 Then
    Gosub Lewo
    Elseif Command = 18 Then
    Gosub Prawo
    End If
    
    
    Loop
    End
    
    
    
    Prawo:
    Portd.6 = 1
    Portd.5 = 0
    Waitms 10
    Portd.6 = 0
    
    If Pind.7 = 0 Then
    Incr Obroty
    End If
    
    Return
    
    
    
    Lewo:
    Portd.5 = 1
    Portd.6 = 0
    Waitms 10
    Portd.5 = 0
    
    If Pind.7 = 0 Then
    Decr Obroty
    End If
    
    Return
    
    
    



    A tu kod do wyświetlaczy z usuniętymi zbednymi instrukcjami (np kropki) z tym ze nie wiem jak go uzyc aby wyswietlic wartosć mojej zmiennej
    $regfile = "m8def.dat"
    $crystal = 8000000
    Config Portd = Output
    Config Pinb.1 = Output
    Config Pinb.2 = Output
    Config Pinb.3 = Output
    Config Pinb.4 = Output
    Config Timer0 = Timer , Prescale = 256
    Declare Sub Pobr_znaku(cyfra As Byte)
    On Timer0 Mult_wysw
    Dim A As Byte , B As Byte , C As Byte , D As Byte
    Dim Nr_wysw As Byte
    
    Dim Wart As Byte
    W4 Alias Portb.1
    W3 Alias Portb.2
    W2 Alias Portb.3
    W1 Alias Portb.4
    Enable Interrupts
    Enable Timer0
    Load Timer0 , 125
    Do
    A = 1
    B = 2
    C = 8
    D = 9
    
    Wait 2
    D = 10
    C = 10
    
    Wait 2
    Wart = 56
    Wart = Makebcd(wart)
    A = Wart And &B00001111
    Shift Wart , Right , 4
    B = Wart
    Wait 2
    Loop
    End
    
    Sub Pobr_znaku(cyfra As Byte)
    If Cyfra < 10 Then
    Portd = Lookup(cyfra , Kody7seg)
    Else
    Portd = &B11111111
    End If
    End Sub
    
    Mult_wysw:
    Load Timer0 , 125
    Set W1
    Set W2
    Set W3
    Set W4
    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
    
    Kody7seg:
    Data 192 , 249 , 164 , 176 , 153 , 146 , 130 , 248 , 128 , 144
    
  • REKLAMA
  • #3 7037688
    karlos79
    Poziom 33  
    Witam
    Musisz zmienną obroty rozbić na setki, dziesiątki, i jednostki.
    Potem wystarczy tylko odpowiednio wyniki przepisać do zmiennych A,B,C,D i powinno jakoś działać.
    Zobacz w załączniku naskrobałem coś na szybko.
    Pozdrawiam
  • #4 7039109
    Tomekddd
    Poziom 23  
    ZbeeGin napisał:
    A w "książce" Wiązani nie było wytłumaczenia jak ten kod działa?


    no w książce było ale że ja dopiero zaczynam z tym zabawe to nie tak hop siup sobie samemu napisać :) dlatego liczę na pomoc elektrody

    Posprawdzałem dokładnie program, pozmieniałem porty bo sie nakładaly na ten z odbiorem rc5 ale niestety program nie ruszył. Ciągle wyświetla 8888 i nie reaguje na pilota i impulsy silnika

    oto program troszke zmieniony i co moze być nie tak?
    $regfile = "m8def.dat"
    $crystal = 8000000
    
    
    Config Rc5 = Pinc.0
    Config Pinc.1 = Output
    Config Pinc.2 = Output
    Config Pinc.3 = Input
    Config Portd = Output
    Config Pinb.1 = Output
    Config Pinb.2 = Output
    Config Pinb.3 = Output
    Config Pinb.4 = Output
    Config Timer0 = Timer , Prescale = 256
    
    Set Portc.3
    
    
    
    
    
    Dim Address As Byte , Command As Byte
    Dim Obroty As Integer
    Declare Sub Pobr_znaku(cyfra As Integer)
    On Timer0 Mult_wysw
    Dim A As Integer , B As Integer , C As Integer , D As Integer
    Dim Nr_wysw As Byte
    
    Dim Wart As Byte
    W4 Alias Portb.1
    W3 Alias Portb.2
    W2 Alias Portb.3
    W1 Alias Portb.4
    Enable Interrupts
    Enable Timer0
    Load Timer0 , 125
    '########################################################
    Do
    Getrc5(address , Command)
    Command = Command And &B01111111
    If Command = 19 Then
    Gosub Lewo
    Elseif Command = 18 Then
    Gosub Prawo
    End If
    D = Obroty / 100                                            'jednostki
    C = Obroty / 10                                             'dziesiatki
    B = Obroty Mod 100                                           'setki
    
    Loop
    End
    '***************************************************
    Sub Pobr_znaku(cyfra As Byte)
    If Cyfra < 10 Then
    Portd = Lookup(cyfra , Kody7seg)
    Else
    Portd = &B11111111
    End If
    End Sub
    
    Mult_wysw:
    Load Timer0 , 125
    Set W1
    Set W2
    Set W3
    Set W4
    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
    
    '############################################
    
    
    Prawo:
    Portc.2 = 1
    Portc.1 = 0
    Waitms 10
    Portc.2 = 0
    
    If Pinc.3 = 0 Then
    Incr Obroty
    End If
    
    Return
    
    
    
    Lewo:
    Portc.1 = 1
    Portc.2 = 0
    Waitms 10
    Portc.1 = 0
    
    If Pinc.3 = 0 Then
    Decr Obroty
    End If
    
    Return
    
    Kody7seg:
    Data 192 , 249 , 164 , 176 , 153 , 146 , 130 , 248 , 128 , 144
  • #5 7044228
    karlos79
    Poziom 33  
    Witam
    Przenieś kod za etykietami Lewo: i Prawo: do pętli głównej i zobacz co się stanie.
    Pozdrawiam
  • REKLAMA
  • #6 7045429
    Tomekddd
    Poziom 23  
    jeśli przeniose wszystko co jest odpowiedzialne za kierunek prawo: i lewo: do petli do loop to nic sie nie dzieje dalej same 8888 i nie reaguje
    spróbowalem jeszcze do tej pętli przenieść wszysto z SUB pobr_znaku i multipleks ale też to samo
    na pilota też nie reaguje
  • #7 7045483
    grysek
    Poziom 19  
    Nie widzę u Ciebie nigdzie polecenia START Timer0, spróbuj to dodać zaraz po Enable Timer0 :D
  • #8 7045574
    Tomekddd
    Poziom 23  
    nie pomaga tak jakby program wyświetlił tylko te 8888 i tyle dalej nic sie nie dzieje żeby nie wiem jak go przerabiać

    spróbuję przerobić program zeby reagował na pilota od przerwania INT0 moze ruszy
    P.S. zejdzie mi z tym pare godzin wiec jak dobrze pójdzie jutro dam znać czy coś ruszyło

    ewentualnie prosze o jakieś inne propozycje
  • REKLAMA
  • #9 7046755
    karlos79
    Poziom 33  
    Witam
    Dodaj jeszcze schemat, bo może masz coś namieszane.
    Pozdrawiam
  • #10 7049614
    Tomekddd
    Poziom 23  
    schematu nie mam narazie uruchamiam na zl2AVR złasnej konstrukcji i do tej pory problemów nie było sprzętowych i myśle ze teraz też nie ma bo odbiór podczerwieni działa oraz sterowanie wyswietlaczami też testowane na kilku programach

    tu raczej kwestia programu niż sprzętu narazie piszę program z przerwaniem INT0 zobaczymy czy ruszy

    jeszcze wpadłem na pomysl aby sprawdzic sam program do wyświetlania wartości zmiennej obroty ale on nie działa poprawnie

    jeśli do zmiennych ABCD przypisze wartosci od 0 do 9 to wyświetla te cyfry ale jeśli zrobie tak jak nizej to wiświetla same zera z czego jedno mruga a tak być nie powinno więc coś z tym jest nie tak
    to jest ten kod z niego wywaliłem wszystko co było do sterowania IR a zostało tylko do wyświetlaczy
    skoro ten kod nie działa to nic mi nie da napisanie sterowania od przerwania INT0 tzreba coś wymyśleć z przetwarzaniem

    $regfile = "m8def.dat"
    $crystal = 8000000
    
    
    Config Portd = Output
    Config Pinb.1 = Output
    Config Pinb.2 = Output
    Config Pinb.3 = Output
    Config Pinb.4 = Output
    Config Timer0 = Timer , Prescale = 256
    
    
    Dim Obroty As Integer
    Declare Sub Pobr_znaku(cyfra As Integer)
    On Timer0 Mult_wysw
    Dim A As Integer , B As Integer , C As Integer , D As Integer
    Dim Nr_wysw As Byte
    
    Dim Wart As Byte
    W1 Alias Portb.1
    W2 Alias Portb.2
    W3 Alias Portb.3
    W4 Alias Portb.4
    Enable Interrupts
    Enable Timer0
    Load Timer0 , 125
    
    
    '########################################################
    Do
    
     Obroty = 100
    
    D = Obroty / 100                                            'jednostki
    
    
    
    
    Loop
    End
    '***************************************************
    Sub Pobr_znaku(cyfra As Byte)
    If Cyfra < 10 Then
    Portd = Lookup(cyfra , Kody7seg)
    Else
    Portd = &B11111111
    End If
    End Sub
    
    Mult_wysw:
    Load Timer0 , 125
    Set W1
    Set W2
    Set W3
    Set W4
    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
    
    '############################################
    
    
    Kody7seg:
    Data 192 , 249 , 164 , 176 , 153 , 146 , 130 , 248 , 128 , 144
  • #12 7053289
    Tomekddd
    Poziom 23  
    zmieniłem nic nie dało same zera, dzięki temu co napisałes wpadłem na pomysł pozmieniania typu danych i to był strzał w dziesiątke

    zamieniłem te linie na bajty

    Declare Sub Pobr_znaku(cyfra As Byte)
    Dim A As Byte , B As Byte , C As Byte , D As Byte


    i to bo po tym co napisałeś wywaliło bład ze zmienne są inne niz te zadeklarowane
    Sub Pobr_znaku(cyfra As Byte)


    teraz kod wyglada tak a na wyświetlaczach pokazało się 0082 teraz to trzeba dopracować
    $regfile = "m8def.dat"
    $crystal = 8000000
    
    
    Config Portd = Output
    Config Pinb.1 = Output
    Config Pinb.2 = Output
    Config Pinb.3 = Output
    Config Pinb.4 = Output
    Config Timer0 = Timer , Prescale = 256
    
    
    Dim Obroty As Integer
    Declare Sub Pobr_znaku(cyfra As Byte)
    Dim A As Byte , B As Byte , C As Byte , D As Byte
    Dim Nr_wysw As Byte
    
    Dim Wart As Byte
    W1 Alias Portb.1
    W2 Alias Portb.2
    W3 Alias Portb.3
    W4 Alias Portb.4
    Enable Interrupts
    Enable Timer0
    Load Timer0 , 125
    On Timer0 Mult_wysw
    
    '########################################################
    Do
    
     Obroty = 1000
    
    D = Obroty / 100
    C = Obroty / 10
    
    
    
    
    
    
    
    
    Loop
    End
    '***************************************************
    Sub Pobr_znaku(cyfra As Byte)
    If Cyfra < 10 Then
    Portd = Lookup(cyfra , Kody7seg)
    Else
    Portd = 0
    End If
    End Sub
    
    Mult_wysw:
    Load Timer0 , 125
    Set W1
    Set W2
    Set W3
    Set W4
    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
    
    '############################################
    
    
    Kody7seg:
    Data 192 , 249 , 164 , 176 , 153 , 146 , 130 , 248 , 128 , 144
  • #13 7053335
    karlos79
    Poziom 33  
    Witam
    To spróbuj jeszcze zamienić te zmienne (obroty, D,C,B,A) na BYTE, bo coś mi się zdaje, że nie da rady wyświetlić w ten sposób zmiennej INTEGER.
    Zrób taki programik na próbę i daj znać jak poszło.
    Pozdrawiam
  • #14 7053362
    Tomekddd
    Poziom 23  
    zmienione
    obroty as byte
    obroty = 255
    abcd as byte

    i wyświetla 0082
    to pewnie dlatego że jak przy dzieleniu jest wiecej niż 9 to wyświetla 8 jak zmniejsze liczbe na np 96 to wyświetla 0090
  • #15 7054168
    karlos79
    Poziom 33  
    Witam
    Żeby wyświetliło pełny wynik musisz napisać coś takiego:
    obroty = 86
    D= 0broty/ 10
    C= obroty mod 10 ' mod zwraca resztę z dzielenia.
    Pozdrawiam
  • #16 7054682
    Tomekddd
    Poziom 23  
    to dziala ale tylko do 99 powyzej wyświetla w dziesiątkach 8
    narazie sie mecze nad instrukcja która powyzej 99 odejmie 100 i wtedy powinno wyliczyc

    Dodano po 8 [minuty]:

    nie wiem czemu ale nie mogę odjąć 100 od obroty chciałem tak zrobić:
    if obroty > 99 then
    obroty - 100
    c=obroty / 10
    end if

    ale wywala error1
  • REKLAMA
  • #17 7055268
    karlos79
    Poziom 33  
    Witam
    Zrób tak jak pokazałem Ci w pierwszym moim poście, tylko zmienne zamień na BYTE, wtedy powinno wyświetlać setki, dziesiątki i jednostki.
    Pozdrawiam
  • #18 7056446
    Tomekddd
    Poziom 23  
    program juz działa wprowadziłem dodatkową zmienną pomocniczą i śmiga teraz tylko pozostaje problem polączenia go z odbiorem podczerwieni

    $regfile = "m8def.dat"
    $crystal = 8000000
    
    
    Config Portd = Output
    Config Pinb.1 = Output
    Config Pinb.2 = Output
    Config Pinb.3 = Output
    Config Pinb.4 = Output
    
    Config Timer0 = Timer , Prescale = 256
    
    
    
    Dim Obroty As Byte
    Declare Sub Pobr_znaku(cyfra As Byte)
    Dim A As Byte , B As Byte , C As Byte , D As Byte
    Dim Nr_wysw As Byte
    Dim Wart As Byte
    Dim P As Byte
    
    W1 Alias Portb.1
    W2 Alias Portb.2
    W3 Alias Portb.3
    W4 Alias Portb.4
    
    Enable Interrupts
    Enable Timer0
    Load Timer0 , 125
    
    On Timer0 Mult_wysw
    
    Do
     P = Obroty
    B = Obroty \ 100
    If P > 99 And P < 199 Then
    P = P - 100
    Elseif P > 199 Then
    P = P - 200
    
    End If
       C = P \ 10
    D = Obroty Mod 10
    
    
    Loop
    End
    
    '#################################################################
    
    
    Sub Pobr_znaku(cyfra As Byte)
    If Cyfra < 10 Then
    Portd = Lookup(cyfra , Kody7seg)
    Else
    Portd = 0
    End If
    End Sub
    
    Mult_wysw:
    Load Timer0 , 125
    Set W1
    Set W2
    Set W3
    Set W4
    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
    
    
    
    
    Kody7seg:
    Data 192 , 249 , 164 , 176 , 153 , 146 , 130 , 248 , 128 , 144
  • #19 7059814
    karlos79
    Poziom 33  
    Witam
    Gratuluję :)
    Co do połączenia wyświetlania i sterowania.
    Spróbuj to
    Getrc5(address , Command)
    Command = Command And &B01111111
    If Command = 19 Then
    Gosub Lewo
    Elseif Command = 18 Then
    Gosub Prawo
    End If

    wpakować do pętli głównej programu "wyświetlającego", no i oczywiście poza pętlą odpowiednie podprogramy.
    Powinno zadziałać
    Pozdrawiam
  • #20 7060338
    Tomekddd
    Poziom 23  
    dodałem to do programu ale wyswietla 8888 i nic nie reaguje
    jak dodam wszystko oprócz tego do pętli głownej program działa jak wpisze tylko do pętli getrc5(address , command) to przestaje
  • #21 7060499
    ZbeeGin
    Poziom 39  
    GETRC5 jest funkcją oczekującą, dlatego program w niej się pętli. Funkcja ta na swoje potrzeby używa TIMER0, którego Ty też używasz.
  • #22 7062526
    Tomekddd
    Poziom 23  
    czyli jak w programie zmienie multipleks na timer 1 to bedzie działało?
  • Pomocny post
    #23 7062872
    karlos79
    Poziom 33  
    Witam
    Powinno zadziałać.
    Pozdrawiam
  • #24 7063047
    Tomekddd
    Poziom 23  
    no i działa dzięki za pomoc, teraz tylko kwestia dostrojenia i zbudowania sterownika

    Dodano po 47 [minuty]:

    jeszcze mi się przypomniało da sie jakoś zrobić zeby zmienna obroty była pamietana po wyłaczeniu zasilania?
  • #26 7064573
    Tomekddd
    Poziom 23  
    to wiem tylko nie wiem jak to zrobić
    do zapisu jest komenda writeeeprom a odczytu readeeprom ale nie wiem gdzie je wstawić do kodu aby byly używane
  • Pomocny post
    #27 7064884
    mirekk36
    Poziom 42  
    a po co się upierać przy writeeprom, skoro można zadeklarować sobie zmienną wprost w obszarze pamięci EEPROM i później z niej korzystać prawie tak jak ze zwykłej zmiennej w RAM

    Dim Zmienna As ERAM Byte


    a później gdzieś w kodzie:

    Zmienna = Obroty ' w ten prosty sposób zapamiętujesz w EEPROMIE swoje obroty


    albo

    Obroty = Zmienna ' czyli np po starcie odtwarzasz zawartość zmiennej obroty z pamięci EEPROM
  • #28 7068084
    Tomekddd
    Poziom 23  
    dzięki narazie śmiga zobacze jak będzie z silnikiem ale to dopiero za ok tydzień bo musze mostek H zbudować
  • #29 7068166
    mirekk36
    Poziom 42  
    Pomyśl też nad scalakiem L293D - zamiast samemu budować mostek czy mostki H ;) ..... będzie szybciej, łatwiej, przyjemniej a co najważniejsze PEWNIEJ i bez ew efektów ubocznych - np upalenia tranzystorów czy procka. Bardzo przyjemnie steruje się silniczkami za pomocą tegoż scalaczka
  • #30 7068241
    Tomekddd
    Poziom 23  
    nie wiem czy on wytrzyma pobór prądu silnika, jak dobrze pójdzie silnik będe miał w tym tygodniu to zmierze
REKLAMA