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.

[C][atmega8] - Zmiana stanu na portach wyjścia

Fifi209 15 Lip 2012 12:37 4292 17
  • #1 15 Lip 2012 12:37
    Fifi209
    Poziom 7  

    Witam, od niedawna interesuje się programowaniem mikrokontrolerów

    Kupiłem programator USBasp, podłączyłem wszystko, z kursów przetestowałem kilka przykładów, napisałem jakieś proste miganie diodami.

    A teraz opiszę w czym problem:

    Mam 3 diody LED i przycisk

    Zielony LED - PORTB0
    Czerwony LED - PORTB1
    Żółty LED - PORTB2

    Przycisk - PORTC0

    Diody ustawiłem tak:

    Code:

    DDRB = 0b111;


    W jakimś kursie znalazłem taki zapis:
    Code:

    DDRB |= (1<<LED1) | (1<<LED2);

    Oczywiście LED1 i LED2 był zdefiniowane odpowiednio jako PB0 i PB1

    Wiem, że << oznacza przesunięcie bitowe w lewo, jednak nie potrafię zrozumieć tego zapisu. I co znaczy też | w tym zapisie? Póki co nie rozumiem tego, więc piszę binarnie.

    Dla zielonego LED'a ustawiam stan:
    Code:

    PORTB = 0b1


    Później ustawiam przycisk jako wejście:
    Code:

    DDRCE = 0b0;


    I pull up
    Code:

    PORTC = 0b1


    Miganie diodami w pętli:
    Code:

    PORTB ^= 0b11


    Potrafię sprawdzić czy przycisk nie jest wciśnięty
    Code:

    if (PINC & (1<<przycisk)

    - zaciągnięte z jakiegoś przykładu
    btw jak to odwrócić? czyli sprawdzać czy jest wciśnięty?

    0 17
  • Pomocny post
    #2 15 Lip 2012 12:54
    tronics
    Poziom 36  

    Cytat:
    jednak nie potrafię zrozumieć tego zapisu

    Jak przesuniesz jedynkę o 3 pola w lewo to masz wartość 8 (innymi słowy to jest *2^n). | to suma logiczna (OR) - czyli zapis (1<<3|1<<5) oznacza ustawienie jako 1 bitów 3 i 5 licząc 0:7.
    Cytat:
    czyli sprawdzać czy jest wciśnięty

    Negacja logiczna.

    0
  • #4 15 Lip 2012 12:59
    Fifi209
    Poziom 7  

    Jakoś poradziłem sobie:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Na ile to jest poprawnie? Jak można zrobić to lepiej/wygodniej/optymalniej ?

    Dodano po 1 [minuty]:

    lukashb napisał:
    Witam. Polecałbym przeczytać to:
    http://hobby.abxyz.bplaced.net/index.php?pid=4&aid=4
    Pozdrawiam


    Czytałem ale jakoś nie trafia do mnie ten kurs.

    0
  • #6 15 Lip 2012 14:06
    Fifi209
    Poziom 7  

    Mam dwie diody, zieloną i czerwoną podłączone do PB0 i PB1

    I przycisk podłączony do PC0

    Diody mają migać na przemian, po naciśnięciu przycisku ma zapalić się dioda żółta podłączona do PB2 a diody zielona i czerwona mają przestać migać do czasu zwolnienia przycisku.

    0
  • #7 15 Lip 2012 14:24
    steter
    Poziom 7  

    Może to Ci ułatwi zrozumienie, ale proponuję ci zakupić jakąś książkę,
    bo tak z internetu to przynajmniej mi było ciężko, a też dopiero zaczynam naukę.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    /*
    * main.c
    *
    * Created on: 2012-07-10
    * Author: Sylwek
    */

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

    #define led_zielona (1<<PB0)//definicja zielonej diody dla PORTB0
    #define led_zielona_on PORTB |=led_zielona //ustawiam bitO portuB w stan wysoki
    #define led_zielona_off PORTB &= ~led_zielona //ustawiam bit0 portuB w stan niski

    #define led_czerwona (1<<PB1)//definicja czerwonej diody dla PORTB1
    #define led_czerwona_on PORTB |=led_czerwona //ustawiam bit1 portuB w stan wysoki
    #define led_czerwona_off PORTB &= ~led_czerwona //ustawiam bit1 portuB w stan niski

    #define led_zolta (1<<PB2)//definicja żółtej diody dla PORTB3
    #define led_zolta_on PORTB |=led_zolta //ustawiam bit2 portuB w stan wysoki
    #define led_zolta_off PORTB &= ~led_zolta //ustawiam bit2 portuB w stan niski

    #define przycisk (1<<PC0)//definicja przycisku dla PORTC0
    #define przycisk_on !(PINC & przycisk)//jeśli przycisk wciśnięty
    #define przycisk_off (PINC & przycisk)//jeśli pzycisk nie wciśnięty

    int main(void)
    {
    //przykład prostego programu

    DDRB |= led_zielona|led_czerwona|led_zolta;//kierunek pinów - wyjściowy
    PORTB &= ~(led_zielona|led_czerwona|led_zolta);//zerowanie tych bitów
    DDRC &= ~(przycisk);//kierunek pinu - wejściowy
    PORTC |=przycisk;//podcągnięcie pinu do rezystora wewnętrznego do VCC

    while(1)//pętla nieskączona
    {
    if(przycisk_on)//jeśli przycisk wciśnięty
    {
    led_zielona_on;//załączenie czerwonej diody
    _delay_ms(1000);//odczekanie 1s
    led_czerwona_on;
    _delay_ms(1000);
    led_zolta_on;
    _delay_ms(1000);
    led_zielona_off;//zerowanie diód
    led_czerwona_off;
    led_zolta_off;
    //ale można by było też tak
    PORTB=00;
    }

    }
    }
    /*nie brałem tu pod uwagę drgań styków, to jest prosty program tak, żeby zobrazować
    niektóre udogodnienia*/
    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #8 15 Lip 2012 14:35
    dondu
    Moderator Mikrokontrolery Projektowanie

    Fifi209 napisał:
    Na ile to jest poprawnie? Jak można zrobić to lepiej/wygodniej/optymalniej ?

    Problem polega na tym, że nie komentujesz kodu w każdej istotnej linii.
    Gdybyś to robił łatwo byłoby nam znaleźć Twoje błędy, bez dodatkowych pytań.
    Rób to zawsze dla siebie, a w szczególności gdy wrzucasz kod na forum.

    Spróbuj tak:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Oczywiście nie jest to idealne rozwiązanie (nie uwzględnia drgań styków), ale powinno spełnić Twoje wymagania.

    Dodano po 2 [minuty]:

    steter napisał:
    nie wiem dlaczego kod nie wylądował w ramce z kolorową składnią?

    Dałeś SYNTAX ale nieprawidłowo: http://mikrokontrolery.blogspot.com/2011/04/fora-dyskusyjne-sa-bardzo-pomocne.html

    0
  • #9 15 Lip 2012 14:40
    Fifi209
    Poziom 7  

    steter - Mają migać dwie zielona i czerwona cały czas, a gdy wcisnę przycisk mają się zgasić i w tym czasie ma się palić żółta dioda do czasu zwolnienia przycisku.

    co do kolorowania składni, zobacz w poście jak tagi pokręciłeś.

    dondu - niestety, nie działa, świeci się tylko czerwona, w dodatku coś słabo, owszem żółta się zapala po naciśnięciu ale zielona ani drgnie, w ogóle jakby za mało napięcia dostawały.

    0
  • #11 15 Lip 2012 14:45
    Fifi209
    Poziom 7  

    W AVRdude burn-o-mat ustawiłem sobie zegar na 8MHz i fast rising power

    Schematu nie mam, ale mogę zrobić jeżeli opis nie wystarcza.

    0
  • #12 15 Lip 2012 14:52
    dondu
    Moderator Mikrokontrolery Projektowanie

    Opis jest dokładny ale napisałeś:

    Fifi209 napisał:
    ... w ogóle jakby za mało napięcia dostawały.

    a to oznacza, że poza programem i ustawieniami zegara, problem może leżeć w schemacie.

    Fifi209 napisał:
    W AVRdude burn-o-mat ustawiłem sobie zegar na 8MHz i fast rising power

    Pytałem o warningi kompilacji - nie odpowiedziałeś.
    Pytam ponownie ponieważ nie podałeś czy w kompilatorze zegar ustawiłeś, a jednocześnie w kodzie go nie masz.

    0
  • #13 15 Lip 2012 14:54
    Fifi209
    Poziom 7  

    Bo przy moim programie, który napisałem i zapytałem czy można by zrobić to lepiej, wszystko działa jak należy, przy Twoim nie dość że świeci tylko czerwona (ciągle) to jeszcze jakoś słabo :)

    0
  • #15 15 Lip 2012 15:00
    Fifi209
    Poziom 7  

    Na samym początku

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Brak warningów, wszystko kompiluje się dobrze

    0
  • #17 15 Lip 2012 15:06
    steter
    Poziom 7  

    Kod: c
    Zaloguj się, aby zobaczyć kod

    /*
    * main.c
    *
    * Created on: 2012-07-10
    * Author: Sylwek
    */

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

    #define led_zielona (1<<PB0) //definicja zielonej diody dla PORTB0
    #define led_zielona_off PORTB &= ~led_zielona //ustawiam bit0 portuB w stan niski
    #define led_czerwona (1<<PB1) //definicja czerwonej diody dla PORTB1
    #define led_czerwona_off PORTB &= ~led_czerwona //ustawiam bit1 portuB w stan niski
    #define led_zolta (1<<PB2) //definicja żółtej diody dla PORTB3
    #define led_zolta_on PORTB |=led_zolta //ustawiam bit2 portuB w stan wysoki
    #define led_zolta_off PORTB &= ~led_zolta //ustawiam bit2 portuB w stan niski
    #define przycisk (1<<PC0) //definicja przycisku dla PORTC0
    #define przycisk_on !(PINC & przycisk) //jeśli przycisk wciśnięty

    int main(void)
    {
    //przykład prostego programu
    DDRB |= led_zielona|led_czerwona|led_zolta; //kierunek pinów - wyjściowy
    PORTB &= ~(led_zielona|led_czerwona|led_zolta); //zerowanie tych bitów
    DDRC &= ~(przycisk); //kierunek pinu - wejściowy
    PORTC |=przycisk; //podcągnięcie pinu do rezystora wewnętrznego do VCC
    while(1) //pętla nieskączona
    {
    led_zolta_off; //wyłączenie żółtej diody
    PORTB ^=led_czerwona; //zmiana stanu diody na przeciwną
    PORTB ^=led_zielona; //zmiana stanu diody na przeciwną
    _delay_ms(500); //czekać 500ms
    while(przycisk_on) //pętla wtedy ja przycisk jest włączony
    {
    led_czerwona_off; //wyłączenie czerwonej diody
    led_zielona_off; //wyłączenie zielonej diody
    led_zolta_on; //załączenie żółtej diody
    }

    }
    }
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Bardziej zrozumiale już się chyba nie da.
    U mnie działa. Nie mam wpisanego taktowania procesora ponieważ piszę w eclipse
    a taktowanie ustawiam przy tworzeniu projektu.

    0