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

Atmega8, Bascom - Jak przełączać diody za pomocą przycisku?

neo_dc 25 Lut 2008 10:02 4876 13
REKLAMA
  • #1 4843511
    neo_dc
    Poziom 32  
    Posty: 2206
    Pomógł: 178
    Ocena: 211
    Witam wszystkich

    Jako, że technika idzie do przodu, to i ja postanowiłem się wziąć za avr-y.

    Napisałem programik z miganiem diody, wszystko ok
    Teraz chcialem sobie zrobic coś takiego, że mam przycisk, 2 diody.
    Jak wcisnę go raz, to zapala się jedna dioda, a druga gaśnie,
    jak wcisnę go drugi raz to na odwrót - pierwsza gaśnie druga się zapala.

    $regfile = "m8def.dat"
    $crystal = 1000000
    
    Config Portc = Output
    Config Portd.4 = Input
    Config Debounce = 50
    Portd = &B1101111                       ' ustawiam wszystkie niepotrzebne
    Portc = &B1011111                       ' porty na 1 oraz zapalam jedna diode
    Dim A As Byte
    A = 0
    Do
    If A = 0 Then
    Debounce Portd.4 , 0 , Program        'oczekuje stanu niskiego na portd.4
    Else
    Debounce Portd.4 , 0 , Program2       'oczekuje stanu niskiego na portd.4
    End If
    
    Loop
    End
    
    Program:
    Portc.4 = 0                                                 'jedna dioda zapalona
    Portc.5 = 1                                                 'druga dioda zgaszona
    Portd.4 = 1                                                 'ustawiam na portd.4 jedynke
    A = 1
    Return
    
    Program2:
    
    Portc.4 = 1                                                 ' dioda zgaszona
    Portc.5 = 0                                                 ' dioda zapalona
    Portd.4 = 1                                                 ' ustawiam na portd.4 jedynke
    A = 0
    Return


    Przycisk podłączony do portd.4 i do masy, diody do portc.4 i portc.5 przez rezystory do plusa zasilania.

    na symulacji działa a na atmedze diody ciagle migają.... co zrobic ?

    Nie stać mnie na ksiażkę więc uczę się z forum, helpa i internetu :)
  • REKLAMA
  • #2 4843652
    seba_x
    Poziom 31  
    Posty: 2071
    Pomógł: 29
    Ocena: 112
    powinno być config pind.4=input , to samo z debounce nie port tylko pin . program i program2 daj między loop a end
  • REKLAMA
  • Pomocny post
    #4 4843777
    nsvinc
    Poziom 35  
    Posty: 2870
    Pomógł: 262
    Ocena: 88
    Po co ustawiasz portd.4 na wejscie Hi-Z? Ustaw tak:
    PORTD = PORTD or &h10
    Wtedy podsiągasz ten pin do plusa i nie musisz ustawiać tam jedynki w podprogramach.

    Przerób A na BIT, po czym

    
    Program: 
    Portc.4 = 0                                                 'jedna dioda zapalona 
    Portc.5 = 1                                                 'druga dioda zgaszona 
    toggle a 
    Return 
    
    Program2: 
    
    Portc.4 = 1                                                 ' dioda zgaszona 
    Portc.5 = 0                                                 ' dioda zapalona 
    toggle a 
    Return 
    


    I pozamieniaj PORT na PIN tak jak masz wyżej w postach
  • REKLAMA
  • #5 4844016
    neo_dc
    Poziom 32  
    Posty: 2206
    Pomógł: 178
    Ocena: 211
    Narazie dziekuje za wszystkie rady, chwilowo jestem poza domem, jak przyjade to zaprogramuje uC i sprawdze czy zadziala :)

    Jak bedzie cos nie tak to bede Was jeszcze troche meczyl :)
    Pozdrawiam


    ________________________________________________________


    Nie chce nic działać...

    Przy migającej diodzie zawsze używałem portc.4 powiedzmy, a nie pinc.4

    $regfile = "m8def.dat"
    $crystal = 1000000
    
    Config Portc = Output
    Do
    Waitms 500
    Pinc.5 = 1
    Pinc.4 = 0
    Waitms 500
    Pinc.5 = 0
    Pinc.4 = 1
    
    Loop
    End


    taki program u mnie nie działa, diody świecą się cały czas...
    ale taki

    $regfile = "m8def.dat"
    $crystal = 1000000
    
    Config Portc = Output
    Do
    Waitms 500
    Portc.5 = 1
    Portc.4 = 0
    Waitms 500
    Portc.5 = 0
    Portc.4 = 1
    
    Loop
    End



    Działa wyśmienicie.... czemu ?



    Istnieje przycisk "Zmień" i proszę z niego korzystać. Posty scaliłem. [c_p]
  • Pomocny post
    #6 4845919
    bogdan_p
    Poziom 39  
    Posty: 3849
    Pomógł: 525
    Ocena: 120
    instrukcja Pinx.y służy do odczytu stanu portu natomiast Portx.y do ustawienia stanu na porcie
  • REKLAMA
  • #7 4846132
    neo_dc
    Poziom 32  
    Posty: 2206
    Pomógł: 178
    Ocena: 211
    masz rację, doczytałem to jeszcze gdzieś tu na forum :)

    Program z postu 1 dalej nie działa pomimo zmian proponowanych przez Was.... ale jutro się za to wezmę :) Dzisiaj już myślenie zawodzi :)

    ---EDIT----

    Ehh to takie proste się okazało....

    Już podaję rozwiązanie :)

    $regfile = "m8def.dat"
    $crystal = 1000000
    Config Portc = Output
    Config Portd = Input           'ustawiam we/wy
    Set Portd.4                         ' ustawiam sobie stany na pinach portow
    Reset Portc.4
    Set Portc.5
    
    
    Do
    If Pind.4 = 0 Then                 ' jesli wcisne przycisk
    Waitms 300                          'eliminacja drgan zestykow
    Toggle Portc.5                      'zmien stan portu :)
    Toggle Portc.4
    
    
    End If
    
    Loop
    End


    Narazie tematu nie zamykam, jak bede cos jeszcze potrzebowal to napisze tutaj :)
  • #8 4849132
    rdt
    Poziom 25  
    Posty: 789
    Pomógł: 29
    Ocena: 38
    mnie z kolei sie wydaje ze troszke bez sensu był warunek
    If A = 0 Then
    Debounce Portd.4 , 0 , Program 'oczekuje stanu niskiego na portd.4
    Else
    Debounce Portd.4 , 0 , Program2 'oczekuje stanu niskiego na portd.4
    End If
    Ale skoro sobie poradzileś to swietnie
  • #9 4852128
    neo_dc
    Poziom 32  
    Posty: 2206
    Pomógł: 178
    Ocena: 211
    Nie wiem czy był zły.... ja to rozumiałem tak, że oczekuje dwa razy tego samego, ale zależnie od stanu zmiennej A idzie do innego podprogramu :)

    Teraz bawię się LCDkiem i mam jedno takie pytanko - kontrast. Jak ograniczę prąd na zasilaczu to jest ok, jak ograniczenie wyłączę to jest zbyt duży. W nocie katalogowej nie mam wyprowadzenia contrast, jest tylko Vss, Vdd i 0 Vdd to zasilanie, do Vss nic nie mam podłączone. Ale dopięcie tam rezystora do masy lub plusa zasilania nic nie daje. Zostaje tylko rezystor w szereg z wyświetlaczem ?
  • #10 5029246
    peleton123
    Poziom 13  
    Posty: 48
    Pomógł: 3
    Ocena: 5
    Nie chce zakładać nowego tematu a mam podobny problem. Tzn chce zastosować jeden switch podpięty do masy którym będę przełączał informacje wyświetlane na LCD.
    Mówiąc prościej nacisnę raz wyświetli mi sie tekst "jeden" nacisnę drugi raz wyświetli tekst "dwa" nacisnę trzeci wyświetli "trzy" nacisnę czwarty to znowu wyświetli "jeden" i tak w pętli wyświetlając po kolei 3 różne teksty.

    Podjąłem próby ale nie wychodzi mi to
    $regfile = "m8def.dat"
    $crystal = 1000000
    Config Portd = Input          ' ustawiam we/wy
    Dim A As Integer
    A = 0
    
    Do
     Pocz:
    Set Portd.4
    If Pind.4 = 0 Then             ' jesli wcisne przycisk
    Waitms 300                      ' eliminacja drgan zestykow
      If A = 0 Then
      Locate 1 , 1
      Lcd "pierwszy"
      Incr A
      Goto Pocz
      End If
    
      If A = 1 Then
      Locate 1 , 1
      Lcd "drugi" 
      Decr A
      Goto Pocz
      End If
    End If
    Loop

    Jakieś sugestie, porady,pomoc.
  • #11 5029313
    pio_05
    Poziom 12  
    Posty: 59
    Ocena: 1
    Jak dla mnie to powinno być tak.
    Nie mam kompilatora pod rękom nie jestem pewien czy jest dobrze ale to mniej więcej to.

    
    Kod:
    $regfile = "m8def.dat"
    $crystal = 1000000
    Config Portd = Input          ' ustawiam we/wy
    Dim A As byte            'po co marnować pamięć
    A = 0
    Config Timer0 = Timer , Prescale = 1024
    Enable Timer0
    Enable Interrupts
    Do
    If Pind.4 = 0 Then
    waitms 50
    a=a+1;
    if a = 4 then a = 0 
    end if
    
    
                    
    loop
    
      Tim0_isr:
        Stop Timer0
        Start Timer0
      cls
      Locate 1 , 1 
      if a = 0 then lcd "pierwszy"
      if a = 1 then lcd "drugi"
      if a = 2 then lcd "trzeci"
      if a = 3 then lcd "czwarty"
       
      Return
    end
  • #12 5029415
    Leoo
    Poziom 16  
    Posty: 155
    Pomógł: 11
    Ocena: 12
    pio_05 napisał:
    Jak dla mnie to powinno być tak.
    Nie mam kompilatora pod rękom nie jestem pewien czy jest dobrze ale to mniej więcej to.

    
    Kod:
    $regfile = "m8def.dat"
    $crystal = 1000000
    Config Portd = Input          ' ustawiam we/wy
    Dim A As byte            'po co marnować pamięć
    A = 0
    Config Timer0 = Timer , Prescale = 1024
    Enable Timer0
    Enable Interrupts
    Do
    If Pind.4 = 0 Then
    waitms 50
    a=a+1;
    if a = 4 then a = 0 
    end if
    
    
                    
    loop
    
      Tim0_isr:
        Stop Timer0
        Start Timer0
      cls
      Locate 1 , 1 
      if a = 0 then lcd "pierwszy"
      if a = 1 then lcd "drugi"
      if a = 2 then lcd "trzeci"
      if a = 3 then lcd "czwarty"
       
      Return
    end

    Ciekawe rozwiązanie. Kolega używa tylko jednego bajtu na zmienną A ale w zamian zabiera zasób w postaci przerwania od timera. Timer0 generuje cykliczne przerwania, których skutkiem będzie cykliczne wpisywanie tekstu do LCD niezależnie czy nastąpiła jego zmiana, czy nie.
  • #13 5029963
    peleton123
    Poziom 13  
    Posty: 48
    Pomógł: 3
    Ocena: 5
    Fajne sposób ale wolałbym coś bez timera. Dałoby rade??
    Bo timera używam do zegarka. Bo w moim programie chodzi o to by przełączać tym przyciskiem miedzy pokazywanie temperatur a zegarkiem.


    Jeszcze mam pytanie po wciśnięciu switcha zmienia sie stan z 1 na 0 na portd czyli i na pind.4, tak??
    A czy on potem wraca do stanu 1? Sory za takie pytania ale pierwszy raz stosuje switch na mikrokontrolerze

    $regfile = "m8def.dat"
    $crystal = 1000000
    Config Lcdpin = Pin , Db4 = Portb.0 , Db5 = Portb.1 , Db6 = Portb.2 , Db7 = Portb.3 , E = Portb.4 , Rs = Portb.5
    
    Config Lcd = 16 * 4
    Config Pind.0 = Input                                       ' przycisk podłączony do tego portu
    Set Portd.0
    Przycisk Alias Pind.4
    Dim Sekwencja As Byte
    Declare Sub Pierwsza
    Declare Sub Druga
    Declare Sub Trzecia
    
    Do
    If Przycisk = 0 Then
    Waitms 50
    Sekwencja = Sekwencja + 1
    
    If Sekwencja = 4 Then Sekwencja = 0
    End If
    
    If Sekwencja = 1 Then
       Gosub Pierwsza
    End If
    If Sekwencja = 2 Then
       Gosub Druga
    End If
    If Sekwencja = 3 Then
       Gosub Trzecia
    End If
    
    Loop
    End
    Sub Pierwsza                                                ' pierwsza sekwencja
     Locate 1 , 1
      Lcd "pierwszy"
    End Sub
    Sub Druga                                                   ' druga sekwencja
     Locate 1 , 1
      Lcd "drugi    "
    End Sub
    Sub Trzecia                                                 'trzecia sekwencja
    Locate 1 , 1
      Lcd "trzeci    "
    End Sub


    Niby na symulatorze działa, ale czy w praktyce zadziała?? Może ktoś przeanalizować
  • #14 5034148
    pio_05
    Poziom 12  
    Posty: 59
    Ocena: 1
    W sumie to tylko jeden błąd poza tym chyba powinno działać.
    Błąd jest taki
    
    Config Lcd = 16 * 4
    Config [b]Pind.0[/b] = Input                                       ' przycisk podłączony do tego portu
    Set [b]Portd.0[/b]
    Przycisk Alias [b]Pind.4 [/b]
    


    Na jakim pinie będzie w końcu ten switch?

    Poza tym chyba wszystko dobrze zaprogramuj atmege to sie dowiesz.:)

