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

[bascom] jego możliwości z diodami

stoper17 01 Gru 2010 13:26 5511 30
  • #1 8812423
    stoper17
    Poziom 20  
    Witam. Założyłem sobie kilka prostych celów i stopniowo będę je realizował. Tworze programik który stopniowo będę modernizował i dodawał coraz to rozmaitsze funkcje związane oczywiście ze sterowaniem diod LED.Mam nadzieje że starczy cierpliwości innym a także wyrozumiałości:)Pracuje na atmega8.

    Zatem mam już swój 1 program:

    Config Portd = Output
    Dim i as byte
    Portd = &B11111110
    
    Do
    for i=1 to 7
      Rotate Portd , Left , 1
      Waitms 200
    next
    for i=1 to 7
      Rotate Portd , right , 1
      Waitms 200
    next
    
    
    Loop
    End 


    Chciałbym wydłużyć zakres "biegnięcia" diody o kolejny port np PORTB. Czyli dioda biegnie od pind0 do pind6 i przechodzi do pinb0 do pinb6 po czym zawraca. Wymyśliłem coś takiego:

    Config Portd = Output
    Config Portb = Output
    Dim i as byte
    Portd = &B11111110
    Dim j as byte
    Portb = &B11111110
    
    Do
    for i=1 to 7
    Rotate Portd , Left , 1
    Waitms 200
    next
    
    for j=1 to 7
    Rotate Portb , Left , 1
    Waitms 200
    next
    
    for j=1 to 7
    Rotate Portd , right , 1
    Waitms 200
    next
    
    for i=1 to 7
    Rotate Portd , right , 1
    Waitms 200
    next
    
    Loop
    End


    Co wy na to??

    Proszę pamiętać o używaniu znaczników code. - arnoldziq
  • #2 8812917
    galusz
    Poziom 15  
    Jeśli zmienną wykorzystujesz tylko do pętli for to wystarczy tylko 1. Idea dobra ale z wykonaniem gorzej. Przetestuj to na symulatorze.

    Generalnie nie będziesz miał płynnego efektu bo po przesunięciu całego portu ostatnia dioda w danym porcie nadal będzie się świecić, podobnie jak pierwsza w na porcie D.
  • #3 8813569
    Duch__
    Poziom 31  
    Tak jak napisał poprzednik. Niepotrzebnie stosujesz dwie zmienne:
    
    Dim i as byte
    Dim j as byte 
    


    Kod i tak jest pokolej wykonywany więc możesz przyjąć w każdej "pętelce" FOR-NEXT używanie tej samej zmiennej do liczenia np. J. Nauczy cię to dobrych nawyków z oszczędzaniem zasobów pamięci RAM procesorka, co w bardziej ambitnych projektach w przyszłości pozwoli uniknąć problemów.

    Jakby się uprzeć to można by zastosować pętlę w pętli, oraz funkcję select case. Jedna pętla (zewnętrzna) liczyła by "rotację" w którym kierunku mają iść diody którego portu, natomiast druga wykonywała by już obliczenia co do przesuwania diód. Zaoszczędzi to kilkanaście bajtów kodu.
  • #4 8814860
    stoper17
    Poziom 20  
    jak podczas symulacji zmniejszyć prędkość? za szybko się wszystko dzieje i nie jestem w stanie wyłapać to co się dzieje:P

    Poza tym jest jakiś może inny sprawdzony sposób zrobienia biegnącego światła na np 12 diodek i więcej. Zabawę z funkcją select case zostawie na weekend :)
  • Pomocny post
    #5 8818729
    galusz
    Poziom 15  
    Korzystaj z symulacji krokowej. Ostatecznie nie dawaj $sim w programie natomiast waitms zmień na mniejsze (symulacja jest ok 100x wolniejsza od procka, więc zamiast waitms 200 daj 2)

    Sprawdzonego programu do zapalania diod na kolejnych portach nie ma. Np. możesz użyć jednej zmiennej WORD i rozbić ją potem na dwa proty. Zaletą jest to że operujesz na jednej liczbie a dopiero sam wynik rozdzielasz na porty.. Ogólnie sposobów jest cala masa.

    Poniższy kod robi to samo co poprzedni zapala po kolei diodę na porcie B/D a potem wraca, a potem od nowa....
    Config Portd = Output
    Config Portb = Output
    Portd = &B00000000
    Portb = &B00000000
    
    Dim Newport As Word
    Dim I As Byte
    Newport = 0
    
    Do
    
    For I = 0 To 15
     Waitms 200
     Newport = 2 ^ I
     Portd = Low(newport)
     Portb = High(newport)
    Next I
    
    For I = 15 To 0 Step -1
     Waitms 200
     Newport = 2 ^ I
     Portd = Low(newport)
     Portb = High(newport)
    Next I
    
    Loop
  • #6 8819789
    stoper17
    Poziom 20  
    Z ciekawości próbowałem jeszcze rozszerzyć działanie na 3 porty na zasadzie:
    
    For I = 0 To 15
     Waitms 200
     Newport = 2 ^ I
     Portd = Low(newport)
     Portb = low(newporrt)
     Portc = High(newport)


    ale rezultat jest znany. Próbowałem znaleźć więcej wiadomości na temat zmiennej word, wychodząc z założenia że skoro jest Low i high musi być jakaś funkcja pośrednia typu mid?! ale też lipa.
    Skąd pobrać informacje by samemu poradzić sobie z tym problemem, bo przecież co pomysł to wielki znak ?. Szukam po różnych kursach, to albo nie ma tego albo nie rozumiem.

    Jest może ktoś w stanie przedstawić "logikę" bascomu? Analiza prostych programów nie sprawia problemu,ale jak coś samemu chcę to nie bardzo wiem za co się chwycić;/
  • Pomocny post
    #7 8819971
    galusz
    Poziom 15  
    Tak na szybko:
    Masz zmienną :
    Byte (1 bajt, 8 bitów)
    Word = 2x Byte (2 bajty, 16 bitów)
    Long = 2x Word (4 bajty, 32 bity)

    Nie ma zmiennej składającej się z 3 bajtów, dlatego jeśli chcesz rozszerzyć tą idee na 3 porty musisz użyć zmiennej Long, następnie rozbić ją na 2 zmienne WORD a potem WORD rozbić na 2 zmienne Byte ( i je przydzielić do portów)

    Wizualnie przedstawia to schemat działania
    
    Newport = 00000000 00000000 00000000 00000000
      2port =                   00000000 00000000
      portd =                            00000000
      portb =                   00000000
      2port = 00000000 00000000
      portc =          00000000
    




    A tak wygląda kod który to robi..
    
    Dim Newport As Long
    Dim 2port As Word
    
    For i=0 to 24 ' teraz liczymy do 24 (8*3)
    Newport = 2 ^ I 'zapalamy odpowiedni bit w naszej zmiennej
    2port=newport  ' rozbijamy Long na 2xWord (bierzemy tylko początek LSB)
    portd = low(2port) ' rozbijamy Word na port (LSB) 
    portb = high(2port) ' rozbijamy Word na port (MSB)
    2port =highw(newport) ' rozbijamy Long na 2xWord (bierzmy tylko MSB)
    portc= low(2port) ' rozbijamy Word na port (LSB)
    Next i


    Ponieważ całe to robicie i wysłanie zmiennej na porty zajmuje trochę miejsca i jest używane w 2 pętlach, najlepiej zawrzeć je w postaci podprogramu uruchamianego w odpowiednim czasie. Poniżej cały kod:

    Config Portd = Output
    Config Portb = Output
    Config Portc = Output
    
    Portd = &B00000000
    Portb = &B00000000
    Portc = &B00000000
    
    Dim I As Byte
    Dim Newport As Long
    Dim 2port As Word
    Newport = 0
    
    Do
     For I = 0 To 23
      Waitms 2
      Newport = 2 ^ I                                                'zapalamy odpowiedni bit w naszej zmiennej
      Gosub Wyslij_dane
     Next I
     For I = 23 To 0 Step -1
      Waitms 2
      Newport = 2 ^ I
      Gosub Wyslij_dane
     Next I
    Loop
    
    Wyslij_dane:
     2port = Newport
     Portd = 2port 'Brak funkcji Low() generalnie nie jest ona potrzebna bo przy przepisywaniu większej zmiennej do mniejszej brany jest LSB
     Portb = High(2port)
     2port = Highw(newport)
     Portc = 2port
    Return
  • #8 8834856
    stoper17
    Poziom 20  
    Bawiąc się dalej chciałem wysterować diody by od prawej zapalały się i nie gasły,gdy dojdą do końca wracały do początku gasnąc po kolei. Wyszło mi coś takiego:

    
    $regfile = "m8def.dat"
    $crystal = 1000000
    
    
    Config Portb = Output
           Portb = &B11111111
    
    
    Do
    
    Set Portb.0
    Waitms 10
    
    Set Portb.1
    Waitms 10
    
    Set Portb.2
    Waitms 10
    
    Set Portb.3
    Waitms 10
    
    Set Portb.4
    Waitms 10
    
    Set Portb.5
    Waitms 10
    
    Set Portb.6
    Waitms 10
    
    Set Portb.7
    Waitms 10
    
    Reset Portb.7
    Waitms 10
    
    
    Reset Portb.7
    Waitms 10
    
    Reset Portb.6
    Waitms 10
    
    Reset Portb.5
    Waitms 10
    
    Reset Portb.4
    Waitms 10
    
    Reset Portb.3
    Waitms 10
    
    Reset Portb.2
    Waitms 10
    
    Reset Portb.1
    Waitms 10
    
    Reset Portb.0
    Waitms 10
    
    Loop
    
    End
    
    
  • Pomocny post
    #9 8835265
    arktik1
    Poziom 27  
    Może być np tak:
    
    $regfile = "m8def.dat"
    
    Config Portd = Output
            Portd = &B00000000
    
    Dim D As Integer , D1 As Byte
    D = 0
    D1 = 0
    
    Do
    
    If D = 0 Then Portd = &B00000000
    If D = 1 Then Portd = &B00000001
    If D = 2 Then Portd = &B00000011
    If D = 3 Then Portd = &B00000111
    If D = 4 Then Portd = &B00001111
    If D = 5 Then Portd = &B00011111
    If D = 6 Then Portd = &B00111111
    If D = 7 Then Portd = &B01111111
    If D = 8 Then Portd = &B11111111
    
    If D = 0 Then D1 = 0
    If D = 8 Then D1 = 1
    If D1 = 0 Then
    Incr D
    Else
    Decr D
    End If
    Waitms 100
    
    Loop
    End
    

    możesz dopisać resztę portów
    Ale to tylko jeden ze sposobów.
    :D
  • #10 8836356
    stoper17
    Poziom 20  
    Dobry bajerek:) Na pewno się ten pomysł przyda. Natomiast mam teraz inny problem. Chcę połączyć dwa programy, z tym że wyskakuje mi błąd którego nie potrafie usunąć. Koncepcja programu: klawisz s1 załącza podprogram pr1 s2 podprogram 2.

    
    
    $regfile = "m8def.dat"
    $crystal = 1000000
    
    
    Config Portb = Output
           Portb = &B00000000
    Config Portc = Output
           Portc = &B00000010
    Config Portd = Output
           Portd = &B00000000
    
    
    
    S1 Alias Pinc.1
    S2 Alias Pinc.2
    Declare Sub Pr2
    Declare Sub Pr1
    
    
    Do
    
    If S1 = 1 Then
    Call Pr1
    If S2 = 1 Then
    Call Pr2
    
    Loop
    
    Sub Pr1:
    
    Set Pinb.1
    Waitms 5
    Reset Pinb.1
    Waitms 5
    Set Pinb.1
    Waitms 5
    Reset Pinb.1
    Waitms 5
    Set Pinb.1
    Waitms 5
    Reset Pinb.1
    Waitms 5
    Set Pinb.1
    Waitms 5
    Reset Pinb.1
    Waitms 5
    Set Pinb.1
    Waitms 5
    Reset Pinb.1
    Portb = 0
    Waitms 30
    Set Pinb.4
    Waitms 5
    Reset Pinb.4
    Waitms 5
    Set Pinb.4
    Waitms 5
    Reset Pinb.4
    Waitms 5
    Set Pinb.4
    Waitms 5
    Reset Pinb.4
    Waitms 5
    Reset Pinb.4
    Waitms 5
    Set Pinb.4
    Waitms 5
    Reset Pinb.4
    Waitms 5
    Set Pinb.4
    Waitms 5
    Reset Pinb.4
    Portb = 0
    Waitms 30
    End Sub
    
    
    
    
    Sub Pr2:
    
    Pind.2 = 1
    Waitms 10
    end SUB
  • Pomocny post
    #11 8837140
    sp3ots
    Poziom 38  
    Witam !
    Masz błędy, bo te dwa warunki:
    Cytat:

    If S1 = 1 Then
    Call Pr1
    If S2 = 1 Then
    Call Pr2

    nie są dokończone,
    Możesz zrobić tak:
    Cytat:

    If S1 = 1 Then Call Pr1
    If S2 = 1 Then Call Pr2

    albo tak:
    Cytat:

    If S1 = 1 Then
    Call Pr1
    end if
    If S2 = 1 Then
    Call Pr2
    end if

    Pozdrawiam. Stefan
  • #12 8837298
    stoper17
    Poziom 20  
    Faktycznie :) chcąc teraz zasymulować na bascomie działanie zmieniam w zależności od przycisku linie:
    Config Portc = Output
           Portc = &B00000000

    na np
    Config Portc = Output
           Portc = &B00000010

    czyli imituje załączenie S1 i symulator teoretycznie powinien go uruchomić.A tak nie jest. Czemu tak się dzieje?
  • #13 8837362
    sp3ots
    Poziom 38  
    Działaj na pojedynczych pinach:
    config portc.1= output
    portc.1=1
    albo
    set portc.1
  • #14 8837597
    arktik1
    Poziom 27  
    "i symulator teoretycznie powinien go uruchomić"
    Symulator BASCOMA tego nie uruchomi.
    Jeśli chcesz zobaczyć w symulatorze zmianę pinów to musisz przerzucać program ręcznie przyciskiem "Step Into code F8" i wpisać $SIM na początku programu ,bo WAIT będzie zajmował mu wieki.

    Dodano po 6 [minuty]:

    Poza tym jak tak będziesz pisał takie proste programy ,to może ci zabraknąć linijek w BASCOMie.
    Na to mruganie diodą wystarczy dodatkowa pętla ,zmienna licząca mrugnięcia i polecenie TOGGLE.
  • #15 8838025
    Konto nie istnieje
    Poziom 1  
  • #16 8838783
    arktik1
    Poziom 27  
    To:
    
    Config Portb = Output
    

    Oznacza że cały PortB to wyjście.
    To samo znaczy to:
    
    Config Portb = &B11111111
    

    To oznacza:
    
    Config Portb = Input
    

    że cały port to wejście
    To samo znaczy to:
    
    Config Portb = &B00000000
    

    Jeśli chcesz by któreś porty były wejściami a niektóre wyjściami to:
    
    Config Portb = &B11111100
    

    oznacza że PinB.0 i PinB.1 to wejścia a reszta to wyjścia.
    Chyba powinieneś zajrzeć do HELPA BASCOMa, lub poczytać coś programowaniu Uc
  • #17 8839193
    stoper17
    Poziom 20  
    Czyli tak. Poprawiłem wcześniejszy program tak jak radził arktik1 i zrezygnowałem z "długiego listu".Wyszło mi takie coś:
    $regfile = "m8def.dat"
    $crystal = 1000000
    
    
    Config Portb = Output
           Portb = &B00000000
    
           Dim I As Byte
    
    Do
    
    For I = 0 To 5
    Toggle Pinb.1
    Waitms 4
    Reset Pinb.1
    
    Next I
    
    For I = 0 To 5
    Toggle Pinb.4
    Waitms 4
    Reset Pinb.4
    
    Next I
    
     Loop
    


    i tak mam imitacje policyjnego sygnału:)
    Z tymi portami faktycznie pomieszałem.Przyznaje głupi błąd.






    Mam jeszcze zamiar podpiąć atmega8 pod sygnał wychodzący z głośnika. Możecie mi powiedzieć jakiej użyć funkcji by w zależności o mocy sygnału wyjściowego, adekwatnie do niej zapalało mi odpowiednią ilość diodek ??
  • #18 8847466
    stoper17
    Poziom 20  
    odświeżam posta.

    Jak mogę wysterować atmega8 tak by w zależności o wysokości amplitudy impulsu zapalała się odpowiednia ilość diodek?
  • #19 8847590
    arktik1
    Poziom 27  
    Zależy jakiego impulsu.
    Jeśli impuls o napięciu max 5v, to możesz wykorzystać ADC Uc.
    Jeśli jakiś bardzo mały to musisz dorobić wzmacniacz i dopiero do ADC.
    Możesz zrobić tak jak pisałem ci wyżej z zapalaniem diod po kolei.
    Zamiast zmiennej wykorzystaj podzieloną przez ilość diod wartość ADC.
  • #20 8848367
    stoper17
    Poziom 20  
    W sumie znalazłem równoległy projekt autorstwa
    ZbeeGin. Bardzo fajna sprawa :)


    ' VU meter na ATmega8
    ' (c) by ZbeeGin / Reset soft
    '----------------------------------------
    $regfile = "m8def.dat"
    $crystal = 1000000
    
    Config Portd = &B11111111
    Config Portb = &B00000011
    
    Config Adc = Single , Prescaler = Auto , Reference = Internal
    Start Adc
    
    Dim Vu As Byte                          ' wartosc diod dla chwilowej wartosci
    Dim Hold As Byte                        ' wartosc diody dla opcji hold
    Dim Hold_time As Byte                   ' czas w jakim opada hold
    Dim Sample As Word                      ' wartosc odczytana z przetwornika
    
    Dim Wtemp As Word
    Dim Temp_portd As Byte                  ' tymczasowa zawartosc PORTD
    Dim Temp_portb As Byte                  ' tymczasowa zawartosc PORTB
    
    Do
      Waitms 5
    
    Convert:
      Sample = Getadc(0)                    ' pobierz napiecie z ADC0
      Select Case Sample                    ' przeskaluj na ilosc diod
        Case 0 To 10 : Vu = 0
        Case 11 To 112 : Vu = 1
        Case 113 To 214 : Vu = 2
        Case 215 To 316 : Vu = 3
        Case 317 To 418 : Vu = 4
        Case 419 To 520 : Vu = 5
        Case 521 To 622 : Vu = 6
        Case 623 To 724 : Vu = 7
        Case 725 To 826 : Vu = 8
        Case 827 To 928 : Vu = 9
        Case 929 To 1023 : Vu = 10
      End Select
    
    Hold_peak:
      If Vu >= Hold Then                    ' jesli przetworzona wartosc wieksza niz zapamietana max
        Hold = Vu                           ' to przypisz max nowa wartosc odczytana
        Hold_time = 60                      ' i ustaw liczniczek czasu podtrzymania
      Else
        Decr Hold_time                      ' w przeciwnym wypadku wartosc max bedzie opadac
        If Hold_time = 0 Then               ' jesli liczniczek sie przekrecil
          Decr Hold                         ' opusc diode max o jeden
          Hold_time = 48                    ' i zmien czas po jakim ma opadac w nast. kroku
        End If
      End If
    
    Displ:
      Wtemp = Lookup(hold , Hold_table)     ' czas na wyswietlanie
      Temp_portd = Low(wtemp)               ' wg danych z linii data
      Wtemp = Lookup(vu , Vu_table)
      Temp_portd = Temp_portd And Low(wtemp)       ' po prostu zmiksuj dane chwilowej wartosci z max
    
      Wtemp = Lookup(hold , Hold_table)
      Temp_portb = High(wtemp)
      Wtemp = Lookup(vu , Vu_table)
      Temp_portb = Temp_portb And High(wtemp)
    
      Portd = Temp_portd                    ' jak dane gotowe to na porty!
      Portb = Temp_portb
    Loop
    
    End
    
    Vu_table:
      Data &B0000001111111111%
      Data &B0000001111111110%              '1
      Data &B0000001111111100%              '2
      Data &B0000001111111000%              '3
      Data &B0000001111110000%              '4
      Data &B0000001111100000%              '5
      Data &B0000001111000000%              '6
      Data &B0000001110000000%              '7
      Data &B0000001100000000%              '8
      Data &B0000001000000000%              '9
      Data &B0000000000000000%              '10
    
    Hold_table:
      Data &B0000001111111111%
      Data &B0000001111111110%              '1
      Data &B0000001111111101%              '2
      Data &B0000001111111011%              '3
      Data &B0000001111110111%              '4
      Data &B0000001111101111%              '5
      Data &B0000001111011111%              '6
      Data &B0000001110111111%              '7
      Data &B0000001101111111%              '8
      Data &B0000001011111111%              '9
      Data &B0000000111111111%              '10 


    Jeszcze tylko dla formalności. Sygnał z głośników podpinam pod Portb Pinb.0 i Pinb.1 ??
  • Pomocny post
    #21 8850238
    arktik1
    Poziom 27  
    Gdzie to wyczytałeś, tak dla formalności?
    Oczywiście że nie, przecież masz napisane:
    
    Sample = Getadc(0)                    ' pobierz napięcie z ADC0 
    

    A gdzie jest w Uc ADC(0)?

    Dodano po 1 [minuty]:

    I jeszcze jedno, to wskaźnik MONO.
  • #22 8850657
    stoper17
    Poziom 20  
    Obstawiałem na podstawie
    Config Portb = &B00000011 

    hehe ale faktycznie...mono mówi wszystko na ten temat. Wielkie dzięki :D. Jeszcze pewnie coś wymyśle, to odświerze temat :D
  • #23 8892079
    stoper17
    Poziom 20  
    :( jednak nie jest wszystko jasne z tym ostatnim programem. Podpinam standardowo 5V na vcc na zasilanie atmegi z mostkiem na zasilanie diod, potem " - " pod Gnd, następnie pod portD podpinam wyjścia diod. Wydaje mi się że samo zasilanie jest dobrze podpięte, natomiast sterowanie:

    dodatni ze wzmacniacza podpinam pod ADC0 i nie jestem pewny(gdzieś wyczytałem) ale pod ADC1 podpinam biegun ujemny ze wzmacniacza, i chyba muszę jeszcze zasilić pin AVCC ??
    Bynajmniej próbowałem i nic nie działa;/
    Proszę o kortektę
  • #24 8892096
    arktik1
    Poziom 27  
    "dodatni ze wzmacniacza podpinam pod ADC0 i nie jestem pewny(gdzieś wyczytałem) ale pod ADC1 podpinam biegun ujemny ze wzmacniacza,"
    źle przeczytałeś.
    Poza tym jakiego wzmacniacza?
    AVCC podłącz do +5v i zrób tak:"Reference = Avcc"
  • #25 8896415
    stoper17
    Poziom 20  
    Nie wiem czy dobrze zrobiłem.Efekt nie jest mimo wszystko uzyskiwany;/Diody mrygają z wysoką częstotliwością. Myślałem że to zakłócenia ale jak odłączam od głośnika sygnał dalej to samo się dzieje.

    [bascom] jego możliwości z diodami

    Załączam prowizoryczny rysunek jak to połączyłem oczywiście po zmianie tamtej komendy.
  • #26 8897628
    arktik1
    Poziom 27  
    Podejrzewam że chciał byś uzyskać taki efekt:



    tylko na diodach led.
    Niestety do tego sam program ci nie wystarczy.
    Musisz poczytać o VU Meter.
    :D
  • #27 8899108
    stoper17
    Poziom 20  
    Dokładnie dotyczy to tego:
    Link
  • #28 8899979
    arktik1
    Poziom 27  
    Najprostszym rozwiązaniem jest dodanie kondensatora i opornika do wejścia ADC by spowolnić proces opadania słupka.
    Kondensator jakieś 2uF, rezystor ok 300KOhm, dioda prostownicza, najlepiej schottky.
    Podłączasz diodę do "+" głośnika w kierunku "+" kondensatora.
    Do diody podłączasz kondensator i + kondensatora do ADC.
    Do kondensatora podłączasz równolegle opornik, i oczywiście kondensator z opornikiem do masy.
    Musisz też połączyć - urządzenia z - wzmacniacza.
    Złapał??
    :D
  • #29 8902747
    stoper17
    Poziom 20  
    jak zwykle na horyzoncie wątpliwości, dlatego przedstawię to graficznie:
    [bascom] jego możliwości z diodami

    I w sumie jeszcze kwestia
    Cytat:
    Musisz też połączyć - urządzenia z - wzmacniacza.


    Czyli minus z minusem mojego R i C ??:cry:
  • #30 8902834
    arktik1
    Poziom 27  
    [bascom] jego możliwości z diodami
    Ostatnie pytanie:TAK
REKLAMA