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

AVRGCC i obsługa klawiatury

19 Mar 2005 13:34 1772 9
  • Poziom 27  
    Witam
    już od jakiegoś czasu próbuję zrobić na ATmega8 wykryła mi naciśnięcie guzika i nic. próbowałem już według wielu instrukcji, z podciąganiem, bez i nic.
    teraz próbuję na kodzie prtzepisanym z książki "mikrokontrolery AVR w praktyce", z rezystorem podciągającym 1kΩ. jest kompletny brak reakcji w przypadku zaciśnięcia lub rozwarcia zworki. może ktoś wie co robię nie tak. oto fragment kodu:

    pod PORTC podpięte są ledy.

    int main (void)
    {
    DDRC=0xff;
    DDRB=0x60;
    PORTB=0xff;
    for (;;)
    {
    PORTC=38;
    czekaj(3000); //czekaj 3 sekundy

    if (bit_is_clear(PINB, PB1))
    {
    PORTC=3;
    czekaj(5000);
    }
    if (bit_is_clear(PINB, PB2))
    {
    PORTC=12;
    czekaj(5000);
    }

    }

    return (0);
    }
    Darmowe szkolenie: Ethernet w przemyśle dziś i jutro. Zarejestruj się za darmo.
  • VIP Zasłużony dla elektroda
    Hmm.... za mało danych, jaki zegar ? Czy wybór zegara w fusebits jest prawidłowy ? Jakiś nawet odręczny schemacik ? Po co zewnętrzne podciąganie ?
    Pozdr. LightI
  • Poziom 27  
    raczej zegar nie ma tutaj żadnego znaczenia, pozatym nic przy nim nie majstrowałem. a zewnętrzne podciąganie jest żeby nie było zakłóceń, bop bez niego to jakieś szopki są.
  • VIP Zasłużony dla elektroda
    Uparciuch z ciebie, a takim ciężko pomóc... :P
    W kodzie definiuje się przecież predkość zegara i musi się ona zgadzać z rzeczywistością, bo jak masz w programie ustawione 16MHz a układ lata na wewnętrznym 1 MHz to twoje upragnione opóźnienie 5 s zamienia się na rzeczywiste 1min i 20 s... Pewnie w międzyczasie znudzony wyłączasz zasilanie układu. Czy nadal uważasz, że zegar nie ma znaczenia ?
    Pytanie dodatkowe : Czy żadna z LED-ek nie świeci ?
    Pozdr, LightI
  • Poziom 24  
    Hej,
    Czy podłączyłeś zasilanie portu C?
    Pozdrowienia
  • VIP Zasłużony dla elektroda
    Tak więc oba pinu GND też musża być podłączone do masy, jak i również Vcc i AVcc do0 +zasilania (najczęściej 5 V ;) )
    Pozdr. LightI
  • Poziom 27  
    w programie nie definiuje prędkości zegara jest on fabrycznie ustawiony na 1 MHz i opóźnienie działa dobrze bo sprawdzałem wpisując w pętli:

    PORTC=38;
    czekaj(3000);
    PORTC=7;
    czekaj(3000);

    AVcc i druga GND to są wejścia dla pracy analogowej i nie powinno się ich łączyć, ale spróbuje. może pomoże
  • VIP Zasłużony dla elektroda
    Pomoże na pewno... ;)
    Nota Aplikacyjna napisał:
    AVCC is the supply voltage pin for the A/D Converter, Port C (3..0), and ADC (7..6). It
    should be externally connected to VCC, even if the ADC is not used. If the ADC is used,
    it should be connected to VCC through a low-pass filter. Note that Port C (5..4) use digital
    supply voltage, VCC.
    To jest z "Pin Descriptions/AVCC" Drugi pin GND nie ma innego oznaczenia niż pierwszy, więc dobrze jest go podłączyć zgodnie z przeznaczeniem...
    Czy zegarek jest fabrycznie ustawiany w programie ? Może to być zaszyte gdzieś jako wartość domyślna (XTAL ?), ale kompilator nie jest od zgadywania co i jak jest do układu przyłączone i ustawione w rzeczywistości. Na własnych omyłkach mogę zaryzykować stwierdzenie, że niedbalstwo w programowaniu predko owocuje "nadgodzinami" w poszukiwaniu błędów, które po odnalezieniu mogą nas skłonić do nadania energii kinetycznej młotkowi o masie 5000 g, i wektorze ruchu w kierunku głowy... ;)
    Pozdr. LightI
  • Poziom 13  
    Jeśli do PB5 masz podłączony przycisk to wyprowadzenie to też powinno być ustawione jako wejście, czyli
    Code:
     DDRB=0x40;
    . Ale to jest tylko taka drobna poprawka kosmetyczna, szczegół który ma tu chyba najmniejsze znaczenia.
    Nie wiem jak skonstruowana jest funkcja bit_is_clear, bo może w niej jest problem. Dlatego ja bym proponował może więcej pisania, ale u mnie się przynajmniej sprawdzało. Druga rzecz, że jeśli są to przyciski to warto byłoby zabezpieczyć się przed drganiem styków. Fragment tego programu odnosi się do przypadku z rezystorami podciągającymi do "+" zasilania (najlepiej wewnętrznie w mikrokontrolerze)
    Code:

              a=0;
              prevkey=0;
    KBD_WAIT:   while((a=(PINB&0x3e))==0x3e);      //czekaj dopoki jakis przycisk nie nacisniety
             delay_ms(10);                     //opoznienie 10ms
             if(a!=0x3e)                     //jesli przycisk nadal nacisniety
             {
              prevkey=a;                        //poprzednio nacisniety=teraz nacisniety
              delay_ms(10);                     //opoznienie 10ms
              a=(PINB&0x3e);                  //ponowne skanowanie ktory przycisk nacisniety
              if(a==prevkey)                  //jesli teraz nacisniety ten sam co poprzednio
              {
               if(a==0x3c) key=1;               //zwrocenie w globalnej zmiennej key numeru przycisku
               if(a==0x3a) key=2;
               if(a==0x36) key=3;
               if(a==0x2e) key=4;
               if(a==0x1e) key=4;
              }
              else goto KBD_WAIT;               //jesli zaklocenie czekaj na nacisniecie przycisku
             }
          else goto KBD_WAIT;               //jesli zakocenie czekaj na nacisniecie przycisku
          while((PINB&0x3e)!=0x3e);               //czekaj az przycisk zostanie zwolniony


    Z tego fragmentu najlepiej zrobić funkcję wywoływaną z funkcji main i w zależności od tego jaką wartość ma zmienna key podjąć odpowiednie działanie
  • VIP Zasłużony dla elektroda
    1. Eliminacja drgań zestyków podana przez kolegę Pandor-a jest tylko pewna ideą, bo w praktyce tylko dzieli częstotliwość drgań, jakie moga się przytrafić przy bardzo intensywnie używanych zestykach, co jest istotne jeżeli program ma rozróżniać ilość naciśnięć, bo w innym wypadku nie ma potrzeby zawracać sobie tym problemem głowy. Proponowałbym w pętli głównej mały licznik, po którego wyzerowaniu dopiero kod klawisza można traktować jako kolejne jego wciśnięcie. Licznik jest resetowany (ustawiana wartość opóźnienia {ja preferuję 100 - 300 ms} będąca wielokrotnością czasu pomiędzi przerwaniami procesorka, o których dalej), jeżeli klawisz jest wciśnięty, a jeżeli uprzednio miał wartość zero, uznajemy wciśnięcie klawisza za prawidłowe. Zmniejszaniem wartości licznika zajmuje się odpowiednie przerwanie występujące w regularnych odstępach czasu np. od Timer0 Overflow. Osobiście mam ogromną awersję do procedur typu wait_ms() itp. Jest to ogromne marnotrawienie mocy obliczeniowej procesorka, które się mści w bardziej złożonym projekcie. Najlepiej używać zmiennych, użytych jako swoiste liczniki, zmieniające swoją wartość w przerwaniu wywoływanym w równym odstępie czasu. Na chłopski rozum : Licznik różny od 0 ? No to sio do pętli głównej robić coś innego, jak to zrobisz, to znowu sprawdzasz licznik itd. Polecam uwadze takiego sobie pdf-ka...
    2. W projekcie ~sojer-a widzę pewne niuanse wskazujące na oparcie się na wskazówkach z tej strony. Czy dobrze wydedukowałem ? ;)
    Pozdr. LightI