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 - Pierwszy program i pytanie

oko.mar 01 Lis 2012 13:11 1527 10
  • #1 01 Lis 2012 13:11
    oko.mar
    Poziom 9  

    Witam. Wlasnie zacząłem zabawe z programowaniem i napisałem swój pierwszy ambitny program :). Zasada jes prosta po wciśnieciu przycisku dioda swieci okreslony czas. Mam pytanie odnośnie przełącznika, jaką podać instrukcę żeby dioda zaświeciła sie na określony czas np 2 sekundy jeśli przełącznik będzie cały czas wciśnięty

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Z góry dziękuje za odpowiedź

    0 10
  • #2 01 Lis 2012 13:42
    dondu
    Moderator Mikrokontrolery Projektowanie

    Witaj,

    Zacznijmy od tego, że Twój program nie kompiluje się ponieważ zawiera błędy.
    Doprowadź go najpierw do stanu, w którym skompiluje się poprawnie - próbowałeś go już kompilować?

    Cytat:
    rm -rf dd.o PROBY.elf dep/* PROBY.hex PROBY.eep PROBY.lss PROBY.map
    Build succeeded with 0 Warnings...
    avr-gcc -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=1000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT dd.o -MF dep/dd.o.d -c ../dd.c
    ../dd.c:1:1: warning: "F_CPU" redefined
    <command-line>: warning: this is the location of the previous definition
    ../dd.c: In function 'main':
    ../dd.c:17: error: 'time' undeclared (first use in this function)
    ../dd.c:17: error: (Each undeclared identifier is reported only once
    ../dd.c:17: error: for each function it appears in.)
    ../dd.c:18: error: expected ';' before '{' token
    ../dd.c:26: error: expected declaration or statement at end of input
    ../dd.c:26: error: expected declaration or statement at end of input
    make: *** [dd.o] Error 1
    Build failed with 6 errors and 2 warnings...


    Dodatkowo zapoznaj się z tematem definiowania F_CPU: http://mikrokontrolery.blogspot.com/2011/03/fcpu-gcc-gdzie-definiowac.html

    0
  • #4 01 Lis 2012 15:59
    mirekk36
    Poziom 42  

    piotrva napisał:
    ....
    Po co, skoro można:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Nie dość że można to nawet trzeba (o ile na początku chcemy w ogóle korzystać z delayów) ... bo to co napisał nowynom, niestety w przypadku ustawienia optymalizacji -Os w ogóle zniknie z kodu po kompilacji :(

    0
  • #5 01 Lis 2012 16:07
    oko.mar
    Poziom 9  

    dondu napisał:
    Witaj,

    Zacznijmy od tego, że Twój program nie kompiluje się ponieważ zawiera błędy.
    Doprowadź go najpierw do stanu, w którym skompiluje się poprawnie - próbowałeś go już kompilować?

    Cytat:
    rm -rf dd.o PROBY.elf dep/* PROBY.hex PROBY.eep PROBY.lss PROBY.map
    Build succeeded with 0 Warnings...
    avr-gcc -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=1000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT dd.o -MF dep/dd.o.d -c ../dd.c
    ../dd.c:1:1: warning: "F_CPU" redefined
    <command-line>: warning: this is the location of the previous definition
    ../dd.c: In function 'main':
    ../dd.c:17: error: 'time' undeclared (first use in this function)
    ../dd.c:17: error: (Each undeclared identifier is reported only once
    ../dd.c:17: error: for each function it appears in.)
    ../dd.c:18: error: expected ';' before '{' token
    ../dd.c:26: error: expected declaration or statement at end of input
    ../dd.c:26: error: expected declaration or statement at end of input
    make: *** [dd.o] Error 1
    Build failed with 6 errors and 2 warnings...


    Dodatkowo zapoznaj się z tematem definiowania F_CPU: http://mikrokontrolery.blogspot.com/2011/03/fcpu-gcc-gdzie-definiowac.html


    Wiem przepraszam ale wkradl sie blad z funkcja time, nie powinno jej tam być.
    Dzieki Panowie i jeszcze jedno pytanko w jakim miejscu podac insrukcje opoznienia. Przepraszam za glupie pytania, ale tak jak pisalem dopiero zaczynam.

    0
  • #6 01 Lis 2012 16:11
    dondu
    Moderator Mikrokontrolery Projektowanie

    Jak rozumie pytasz nadal o pierwotny problem? Możesz na przykład zastosować zmienną, która będzie pamiętała aktualny stan klawisza (że był naciśnięty) i dopóki klawisz nie zostanie puszczony, nie dopuści do ponownego zapalenia diody. Wykorzystaj do tego na przykład instrukcję if.

    0
  • #7 01 Lis 2012 17:39
    oko.mar
    Poziom 9  

    dondu napisał:
    Jak rozumie pytasz nadal o pierwotny problem? Możesz na przykład zastosować zmienną, która będzie pamiętała aktualny stan klawisza (że był naciśnięty) i dopóki klawisz nie zostanie puszczony, nie dopuści do ponownego zapalenia diody. Wykorzystaj do tego na przykład instrukcję if.


    hmmm, ten program ktory podalem dziala bez problemu, chodzi mi tylko o to ze dopoki trzymam przycisk dioda caly czas swieci, a jak puszcze to dioda swieci jeszcze ok 2 sekun, mnie natomiast chodzi o to co zmienic w programie, ze jak wciskam przycisk i trzymam go powiedzmy nawet 10 minut to dioda i tak powinna zaswiecic sie na 2 sekundy (wraz z nacisnieciem przycisku) i zgasnac (przycisk dalej zwiera do masy)

    0
  • #8 01 Lis 2012 17:50
    Raphaw
    Poziom 20  

    Wystarczy wykryć zbocze opadające na wejściu przypisanym do przycisku, a po instrukcji delay zgasić diodę.

    0
  • #9 01 Lis 2012 18:36
    tmf
    Moderator Mikrokontrolery Projektowanie

    oko.mar napisał:
    dondu napisał:
    Jak rozumie pytasz nadal o pierwotny problem? Możesz na przykład zastosować zmienną, która będzie pamiętała aktualny stan klawisza (że był naciśnięty) i dopóki klawisz nie zostanie puszczony, nie dopuści do ponownego zapalenia diody. Wykorzystaj do tego na przykład instrukcję if.


    hmmm, ten program ktory podalem dziala bez problemu, chodzi mi tylko o to ze dopoki trzymam przycisk dioda caly czas swieci, a jak puszcze to dioda swieci jeszcze ok 2 sekun, mnie natomiast chodzi o to co zmienic w programie, ze jak wciskam przycisk i trzymam go powiedzmy nawet 10 minut to dioda i tak powinna zaswiecic sie na 2 sekundy (wraz z nacisnieciem przycisku) i zgasnac (przycisk dalej zwiera do masy)

    Świeci się przez te 2 sekundy bo taki masz delay - w momencie puszczenia przycisku program jest na tym delayu. Można to zrobić na kilka sposobów - prosty, ale badziewny, albo bardziej zawiły i lepszy.
    1. Prosty i badziewny. Wrzuć dodatkową flagę, którą ustawiasz w chwili wykrycia naciśnięcia przycisku i zerujesz w momencie jego puszczenia (czyli do if dodajesz else). Wejście w zapalenie LED i delay jest uwarunkowane spełnieniem dwóch warunków - naciśnięciem przycisku i wyzerowaniem flagi. Jeśli przycisk jest wciśnięty, ale flaga jest ustawiona (czyli przycisk poprzednio też był wciśnięty) nic nie robisz. Dzięki temu przy każdym wciśnięciu LED zapali się tylko na 2s niezależnie jak długo będziesz przycisk dusił.
    2. IMHO lepsze rozwiązanie to wykorzystanie timera. Wszystko robisz tak jak poprzednio, tyle, że zamiast dealya wykorzystujesz timer, którego przerwanie np. overflow, kasuje LEDa. W ten sposób nie blokujesz MCU na 2 s.

    0
  • #10 01 Lis 2012 19:09
    oko.mar
    Poziom 9  

    Dzieki za pomoc ale widze ze sie musze jeszcze bardzo duzo nauczyc bo slabo to rozumiem

    0
  • Pomocny post
    #11 01 Lis 2012 19:33
    Raphaw
    Poziom 20  

    Na początku nauki programowania warto rozpisać krok po kroku problem oraz algorytm rozwiązania. Późniejsze przełożenie tego na kod jest już sprawą prostszą. Problem (o ile dobrze zrozumiałem) przedstawia się następująco:
    - wykrycie momentu wciśnięcia przycisku,
    - wykonanie jednorazowej akcji (włącz led),
    - odczekanie określonego czasu,
    - wykonanie jednorazowej akcji (wyłącz led).

    Algorytmy rozwiązania mogą być różne. Najlepszym wyjściem byłoby, jak proponował kolega tmf zastosowanie timera, ale to chyba jeszcze "za wysokie progi". Opisywany wyżej efekt można uzyskać na dwa sposoby
    1) (sposób 1. kolegi tmf) w którym korzystamy z pomocniczej flagi (zmiennej w której zapamiętujemy fakt wciśnięcia przycisku i zapalenia diody)
    - sprawdzamy stan przycisku:
    a) przycisk wciśnięty i flaga wyzerowana (to oznacza że przycisk dopiero został wciśnięty):
    - zapalamy diodę
    - odczekujemy 2s (delay)
    - gasimy diodę
    - ustawiamy flagę na 1 (wówczas przy następnym wykonaniu pętli warunek a) nie będzie spełniony i dioda zostanie załączona tylko raz).
    b)przycisk nie wciśnięty:
    - ustawiamy flagę na 0
    2) Sposób o którym wspomniałem wcześniej:
    - wykrycie chwili wciśnięcia przycisku (zbocze opadające)
    - zapalamy diodę
    - odczekujemy 2s (delay)
    - gasimy diodę
    W tym przypadku "sztuczkę" stanowi wykrycie chwili w której przycisk został wciśnięty. Można tego dokonać w następujący sposób:
    - cyklicznie sprawdzamy stan wejścia przycisku (w pewnym odstępie czasowym) i zapamiętujemy w dwóch zmiennych stan aktualny i poprzedni. W momencie gdy stan poprzedni wynosi 1, a aktualny 0 wykryliśmy moment wciśnięcia przycisku.
    Pozdrawiam i życzę cierpliwości w nauce.

    0