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.

4 diody migające na przemian-kod

GregoriusPL 02 Mar 2013 18:49 2529 19
  • #1 02 Mar 2013 18:49
    GregoriusPL
    Poziom 10  

    Moim celem jest zrobić układ z ATtiny2313, w którym będą 4 diody. Mają migać na przemian, raz parzyste raz nieparzyste. Wykorzystałem jako podstawę kod znaleziony w sieci(kurs programowania).Przerobiłem na swoje potrzeby i oto kod:

    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 B będą wyjściami */
       DDRB = 01010101;  /* 0xFF binarnie 1111 1111 */

       /* Początek nieskończonej pętli */
       while(1)
       {
          PORTB = 01000100;    /* 0xaa binarnie 1010 1010 */
          /* opóźnienie 0.33 sek. */
          _delay_ms(330);
           PORTB = 00010001;    /* 0x55 binarnie 0101 0101 */
          /* opóźnienie 0.33 sek. */
          _delay_ms(330);
       }
    }


    Program był napisany na atmege8, oryginalnie na portD. Zamieniłem to na portB.

    Co się nie zgadza:diody miały się świecić na pinach o nr 1,3,5,7 a świecą się tylko na 0 i 6

    Co należy zmienić by uzyskać pożądany efekt?

    0 19
  • #2 02 Mar 2013 18:57
    netotron
    Poziom 26  

    GregoriusPL napisał:

    Code:
      /* Wszystkie linie portu B będą wyjściami */
    
       DDRB = 01010101;  /* 0xFF binarnie 1111 1111 */

    Wszystkie linie portu B będą wyjściami, a co zrobiłeś? DDRB = 01010101

    0
  • #3 02 Mar 2013 19:08
    excray
    Poziom 39  

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #4 02 Mar 2013 20:34
    GregoriusPL
    Poziom 10  

    Linie komentarza są ze starego kodu i nijak mają się do mojej przeróbki

    Mój tok rozumowania:
    DDRB = 01010101 bo piny 1,3,5,7 chce zeby były wyjściami a reszta wejściami

    Czy zero na początku oznacza pin 0 czy pin 7? Innymi słowy od której strony zaczynamy numerować?

    Pytanie do postu wyżej- Czy kolega mógłby to rozpisać binarnie? Nie rozumiem zbytnio kodu szesnastkowego i nie umiem swobodnie zamieniąc między dwójkowym a tym.

    0
  • #5 02 Mar 2013 20:36
    excray
    Poziom 39  

    GregoriusPL napisał:
    Czy zero na początku oznacza pin 0 czy pin 7? Innymi słowy od której strony zaczynamy numerować?

    Zero na początku oznacza bit 7.

    GregoriusPL napisał:
    Czy kolega mógłby to rozpisać binarnie? Nie rozumiem zbytnio kodu szesnastkowego i nie umiem swobodnie zamieniąc między dwójkowym a tym.

    W windowsie masz kalkulator z zamianą hex-bin-dec. Tak samo pełno jest takich programów w internecie.

    0
  • #6 02 Mar 2013 20:46
    GregoriusPL
    Poziom 10  

    No dobrze, to już wiem jak działa to zamienianie.

    Kolega w poprawionym kodzie ustawił 10101010 czyli praktycznie tak jak było. A ja bym chciał to zrobić tak jak mówiłem czyli żeby diody były na pinach 1,3,5,7 i raz się świecił 1 i 5 a następnie 3 i 7.

    0
  • #7 02 Mar 2013 21:03
    zumek
    Poziom 39  

    GregoriusPL napisał:

    Mój tok rozumowania:
    DDRB = 01010101 bo piny 1,3,5,7 chce zeby były wyjściami a reszta wejściami

    Twój tok rozumowania, nie idzie właściwą drogą, bo pomimo tego, że liczba składa się z zer i jedynek, nie jest przez kompilator traktowana jako liczba binarna, tylko jako dziesiętna.

    0
  • #8 02 Mar 2013 21:07
    GregoriusPL
    Poziom 10  

    A można zrobić tak by liczba binarna była jako binarna? Czy po prostu trzeba wartości wpisywać szesnastkowo

    EDIT: Poprawiłem kod, wpisałem moje wartości szesnastkowo i gra gitara. Jednak chciałbym wiedzieć czy da się też to zrobić binarnie ( tak z czystej ciekawości :) )

    0
  • #9 02 Mar 2013 21:37
    BlueDraco
    Specjalista - Mikrokontrolery

    Oczywiście - trzeba podać stałą w postaci binarnej, a nie dziesiętnej.

    0
  • #10 02 Mar 2013 21:39
    GregoriusPL
    Poziom 10  

    No dobrze,tylko jak, skoro po prostu wpisując wartość binarną kompilator odczytuje to jako dziesiętną? Czy trzeba wstawić coś podobnego jak przed hex czyli 0x?

    0
  • #11 02 Mar 2013 21:59
    BlueDraco
    Specjalista - Mikrokontrolery

    Naprawdę nie możesz tego sprawdzić w dokumentacji i tysiącach programów przykładowych, choćby na tym forum? Tak, trzeba wstawić coś podobnego. Poszukaj co.

    Dodam, że np. PORTD = 0101; nie jest interpretowane ani jako wartość dziesiętna, ani jako binarna. Może jednak warto poczytać o zapisie stałych w języku, w którym chce się pisać programy, żeby wiedzieć, co się właściwie pisze...

    0
  • #12 02 Mar 2013 22:06
    GregoriusPL
    Poziom 10  

    ok dobrze nie ma co się denerwować, dziękuje za pomoc:) Ja już sobie poczytam o tych stałych

    0
  • #14 06 Mar 2013 10:08
    xamrex
    Poziom 28  

    GregoriusPL napisał:
    Mój tok rozumowania:
    DDRB = 01010101 bo piny 1,3,5,7 chce zeby były wyjściami a reszta wejściam


    Tak jak mówili poprzednicy.
    Żeby zapisać to w postaci binarnej, należy dodać 0b (jeśli jest to zapis binarny) lub 0x (jeśli zapis szesnastkowy).
    Więc w twoim przypadku poprawny zapis to:
    DDRB = 0b01010101;

    0
  • #15 06 Mar 2013 17:29
    sibatec
    Poziom 1  

    Witam

    Ja tez mam problem z diodami i sie poddaje . Czy ktos odplatnie napisze mi program w bascomie avr na atmega32 ?

    0
  • #16 06 Mar 2013 20:56
    GregoriusPL
    Poziom 10  

    z mojego doświadczenia Ci powiem sprawdź czy dobrze ześ wszystko popodłączał albo też sam sposób programowania- mi się na przykład zdażyło że ładowałem ciągle zmieniony program a faktycznie nic się nie zmieniało ( no coś nie zagrało) dopiero jak wyłączyłem i włączyłem programator to zaczęło działać

    0
  • #17 08 Mar 2013 07:49
    charwer
    Poziom 15  

    GregoriusPL napisał:
    Pytanie do postu wyżej- Czy kolega mógłby to rozpisać binarnie? Nie rozumiem zbytnio kodu szesnastkowego i nie umiem swobodnie zamieniąc między dwójkowym a tym.


    xamrex napisał:
    Więc w twoim przypadku poprawny zapis to:
    DDRB = 0b01010101;


    Zamiast używać nieczytelnego zapisu hexadecymalnego, lub binarnego przypisania do rejestru portu, proponuję od razu nabierać dobrych nawyków i stosować zapis podobny do tego:

    Code:

    #define LED1 (1<<PB0)
    #define LED2 (1<<PB1)
    #define LED3 (1<<PB2)
    #define LED4 (1<<PB3)

    (...)

    DDRB |= LED1|LED2|LED3|LED4;


    Od razu widać, co się w programie dzieje.

    0
  • #18 09 Mar 2013 00:35
    GregoriusPL
    Poziom 10  

    Skorzystałem z rady kolegi powyżej i faktycznie bardziej czytelny jest zapis :)

    Mam kolejny problem, chcąc się nauczyć operacji na bitach napisałem prosty programik, i teraz chce żeby :
    - przycisk nie wciśnięty- diody migają w sposób przeze mnie ustalony
    - przycisk wciśnięty- natychmiast się zapalają wszystkie lampki, gdy zwalniam przycisk to wraca do poprzedniej pętli

    Code:
     
    
    #include <avr/io.h> 
    #include <util/delay.h> 
     

    #define LED1 PB0 
    #define LED2 PB1 
    #define LED3 PB2
    #define LED4 PB3 
    #define KLAWISZ PD5               

    int main(void) 

        //########### I/O ########### 
        DDRB  |= (1<<LED1) | (1<<LED2) | (1<<LED3) | (1<<LED4); //Ustawienie pinów sterujących diodami 
         PORTB = (1<<LED1) | (1<<LED2) | (1<<LED3) | (1<<LED4);

       DDRD  = (0<<KLAWISZ); //Ustawienie pinu klawisza jako wejście   
        PORTD =  (1<<KLAWISZ);
        while(1)//Pętla główna 
       
       {if(PIND & (1<<KLAWISZ))
     
       {
       PORTB = (1<<LED1) | (1<<LED2) | (1<<LED3) | (1<<LED4);
       _delay_ms(500);
         PORTB ^= (1<<LED1) | (0<<LED2) | (1<<LED3) | (0<<LED4);
       _delay_ms(500);
          PORTB ^= (1<<LED1) | (1<<LED2) | (1<<LED3) | (1<<LED4);
       _delay_ms(500);
       }
       
       PORTB = (1<<LED1) | (1<<LED2) | (1<<LED3) | (1<<LED4);
       
       }
    }

    Program działa w połowie ;p diody migają, gdy naciskam przycisk to cała pętla musi przejść i dopiero się zapalają wszystkie lampki. Próbowałem na kilanaście różnych sposób, wstawianie if else ( tu mniej więcej wychodziło ale po zwolnieniu przycisku nie wracało do głównej pętli). Jak ten problem rozwiązać?

    0
  • #19 09 Mar 2013 08:44
    BlueDraco
    Specjalista - Mikrokontrolery

    Jak rozwiązać?

    Całkowicie przebudować program. Wprowadzić przerwanie timera, np. 100 Hz i WSZYSTKO robić w tym przerwaniu. Pusta pętla główna z jedną instrukcją "idź spać", żadnych delay().

    Motto numer 3: nie da się napisać dobrego programu, który delay() używa gdziekolwiek poza inicjowaniem peryferiali. Jeśli delay() występuje w pętli lub w obsłudze przerwania - są z tego kłopoty, a przede wszystkim program nie daje się rozbudowywać.

    Pokazuję tu od czasu do czasu takie rozwiązania, ale nie dla AVR, których już dawno nie używam. Logika jest taka sama, tyko rejestry nazywają się inaczej.

    0
  • #20 09 Mar 2013 15:00
    GregoriusPL
    Poziom 10  

    Ok czyli muszę przejść do następnej części kursu bo o timerze jeszcze nie czytałem :) Postawiłem sobie takie zadania ale jak widać przy obecnych umiejętnościach jest dla mnie niemożliwe do wykonania.

    0