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.

Układ oparty na Atmega8 - sterownik silnika działający po wpisaniu PIN

ŻakSziRak 19 Lip 2009 17:53 1221 4
  • #1 19 Lip 2009 17:53
    ŻakSziRak
    Poziom 9  

    Witam. Próbuję stworzyć układ oparty na uC Atmega8 i klawiaturze. Ma to być coś w rodzaju sterownika, który po wpisaniu prawidłowego PINU uruchamia silnik (oparty będzie pewnie na mostku, ale to inna sprawa). Żeby sprawdzić, czy takie coś ma prawo działać zbudowałem sobie szybko układ: dioda podłączona do PC5, przyciski podłączone do PB0, PB1 i PB2 (po wciśnięciu zwierają te porty do masy). Kod:


    Code:

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

    #define LED1_ON_ENABLE DDRC |= (1<<5)
    #define LED1_ON PORTC |= (1<<5)
    #define LED1_OFF PORTC &=~ (1<<5)


    main()
    {

    DDRB &=~ (1<<0);
    DDRB &=~ (1<<1);
    DDRB &=~ (1<<2);     //PB0, PB1 oraz PB2 ustawione
    PORTB |= (1<<0);     //jako wejście z
    PORTB |= (1<<1);     //podciągnięciem do VCC
    PORTB |= (1<<2);   

    LED1_ON_ENABLE;   //ustawienie pinu z diodą na wyjście



    while(1)

    {

          if(!(PINB & (1<<0)))              //jesli przyciśnięty został 1. przycisk
       {
          _delay_ms(80);
           PORTB &=~ (1<<0);                    //to po zwolnieniu przycisku zapamiętaj ten pin na stanie niskim
           
          
       
                   if(!(PINB & (1<<1)))              //przycisk 2. analogicznie jak 1.
                {
                   _delay_ms(80);
                    PORTB &=~ (1<<1);
       


                               if(!(PINB & (1<<2)))              //przycisk 3. analogicznie jak 1. i 2.
                            {
                                  
                                _delay_ms(80);




                               LED1_ON;              //zapal diode
                               _delay_ms(3000);      //odczekaj  3 sekundy
                                      
                               PORTB |= (1<<0);   //wróć porty
                               PORTB |= (1<<1);   //do ustawień
                               PORTB |= (1<<2);   //początkowych
                                        
                                      
                                      
                            }
                                  
                               else             
                                  
                                           
                            {
                               _delay_ms(80);
                               LED1_OFF;              //dioda zgaszona
                            }
                      
                       
                }
                      
                      
                   else             
                {
                   _delay_ms(80);
                   LED1_OFF;              //dioda zgaszona
                }
                      
                       
           
           
       }
       
          else             
          
       {
           _delay_ms(80);
            LED1_OFF;              //dioda zgaszona
       }
       

    }

    }




    Po wciśnięciu przycisków w odpowiedniej kolejności - PB0-> PB1-> PB2 program wpada do kolejnych " if'ów ". Po każdym wciśnięciu przycisku program ma zapamiętać pin na stanie niskim, bo po puszczeniu przycisku wróciłby do stanu wysokiego i przy kolejnym przejściu programu warunek if nie byłby już spełniony. Rozumując w ten sposób, po wciśnięciu przycisków w odpowiedniej kolejności zapala się dioda na 3 sekundy, po czym porty ustawiane są z powrotem na wejście z podciągnięciem do jedynki i zabawa zaczyna się od nowa.
    Problem polega na tym, że układ raz reaguje, raz nie. Przyciskam przyciski w zadanej kolejności i raz reaguje odrazu, raz za jakiś czas, a raz w ogóle. Na początku do głowy przyszła mi sprawa drgań styków, ale w jaki sposób one mogą burzyć jego pracę, skoro ich efektem jest jakby interpretacja przez program załóżmy kilkudziesięciu przyciśnięć przycisku. Skoro tak, to u mnie nie powinno to przeszkadzać, bo zależy mi tylko na tym, żeby nie wypaść z danego "if'a" jeśli już program się w nim znajdzie po odpowiednim wpisaniu przycisku.

    Jeśli ktoś ma jakiś pomysł to będę bardzo wdzięczny. A jeśli podobny temat był już gdzieś poruszany to z góry przepraszam.

    0 4
  • #2 19 Lip 2009 18:18
    Freddie Chopin
    Specjalista - Mikrokontrolery

    twój program wymaga abyś przyciski wcisnął w odpowiedniej kolejności ORAZ w odpowiednim czasie (natychmiast po zakończeniu delaya z poprzedniego razu). To nie ma prawa działać poprawnie.

    Pozatym jest napisane bezsensownie - ta seria ustawień portów w 3 liniach? Nie da się w jednej?

    DDRB &=~ (1<<0);
    DDRB &=~ (1<<1);
    DDRB &=~ (1<<2);

    jedna linia

    PORTB |= (1<<0);
    PORTB |= (1<<1);
    PORTB |= (1<<2);

    druga linia

    Pozatym "zapamiętanie" stanu przycisku poprzez wyłączenie pullupa na porcie wydaje się mocno naciąganym pomysłem. Porty to nie są rejestry do zapamiętywania czegokolwiek.

    4\/3!!

    0
  • #3 19 Lip 2009 20:33
    ŻakSziRak
    Poziom 9  

    Freddie Chopin napisał:
    napisane bezsensownie - ta seria ustawień portów w 3 liniach? Nie da się w jednej?

    Zgadzam się, do poprawienia (program pisany na szybko tylko do sprawdzenia ogólnego pomysłu), ale to nie jest problem. Nie rozumiem tego:

    Freddie Chopin napisał:
    twój program wymaga abyś przyciski wcisnął w odpowiedniej kolejności ORAZ w odpowiednim czasie (natychmiast po zakończeniu delaya z poprzedniego razu). To nie ma prawa działać poprawnie.

    Idąc przebiegiem programu - gdy przycisk pierwszy zostanie wciśnięty i zwolniony, program wykonuje intstrukcje z pierwszego if'a. Teraz zanim użytkownik wciśnie drugi przycisk, program oczywiście "przeleci" reszte nie wchodząc do drugiego if'a. Zaczyna lecieć od nowa w pętli while. Zowu wpada do 1. if'a (po to zrobiłem zapamiętanie stanu niskiego z poprzedniego "wciśnięcia") i jeśli drugi przycisk dalej nie jest wciśnięty, to sytuacja się powtarza, a jeśli już został wciśnięty, to program wpada do drugiego if'a i dalej wszystko odbywa się analogicznie..

    Jeśli powyższe rozumowanie nie jest poprawne, to jak możesz - wyprowadź mnie z błędu. A jeśli to kompletnie jest nie trafiony pomysł to może jakieś wskazówki, naprowadzenia jakby to inaczej zrobić ?
    Pozdrawiam

    0
  • #4 20 Lip 2009 09:44
    Freddie Chopin
    Specjalista - Mikrokontrolery

    Nie jest poprawne.

    To że wyłączysz podciąganie (PORTx.y = 0) wcale nie oznacza, że odpowiedni pin wejściowy (PINx.y) będzie w stanie niskim. Wyłączając podciąganie przełączasz pin w stan wysokiej impedancji - pin może mieć wtedy stan losowy.

    Do zapamiętywania poprzednio wciśniętych przycisków musisz użyć ZMIENNEJ.

    Do tego sama idea też nie jest słuszna. Nawet gdyby to o czym piszemy działało poprawnie, to użytkownik może wcisnąć na przykład przycisk pierwszy, potem klikać 10x w trzeci i dopiero w drugi, teraz 10x w pierwszy i dopiero potem w trzeci - taka kombinacja też zostałaby zaakceptowana - wymagasz tylko aby przyciski były naciśnięte po sobie, ale nie ZARAZ po sobie - innymi słowy ich naciskanie może być rozdzielone czymkolwiek.

    4\/3!!

    0
  • #5 20 Lip 2009 12:24
    ŻakSziRak
    Poziom 9  

    Freddie Chopin napisał:
    Do tego sama idea też nie jest słuszna. Nawet gdyby to o czym piszemy działało poprawnie, to użytkownik może wcisnąć na przykład przycisk pierwszy, potem klikać 10x w trzeci i dopiero w drugi, teraz 10x w pierwszy i dopiero potem w trzeci - taka kombinacja też zostałaby zaakceptowana - wymagasz tylko aby przyciski były naciśnięte po sobie, ale nie ZARAZ po sobie - innymi słowy ich naciskanie może być rozdzielone czymkolwiek

    Ostateczny projekt miał wyglądać tak, że użytkownik wprowadza - niech już zostanie - 3 liczby i zatwierdza je jakimś przyciskiem (w stylu ENTER). W każdym if'ie byłby warunek 'czy został naciśnięty przycisk potwierdzający PIN'. Jeśli miałoby to miejsce w ostatnim if'ie to OK, jeśli we wcześniejszym to znaczyłoby, że PIN został wprowadzony niepoprawny lub niecałkowity. Co częściowo wyeliminowałoby problem, o którym napisałeś, ale też nie do końca widzę..

    Freddie Chopin napisał:
    To że wyłączysz podciąganie (PORTx.y = 0) wcale nie oznacza, że odpowiedni pin wejściowy (PINx.y) będzie w stanie niskim. Wyłączając podciąganie przełączasz pin w stan wysokiej impedancji - pin może mieć wtedy stan losowy.

    No to tego do końca nie wiedziałem, faktycznie będę kombinował coś z jakimś licznikiem do zapamiętania kolejnych wciśnięć. Jak wymyślę coś nowego w wolnym czasie to jeszcze dorzucę. A teraz dzięki za wskazówki.

    0