logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Atmega8][C] Klawiatura na multiplekserze.

herszt 01 Wrz 2008 23:43 1699 14
  • #1 5498220
    herszt
    Poziom 18  
    Witam!

    Od jakiegoś czasu tworzę sobie prostą centralkę alarmową na mikrokontrolerze ATMEGA8. Wszystko działa ładnie, ale czym byłby alarm bez klawiatury? :) Myślałem nad dodaniem klawiatury matrycowej (16 klawiszy na 8 pinach), ale postanowiłem stworzyć coś innego. Na początek stworzyłem prosty układ z 3 guzikami (widoczny na obrazku - mam nadzieję, że nie popełniłem żadnego błędu). Niestety układ ten nie działa w zamierzony sposób - zachowuje się nieco nieprzewidywalnie. Próbowałem mój program zmieniać na różne sposoby, ale efekt z reguły jest podobny - jakikolwiek guzik nacisnę to zawsze dzieje się to samo, nawet jak program napiszę tak, aby ustawiał za pomocą wejść multipleksera (A i B) tylko jeden adres to i tak jakikolwiek guzik nacisnę to reaguje jakbym nacisnął ten 'zaprogramowany'. Może to jakiś błąd w układzie, albo jakieś niedociągnięcia w programie, ale już nie wiem gdzie można szukać przyczyny. Może ktoś ma jakieś sugestie? Poniżej zamieszczam fragment obecnej wersji programu.

    SIGNAL(SIG_INTERRUPT1)
    {
    
        PORTB = PORTB|0b00000010 ; //adres na multiplekserze
    	if(bit_is_set(PINB,2))            //sprawdzanie czy guzik wcisniety - probowalem sprawdzac czy bit jest ustawiony czy nie. ale rezultat zawsze podobny
    	{
    	write_command(0x1) ;
    	write_command(0x80) ;
    	write_text("wcisnieto guzik") ;
    	}
    	LCD_LED_ON ; //zaswiecenie LCD
    	waitms(500) ;  //czekaj
    	PORTB = PORTB&0b11111100 ; //ustaw adres na 00
            czuwanie() ;
    }
    

    z góry dzięki za pomoc
    pozdrawiam
    herszt


    Poprawiłem tytuł:
    https://www.elektroda.pl/rtvforum/topic1015361.html
    Proszę umieszczać listingi w otoczeniu "code".
    [c_p]
  • Pomocny post
    #2 5498591
    szelus
    Poziom 34  
    Tak, jak narysowałeś, to raczej
    
        if (bit_is_clear(PINB,2))
    

    bo aktywnym stanem jest zero. Ale nie napisałeś jakiego multipleksera używasz. Pinów procesora też nie opisałeś, ale się domyślam, że z A to PORTB0, B to PORTB1 a wyjście mpx to PORTB2. No i że wejścia multipleksera numerują się od dołu...
  • #3 5499106
    herszt
    Poziom 18  
    Multiplekser to 74151, jak Kolega słusznie zauważył A to PORTB0, B to PORTB1 a wyjście mpx to PORTB2. Faktycznie aktywnym stanem jest zero i wtedy ten fragment kodu nie powinien dać żadnego rezultatu, ale co dziwne cokolwiek nacisnę i tak się wykona. Jak sprawdzam czy stan jest równy zero to też dość dziwnie to działa. Czy to mogą być jakieś problemy natury czasowej? Np. multiplekser nie zdąży ustawić wyjścia zanim go sprawdzę? A może jakaś propozycja kodu jaki powinienem zastosować?

    z góry dzięki za pomoc
    pozdrawiam
    herszt
  • Pomocny post
    #4 5499362
    szelus
    Poziom 34  
    herszt napisał:
    Faktycznie aktywnym stanem jest zero i wtedy ten fragment kodu nie powinien dać żadnego rezultatu, ale co dziwne cokolwiek nacisnę i tak się wykona.

    Znaczy, dlaczego nie. Jak wcisnąłeś przycisk 0, a sprawdzasz 2, to przerwanie sie wygeneruje, ale na dwójce jest stan wysoki, to warunek (pierwszy) zadziała.
    Cytat:

    Jak sprawdzam czy stan jest równy zero to też dość dziwnie to działa. Czy to mogą być jakieś problemy natury czasowej?

    Multiplekser TTL to się na pewno wyrobi ;) ale problem jest jeszcze inny. Naciśnięty styk drga i generuje ciąg zmieniających się losowo stanów. Musisz przed odczytem odczekać na ustabilizowanie się stanu kilkadziesiąt milisekund.
    Czekanie w przerwaniu to generalnie nie najlepszy pomysł, ale zależy, co poza tym robi twój program. Najpoprawniej byłoby w przerwaniu od klawiatury startować timer, a przy przerwaniu od niego czytać klawiaturę. Ale w przypadku prostych programów może to być rozwiązanie przesadnie skomplikowane.
  • #5 5499377
    kedzi1
    Poziom 18  
    Kolega jeszcze napisze na co dokładnie reaguje przerwanie. Jak widac na schemacie powinno to by opadające zbocze. Czy tak jest napisany program?
  • #6 5499474
    szelus
    Poziom 34  
    kedzi1 napisał:
    Kolega jeszcze napisze na co dokładnie reaguje przerwanie. Jak widac na schemacie powinno to by opadające zbocze.


    Narastające :!:
  • #7 5499507
    kedzi1
    Poziom 18  
    Tak zgadzam się i przepraszam za błąd.
  • #8 5500519
    herszt
    Poziom 18  
    Oczywiście przerwanie reaguje na zbocze narastające i oczywiście jak zauważył Kolega @szelus powinno być mniej-więcej tak:

    
    SIGNAL(SIG_INTERRUPT1)
    {
    
            PORTB = PORTB|0b00000010 ;
    	if(bit_is_clear(PINB,2))
    	{
    	write_command(0x1) ;
    	write_command(0x80) ;
    	write_text("wcisnieto cos") ;
    	}
    	LCD_LED_ON ;
    	waitms(500) ;
    	PORTB = PORTB&0b11111100 ;
            czuwanie() ;
    }
    


    Trochę się dziś tym pobawiłem i zauważyłem taką prawidłowość, że obojętnie jaki adres ustawie na mpx tzn. czy to będzie
    PORTB = PORTB|0b00000010 ; 

    czy
    PORTB = PORTB|0b00000001 ; 

    czy nawet
    PORTB = PORTB|0b00000000 ;

    to warunek i tak się wykona tylko przy naciśnięciu guzika 0 (no akurat w ostatnim przypadku to tak być powinno :) ) Za pomocą woltomierza sprawdziłem czy faktycznie się te stany ustawiają na wejściach adresowych i działa zgodnie z zamierzeniami. Także nie wiem gdzie mógłbym szukać jeszcze przyczyn. Może to faktycznie nieprzewidziane zmiany stanów na guzikach zanim jeden konkretny się ustabilizuje?

    z góry dzięki
    pozdrawiam
    herszt
  • #9 5504370
    herszt
    Poziom 18  
    Dodam, że raczej wykluczam uszkodzenie multipleksera ;) Czy ktoś ma jakiś pomysł jak mógłbym rozwiązać ten mój problem? Bo jak napisał Kolega @szelus mógłbym czekać na ustabilizowanie kilkadziesiąt ms, w sumie to nawet nie będzie miało większego wpływu na działanie układu, ale czy można zastosować jeszcze jakąś alternatywną metodę?

    z góry dzięki
    pozdrawiam
    herszt
  • Pomocny post
    #10 5504700
    szelus
    Poziom 34  
    Opóźnienie to najprostsze rozwiązanie. Można tez dodać filtr sprzętowy, np. filtry RC plus bramki Schmitta, ale nie praktykowałem tego, więc nie podpowiem konkretnie.
  • #11 5504925
    herszt
    Poziom 18  
    Spróbuję pobawić się opóźnieniem i zobaczę co z tego wyjdzie :)

    dzięki za wszelkie uwagi
    pozdrawiam
    herszt
  • Pomocny post
    #12 5504958
    kulmar
    Poziom 31  
    herszt napisał:
    Trochę się dziś tym pobawiłem i zauważyłem taką prawidłowość, że obojętnie jaki adres ustawie na mpx tzn. czy to będzie
    PORTB = PORTB|0b00000010 ; 

    czy
    PORTB = PORTB|0b00000001 ; 

    czy nawet
    PORTB = PORTB|0b00000000 ;



    A dlaczego ustawiasz port wyjsciowy w taki sposób ? Operator | (suma bitowa) nie wymusi stanu zera logicznego na bicie, na którym poprzednio był stan 1. Rozumiem, że chciałbyś zmieniać na porcie tylko te bity, którymi jesteś zainteresowany, ale dopóki nie masz pewności, że układ działa od strony połączeń, to stosuj pewne metody:
    PORTB = 0;
    PORTB = 1;
    PORTB = 2;

    Pozdrawiam
    Mariusz
  • #13 5505021
    herszt
    Poziom 18  
    Oczywiście, że sam operator | nie zapewni mi pożądanego efektu. Ale zawsze zanim zacznę ustawiać te dwa ostatnie bity to wyzerowuję je przez:
    PORTB = PORTB&0b11111100 ;

    Nie wiem czy robię to elegancko i profesjonalnie, ale działa ;)

    pozdrawiam
    herszt
  • Pomocny post
    #14 5505090
    kulmar
    Poziom 31  
    Aby mieć pewność, że problem nie leży w zależnościach czasowych pomiędzy wysłaniem na port adresu do multipleksera a odczytem stanu bitu, wstaw pomiędzy ustawianie portu i warunek IF opóźnienie np. 1ms:

    PORTB = PORTB | 0b00000001;
    waitms(1);
    if (

    Pozdrawiam
    Mariusz

    Dodano po 9 [minuty]:

    Dodano: 74151 ma wyjścia 2 wyjscia komplementarne, więc dobrze by było opisać na schemacie numery nóżek, żebysmy się tu nie bawili w zgaduj-zgadulę. I ma wejście ENABLE, które na tym schemacie w ogóle nie jest uwzględnione.

    Pozdrawiam
    Mariusz
  • #15 5512544
    herszt
    Poziom 18  
    Faktycznie nie opisałem nóżek, za co przepraszam - na następny raz będę pamiętał. W każdym razie pomogło dodanie opóźnienia po każdej zmianie adresu przed odczytem wartości z multipleksera. Teraz działa całkiem nieźle i zabieram się za konstruowanie nieco bardziej rozbudowanej klawiatury :)

    dzięki za wszystkie porady i sugestie
    pozdrawiam
    herszt
REKLAMA