Podsumowanie tematu

✨ Dyskusja dotyczy programowania mikrokontrolera Atmega8 w Bascom AVR w celu sterowania dwoma diodami LED za pomocą pojedynczego przycisku. Problem polegał na przełączaniu stanu diod przy kolejnych naciśnięciach przycisku – jedna dioda ma się zapalać, a druga gasnąć i odwrotnie. Wskazano błędy w konfiguracji portów i użyciu rejestrów: zamiast „Portd.4” i „Debounce Portd.4” powinno się używać „Pind.4” do odczytu stanu przycisku, a „Portc.x” do sterowania diodami. Zalecano ustawienie pinu przycisku jako wejście z podciągnięciem do plusa (PORTD = PORTD or &h10) oraz eliminację drgań styków przez opóźnienie (Waitms 300). Przykładowy poprawny kod wykorzystuje zmienną bitową do przełączania stanów diod i funkcję Toggle do zmiany stanu portów. Wyjaśniono różnicę między rejestrami PINx.y (do odczytu) a PORTx.y (do zapisu). W dalszej części dyskusji pojawiły się próby implementacji przełączania tekstów na wyświetlaczu LCD za pomocą jednego przycisku, z uwzględnieniem eliminacji drgań i zarządzania stanem zmiennej sterującej. Poruszono także kwestie konfiguracji LCD i problemów z kontrastem. Wskazano, że timer może być użyty do obsługi przerwań, ale preferowane są rozwiązania bez timerów, aby nie kolidowały z innymi funkcjami (np. zegarkiem). Podkreślono konieczność poprawnej konfiguracji pinów i aliasów, aby uniknąć błędów w odczycie stanu przycisku.
Wygenerowane przez model językowy.
REKLAMA