Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Klawiatura i Atmega 8 [c]

holgan22 18 Apr 2009 17:43 5691 32
  • #1
    holgan22
    Level 10  
    Witam. Chciałbym do mojej atmegi8 dołączyć prostą klawiaturę.Mają to być 2 przyciski.po wciśnięciu jednego ma się zapalić dioda 1,natomiast po wciśnięciu drugiego ma się zapalić dioda 2.
    Na porcie C na pinie 5,4,3 mam podłączone diody.Chciałbym pod port D podpiąć ową klawiaturę.
    mój mankament polega na tym,że nie wiem jak napisać pod to program.Wiem,że trzeba zainicjować porty,określić co się stanie po wciśnięciu przycisku 1 itd.. Jednak nie potrafię tego połączyć ze sobą.
    Czy ktoś posiada jakiś gotowy kod do takiego układu lub jest mi w stanie pomóc go napisać??próbuje programować w języku C i do niego tylko mam programator.
  • #2
    Myrek1
    Level 23  
    Przykład: http://avr.elektroda.eu/?q=node/11

    Tylko zamiast cbi oraz sbi używaj makro _BV() np:

    Code:

    //ustawienie bitu
    DDRB |= _BV(1);

    //wyzerowanie bitu
    DDRB &= ~_BV(1);


    A to dlatego, że poprzednie instrukcje zostały zliwidowane w nowszych wersjach avr-gcc.

    W przypadku pierwszego programu będzie to np.:
    Code:

    // zamiast sbi(LED_PORT_D,LED_BIT);        // użyj linii jako wyjścia
    DDRD |= _BV(4);

    //zamiast cbi(LED_PORT_O,LED_BIT);
    PORTD &= ~_BV(4);


    Trzeba jeszcze uwzględnić problem drgania styków klawiatury, ale o tym poczytasz na forum.
  • Helpful post
    #3
    lord_dagoth
    Level 25  
    holgan22 wrote:
    próbuje programować w języku C i do niego tylko mam programator.

    Chyba kompilator :P
    A co do programowania atmegi w C, to:
    http://www.kursc.dioda.com.pl/
  • #4
    holgan22
    Level 10  
    Nie programator a dokładniej ISPcable2. Kompilatorów mam więcej i potrafię rozróżnić jedno od drugiego :P
  • #5
    Myrek1
    Level 23  
    ISPCable 2 z propoxa to właśnie programator ISP. Jeśli chodzi o kompilator to na początek najlepiej avr-gcc w postaci WinAVR + AVR Studio ze strony Atmela.
  • #6
    lord_dagoth
    Level 25  
    holgan22 wrote:
    próbuje programować w języku C i do niego tylko mam programator.

    holgan22 wrote:
    Nie programator a dokładniej ISPcable2. Kompilatorów mam więcej i potrafię rozróżnić jedno od drugiego :P

    A co ma wspólnego programator z językiem, w jakim piszesz program?
  • #7
    holgan22
    Level 10  
    To,że np programu napisanego w BASCOM-ie nie wgram poprzez ten programator
  • #8
    User removed account
    User removed account  
  • #9
    holgan22
    Level 10  
    już próbowałem.nie chciał a z kolei z językiem C nie mam najmniejszego problemu. nie odbiegajmy jednak od tematu.
    Powiedzcie czego brakni,że po wgraniu do procesora nie działa.
    Ledy mam podłączone na porcie C pod PC5,PC4,PC3 a przycisk pod PB0 i masę.Oto kod.(wzorowałem się na linku podanym wyżej http://avr.elektroda.eu/?q=node/11)





    #include <avr/io.h> // dostęp do rejestrów
    #define F_CPU 4000000

    int main( void ) // program główny
    {
    sbi(DDRC,5); // użyj linii PD4 jako wyjścia
    sbi(PORTB,0); // "podciągnij" do logicznej 1 linię PD3

    while(1) // pętla nieskończona
    {
    cbi(PORTC,5); // zapal diodę LED podłączoną do linii PD4
    loop_until_bit_is_clear(PINB,0); // czekaj na naciśnięcie przycisku na PD3
    sbi(PORTD,4); // zgaś diodę LED podłączoną do linii PD4
    loop_until_bit_is_clear(PINB,0); // czekaj na naciśnięcie przycisku na PD3
    }
    }
  • #10
    lord_dagoth
    Level 25  
    To nie jest odbieganie od tematu, tylko wyprowadzanie z bardzo poważnego błędu ;) Kompilator generuje Ci plik HEX, który wrzucasz do uC programatorem. Nie ważne czy pisałeś program w C czy Bascomie, kodu źródłowego nie wrzucasz.

    Prawdopodobnie miałeś na myśli to, że środowisko w którym piszesz w C umożliwia Ci bezpośrednie zgranie hex'a do uC, a jak pisałeś korzystając ze środowiska Bascom'owego to możliwe że nie wykrywało twojego programatora. Ale wygenerowany hex możesz zgrać dowolnym programem obsługującym Twój programator, język nie ma tutaj nic do rzeczy.

    A wracając do tematu... zaglądałeś do linka podanego przeze mnie? Świetnie napisany i zilustrowany tutorial, wszystkie zaprezentowane tam układy i kody działają. Autor włożył bardzo wiele pracy w napisanie tego, i wyszło mu znakomicie. Między innymi znajduje się tam obrazek, który powinien wyprowadzić Cię z błędu ;)

    Klawiatura i Atmega 8 [c]
  • #11
    Myrek1
    Level 23  
    holgan22 wrote:
    już próbowałem.nie chciał a z kolei z językiem C nie mam najmniejszego problemu. nie odbiegajmy jednak od tematu.
    Powiedzcie czego brakni,że po wgraniu do procesora nie działa.
    Ledy mam podłączone na porcie C pod PC5,PC4,PC3 a przycisk pod PB0 i masę.Oto kod.(wzorowałem się na linku podanym wyżej http://avr.elektroda.eu/?q=node/11)


    I niby ten kod Ci się kompiluje? Pisałem Ci o zmianie sbi i cbi na makra _BV(). Zmień kod. Do tego czy twój kwarc ma 4MHz? Bo tak masz ustawione w kodzie.
  • #12
    holgan22
    Level 10  
    Tak kompiluje się bezproblemowo.Kwarc również ma 4MHz (zgodnie z zadeklarowaną wartością)
  • #13
    lord_dagoth
    Level 25  
    Pokaż schemat podłączenia zasilania do uC.
  • #14
    holgan22
    Level 10  
    Klawiatura i Atmega 8 [c]

    Tak mam podłączone całość. Narazie zamiast 4ech przycisków dałem 1 dla testów
  • #15
    Myrek1
    Level 23  
    Połącz do diod w szeregu rezystory z przedziału 330Ω-1kΩ. Podłącz też masę diod i przycisku do normalnej masy, a nie tylko do procka. Daj też kondensatory 22pF z kwarca do masy. Poczytaj troche o projektowaniu takich układów.

    Nie bardzo mi się chce wierzyć, że kompiluje Ci się program z taką składnią. Napisz jaki masz kompilator i środowisko.
  • #16
    lord_dagoth
    Level 25  
    heh... no to nic dziwnego że nie działa. A procek jeszcze nie spalił się? ;)
    Tak jak kolega wyżej mówił, do tego dodaj jakieś kondensatorki na zasilaniu 100uF i 100nF, Podepnij AREF i AVCC do +5V, reset opornikiem 10k do +5V, czym w ogóle zasilasz to?
    Zobacz jak zrobiłem to u siebie (na ATmedze32).
    Poza tym, czy tak ciężko jest chociaż kliknąć w link który Ci podałem wyżej? Masz tam PODANY JAK NA TACY, ładnie narysowany schemat:
    http://www.kursc.dioda.com.pl/img/art001_schemat1.png
  • #17
    holgan22
    Level 10  
    Klawiatura i Atmega 8 [c]

    Dokonałem takich zmian w układzie jak na schemacie.W poprzednim zapomniałem dorysować rezystora (fakt -> bez niego układ by się spalił).Całość zasilana jest napięciem stałym stabilizowanym o wartości 5V. Jakich zmian w programie muszę pokonać by po naciśnięciu przycisku zapaliła się dioda na pinie PC5 a po ponownym naciśnięciu przycisku zgasła??
  • #18
    Myrek1
    Level 23  
    Totalnie bez sensu.
    Kolego, jeśli chcesz pomocy to najpierw przeczytaj ze zrozumieniem to co napisaliśmy i pomyśl.
    Radzę wcześniej poczytać coś o diodach i ich zasilaniu oraz o projektowaniu systemów mikroprocesorowych.
    Jest tego od groma na elektrodzie oraz w Internecie.

    Wszystko już zostało powiedziane. Przeczytaj to co napisaliśmy ze zrozumieniem, pomyśl a będzie działało.
  • #19
    lord_dagoth
    Level 25  
    Mam wrażenie, że kolega w ogóle nie czyta tego co piszemy -_-'
    W moim poprzednim poście podałem Ci gotowy schemat, przystępnie napisany kurs... prześledź go, i to co jest tam napisane, zmontuj tamten układ.
  • #20
    holgan22
    Level 10  
    Zgadzam się z tym co kolega napisał.Nie doczytałem.Przepraszam.Układ zaprogramowałem i działa tylko...gdy zbliżę palec lub coś przewodzącego prąd to przycisku dioda sama zaczyna świecić,bądź mrygać (reaguje jak by wychwytywała "lewy" stan na wejściu) co może być tego przyczyną??czy nie jest to nadmiar jakiegoś kondensatora??czy też błąd podczas pisania programu??Nie bardzo rozumiem gdzie mam "podciągnąć" jedynkę i czemu ma to służyć.To mój program:

    Code:
    #include <avr/io.h>                        // dostęp do rejestrów
    

    int main( void )                        // program główny
    {
      sbi(DDRC,5);                               
      sbi(PORTC,4);                                // "podciągnij" do logicznej 1 linię

      while(1)                                // pętla nieskończona
      {
        cbi(PORTC,5);                        // zapal diodę LED podłączoną do linii
        loop_until_bit_is_clear(PINB,0);        // czekaj na naciśnięcie przycisku
        sbi(PORTC,5);                        // zgaś diodę LED podłączoną do linii
        loop_until_bit_is_clear(PINB,0);        // czekaj na naciśnięcie przycisku
      }
    }


    Proszę umieszczać listingi programów w znacznikach "Code". [c_p]
  • Helpful post
    #21
    Dr.Vee
    VIP Meritorious for electroda.pl
    Program jest bez sensu.
    Czytasz PB0, zamiast PC3.
    Poza tym dwa razy czekasz na to samo - aż przycisk zostanie wciśnięty - chociaż i to nie jest pewne, bo połowa komentarzy jest nieprawdziwa...

    Pozdrawiam,
    Dr.Vee
  • #22
    Myrek1
    Level 23  
    Dr.Vee wrote:
    Program jest bez sensu.
    Czytasz PB0, zamiast PC3.
    Poza tym dwa razy czekasz na to samo - aż przycisk zostanie wciśnięty - chociaż i to nie jest pewne, bo połowa komentarzy jest nieprawdziwa...

    Pozdrawiam,
    Dr.Vee


    Dobrze czyta bo pod PB0 ma przycisk a pod PC3, 4 i 5 ma diodę. To z tym szybkim odczytem przycisku to fakt, zanim się go puści to program kilkaset razy przeleci i się nie wyłączy. Ale chodzi o pokazanie jak to ma być. W pewnym momencie trzeba by wstawić opóźnienie.
    Podłącz wszystko tak jak wcześniej to opisaliśmy to nie będziesz miał cyrków z przyciskami.
    Poprawiony kod jest tu (choć i tak jest mało elegancki jeśli chodzi o przełącznik):

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

    #define F_CPU 4000000UL

    int main( void )
    {
      DDRC |= _BV(5);

      DDRB &= ~_BV(0);
      PORTB |= _BV(0);

      while(1)       
      {
        PORTC &= ~_BV(5);
        loop_until_bit_is_clear(PINB,0);       
        PORTC |= _BV(5);                       
        _delay_ms(100);
       loop_until_bit_is_clear(PINB,0);
     }
    }


    Czas można zwiększyć.
  • #23
    holgan22
    Level 10  
    Program po skompilowaniu ukazuje takie błędy:

    Code:
    avr-gcc -g -Wall -O2 -mmcu=atmega8    -c -o sterowanie.o sterowanie.c
    
    sterowanie.c:2:24: util/delay.h: No such file or directory
    sterowanie.c: In function `main':
    sterowanie.c:18: warning: implicit declaration of function `_delay_ms'
    sterowanie.c:21:2: warning: no newline at end of file
    make.exe: *** [sterowanie.o] Error 1

    > Process Exit Code: 2


    Natomiast bez funkcji "delay" wszystko kompiluje się bezproblemowo.
    Działanie wówczas jest dość dziwne.po każdorazowym naciśnięciu przycisku dioda mrygnie jednakże raz mrygnie i zgaśnie a raz mrygnie i pozostawi swój stan.Dopiero ponowne naciśnięcie przycisku spowoduje jej wyłączenie.
  • Helpful post
    #24
    Dr.Vee
    VIP Meritorious for electroda.pl
    Masz jakąś antyczną wersję avr-libc. Zainstaluj nową wersję WinAVR, a później przemyśl problem i poszukaj rozwiązania na forum.

    W końcu ile razy można pisać początkującym od nowa ten sam program - led + przycisk...

    Pozdrawiam,
    Dr.Vee
  • Helpful post
    #25
    Myrek1
    Level 23  
    holgan22 wrote:
    Program po skompilowaniu ukazuje takie błędy:

    Code:
    avr-gcc -g -Wall -O2 -mmcu=atmega8    -c -o sterowanie.o sterowanie.c
    
    sterowanie.c:2:24: util/delay.h: No such file or directory
    sterowanie.c: In function `main':
    sterowanie.c:18: warning: implicit declaration of function `_delay_ms'
    sterowanie.c:21:2: warning: no newline at end of file
    make.exe: *** [sterowanie.o] Error 1

    > Process Exit Code: 2


    Natomiast bez funkcji "delay" wszystko kompiluje się bezproblemowo.
    Działanie wówczas jest dość dziwne.po każdorazowym naciśnięciu przycisku dioda mrygnie jednakże raz mrygnie i zgaśnie a raz mrygnie i pozostawi swój stan.Dopiero ponowne naciśnięcie przycisku spowoduje jej wyłączenie.


    No to wszystko jasne. Dlatego działa sbi() i cbi(). Zainstaluj nową wersję WinAVR tak jak radzi kolega: http://sourceforge.net/project/showfiles.php?group_id=68108&package_id=66543

    Napisałem dlaczego program bez odmierzania czasu będzie tak działał. Po prostu wykonuje się dużo szybciej niż twoje "puszczenie" przycisku.
  • #26
    holgan22
    Level 10  
    Wszystko działa jak należy tylko jeszcze ten mały mankament z "zatrzymaniem" diody.Próbowałem z instrukcją:

    Code:
    loop_until_bit_is_clear(PINB,0);


    Jak i z

    Code:
    loop_until_bit_is_set(PINB,0);


    i wydaje mi się,że tymi instrukcjami nie da się tego wysterować, gdyż raz po naciśnięciu przycisku dioda zapala się a po puszczeniu przycisku od razu gaśnie albo na odwrót (po naciśnięciu przycisku gaśnie a po puszczeniu od razu zapala się).
    Założenie moje jest takie,że po naciśnięciu przycisku dioda się zapali a po ponownym naciśnięciu zgaśnie.
    Może skoro tymi instrukcjami nie daje rady to macie jakiś pomysł z instrukcją IF..ELSE ???
  • Helpful post
    #27
    szyszekpg
    Level 12  
    Proponuje tak

    Code:

      while(1)       
      {
        if(PINB & 0x01 )
       { 
        PORTC ^= _BV(5);                       
        _delay_ms(100);
       }
     }
  • #28
    holgan22
    Level 10  
    Ok poradziłem sobie.Tu wklejam kod jak by ktoś chciał:

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

    #define F_CPU 4000000UL

    int main( void )
    {
      DDRC |= _BV(5);
      DDRC |= _BV(4);
      DDRC |= _BV(3);

      DDRB &= ~_BV(0);
      PORTB |= _BV(0);

      while(1)       
      {
        PORTC &= ~_BV(5);                // wyzerowanie portu
        loop_until_bit_is_clear(PINB,0); // czekaj na nacisniecie przycisku
       _delay_ms(500);
        PORTC |= _BV(5);                 // zapal diode
        loop_until_bit_is_clear(PINB,0); // czekaj na nacisniecie przycisku
       _delay_ms(500);

     }
    }


    Tyle,że czas opóźnień (aby wyeliminować drganie styków) jest dość długi i w efekcie układ działa nie najszybciej.Dziękuję wszystkim za pomoc !!
  • #29
    _Robak_
    Level 33  
    Tylko tak na prawde opoznienie jest mniejsze niz te 500 ktore dajesz jako wartosc funkcji delay. Poczytaj plik delay.h to bedziesz wiedzial czemu;)
  • #30
    Dr.Vee
    VIP Meritorious for electroda.pl
    _Robak_ wrote:
    Tylko tak na prawde opoznienie jest mniejsze niz te 500 ktore dajesz jako wartosc funkcji delay. Poczytaj plik delay.h to bedziesz wiedzial czemu;)

    Akurat _delay_ms() zezwala na opóźnienia do 6.55 sekund, z tym że z rozdzielczością obniżoną do 1/10 ms.

    Chyba to kol. _Robak_ powinien przeczytać źródła/dokumentację ;)

    Pozdrawiam,
    Dr.Vee