Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Atmega8, C - Kolejne zapalanie diod

Lucasinhoo 26 Cze 2015 22:01 1962 21
  • #1 26 Cze 2015 22:01
    Lucasinhoo
    Poziom 6  

    Witam,

    Bawię się od jakiegoś czasu Atmega8 i językiem C.
    Mam problem napisałem krótką instrukcję . Diody podłączone mam do Portów PD0,1,2, chcę żeby zapalały się one kolejno ( zapalanie kolejnej nie gasi wcześniejszej).

    Code:
    /* przykład 2.1 "leds.c" */
    
    /* 8 diod LED przłączonych do portu D */
    /* ATmega 1MHz */

    #define F_CPU 1000000L
    #include <avr/io.h>
    #include <util/delay.h>

    int main(void)
    {   
       /* Wszystkie linie portu D będą wyjściami */
       DDRD = 0xFF;  /* 0xFF binarnie 1111 1111 */
       PORTD = 0x0;
       /* Początek nieskończonej pętli */
       while(1)
       {
          PORTD|= 0x1;   
        
          _delay_ms(1000);
        
          PORTD|= 1<<PD0 ;
         
          _delay_ms(1000);
        
         PORTD|= 1<<PD1 ;
         
          _delay_ms(1000);
        
       }
    }


    Program "działa do drugiej diody, mianowicie, pierwsza zapala się, mija czas, zapala się druga ( pierwsza nie gaśnie), trzecia zaś wcale się nie zapala, jakiś błąd w logu ? Liczę na pomoc.
    Pozdrawiam

    0 21
  • #2 26 Cze 2015 22:15
    Dople
    Poziom 19  

    Kod: c
    Zaloguj się, aby zobaczyć kod


    jest tym samym co:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #3 27 Cze 2015 00:17
    Fredy
    Poziom 27  

    Jak może sie zapalić trzecia, skoro nigdzie nie masz PORTD|=1<<PD2?
    Jeżeli chcesz, aby diody sią zapalały, ale poprzednie gasly to nie możesz użyć ORa.
    Użyj wprost wpisu w PORTD, czyli PORTD=0x00; potem PORTD=0x01; potem PORTD=0x02;

    0
  • #5 27 Cze 2015 11:58
    Lucasinhoo
    Poziom 6  

    Pomyliłem ustawianie bitu z przesuwaniem :).

    Teraz wygląda to tak:

    Code:
    // diody podlaczone do portow pd 0,1,2 , switch podlaczony do pc5, przytrzymanie switcha
    
    // powoduje zmiane zapalania diod, jesli nie wcisniety inna kolejnosc !

    #define F_CPU 1000000L
    #include <avr/io.h>
    #include <util/delay.h>

    int main(void)
    {   
       /* Wszystkie linie portu D będą wyjściami */
       DDRD = 0xFF;  /* 0xFF binarnie 1111 1111 */
        DDRC  = 0x00;

        PORTC = 0xff;
       /* Początek nieskończonej pętli */
       while(1)
       {
          if(!(PINC &0x20)) // jesli przycisk przytrzymany to 1 na pc5
          {

       

            PORTD = 0x1;    // ustawia Pd0 na 1
              
            _delay_ms(1000);
              
           PORTD|= 1<<PD1 ; // ustawia pd1 na 1
             
           _delay_ms(1000);
              
             PORTD|= 1<<PD2 ; // pd2 na 1
             
            _delay_ms(1000);
              
             PORTD = 0x0;
            _delay_ms(500); // wszysktie pd na 0
          }
          
              
               else // bez wcisnietego przycisku
               {
        
                
                      PORTD = 1<<PD2; // pd2 na 1
                      _delay_ms(1000);
                      
                      PORTD = 1<<PD1; // pd1 na 1
                      _delay_ms(1000);
                      
                      PORTD = 1<<PD0; //pd0 na 1
                      _delay_ms(1000);
                      
                      PORTD = 0x0; // zerowanie wszystkich
                      _delay_ms(500);
                
             
                }
       }
    }


    Kolejne pytanie jest takie, wszystko działa, ale jak zrobić, żeby po samym naciśnięciu switcha zmieniała się kolejność świecenia ( teraz musze trzymać, bo inaczej wykonuje się else). ?
    Dziękuję za zainteresowanie ;)

    0
  • #6 27 Cze 2015 13:03
    ASMnauka_
    Poziom 14  

    Cytat:
    żeby po samym naciśnięciu switcha

    Co Masz na myśli ?
    By zmienić kolejność przesuwania bitów Musisz albo nacisnąć drugi raz ten sam przycisk, lub też nacisnąć inny, ewentualnie jeśli skończy się przesuwanie w lewo, nastąpi przesuwanie w prawo.
    Jeśli ma być to ten sam przycisk to Musisz dodać informację, która będzie widoczna dla podprogramu, który z kolei wyzwoli przesuwanie bitów.
    Jeżeli z kolei naciskając inny przycisk ma się wykonać przesuniecie w druga stronę, Musisz praktycznie powtórzyć to samo, z tym ,że wejście ustawić na odpowiedni pin i zmienić przesunięcie bitowe w drugą stronę.
    W przypadku trzeciej możliwości Musisz sprawdzić, czy skończyło się przesunięcie w lewo, jeśli tak to zaczynasz w prawo.
    Życzę miłej zabawy.

    A tak w ogóle to jednak C jest dla mnie trochę dziwne.
    Zapis PORTD|= 1<<PD0 ; jest informacją, że na porcie D, pinie 0 wystąpi 0, lub 1 (zależnie od negacji)
    Natomiast w ASM zapis

    LDS R16, {zmienna}
    STS &H0644, R16

    gdzie zmienna = odpowiedni ciąg bitów
    &H0644 = adres portu
    Mozna oczywiście przypisać również stałą.

    0
  • #8 27 Cze 2015 13:35
    ASMnauka_
    Poziom 14  

    Dople , oczywiście Masz rację, lecz w tym przypadku musi być licznik zwiększający naciśnięcie przycisku, a do tego drganie styków.
    Co do drgań styków, niezbędny jest Timer, lub pętla, który\a odliczał\a będzie potrzebny czas.

    0
  • #9 27 Cze 2015 13:44
    Dople
    Poziom 19  

    ASMnauka_ napisał:

    A tak w ogóle to jednak C jest dla mnie trochę dziwne.
    Zapis PORTD|= 1<<PD0 ; jest informacją, że na porcie D, pinie 0 wystąpi 0, lub 1 (zależnie od negacji)


    Nie łapię. Na PD0 będzie 1.

    0
  • #13 27 Cze 2015 14:14
    bartek123321
    Poziom 10  

    a co do zapamiętania stanu przycisku.. dla początkującego najprościej będzie zrobić programowy przerzutnik który zmienia stan po naciśnięciu przycisku, a do debouncowania wystarczy _delay_ms(25), póżniej w pętli sprawdzać stan zmiennej ustawionej przez "przerzutnik" i układ gotowy

    Dodano po 2 [minuty]:

    Od jakiej negacji? suma logiczna będzie dawała wynik 1 jeżeli jeden ze składników wynosi jeden. Nawet jeżeli bit PD0 będzie miał stan 0 to po tej operacji będzie miał stan 1, jeżeli miał stan 1 to nic się nie zmieni

    PORTD xxxxxxx0
    + 00000001
    --------------------------
    xxxxxxx1

    0
  • #15 27 Cze 2015 14:20
    bartek123321
    Poziom 10  

    do standardowych microswitchy? ja stosowałem 25 ms i nie było jakiegoś problemu, dla świętego spokoju można zastosować więcej. W książce pana Kardasia jest czas 80 ms więc będzie on najbezpieczniejszy.

    0
  • #17 27 Cze 2015 14:29
    bartek123321
    Poziom 10  

    dlatego najbezpieczniej będzie dać czas 80 ms, poza tym zawsze można sprawdzić kilka opcji.

    Dodano po 4 [minuty]:

    A co do tego programowego przerzutnika, można go zrealizować np. w taki sposób:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Albo żeby było bardziej czytelne:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #18 27 Cze 2015 14:45
    Dople
    Poziom 19  

    Nie chcecie edukacji autora tematu popchnąć w jakimś dziwnym kierunku? ;) Może i @Lucasinhoo osiągnie ten tymczasowy cel związany z przyciskiem, ale chyba chodzi o coś bardziej perspektywicznego.

    Proponuję naukę poprzez przetrząsanie Internetu, albo - lepiej - kupno książki.

    0
  • #19 27 Cze 2015 16:21
    bartek123321
    Poziom 10  

    oczywiście powinien on rozwiązywać sam proste czy trudniejsze problemy, ale warto czasem podejrzeć rozwiązania innych osób, bo ilu programistów tyle rozwiązań :)

    0
  • #20 27 Cze 2015 20:59
    Lucasinhoo
    Poziom 6  

    Chodzi mi dokładnie o to, że gdy przycisk jest zwolniony wykonuje się instrukcja po "else", a gdy nacisnę switcha to nic się nie zmienia, dopiero gdy będę trzymał go wciśnietego, to po zakończeniu cyklu diod tzn. zapalania np kolejno od lewej strony, wtedy przy wciśnietym switchu zapalają się kolejno od prawej strony, chodzi mi o to czy w prosty sposób można zapamiętać w mikrokontrolerze, że switch był wciśniety i po zakończeniu instrukcji else (bez trzymania switcha) wykonała się instrukcja if.
    Jak na razie bardzo dużo wiedzy czerpię z poradników internetowych oraz filmów.

    0
  • #21 28 Cze 2015 11:10
    bartek123321
    Poziom 10  

    Jeżeli zastosujesz to co ja Ci napisałem, to wystarczy że jako warunek sprawdzany w ifie dasz wskaznik. Wtedy jak naciśniesz to Ci się zapamięta albo 1 albo 0 w zmiennej wskaznik i wtedy masz zapamiętywane wciśnięcie - taki programowy przerzutnik T. A żeby działało to sprawniej (pewnie sam zauważysz czemu - będziesz miał małą "bezwładność") to trzebaby zmienić zapalanie diod - nie zapalać ich na sztywno po kolei tylko zapętlić i dać warunek do sprawdzenia

    0