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

Matryca 4x4, problem ze stanami logicznymi atmega32

kli 29 Lip 2010 07:10 2158 18
REKLAMA
  • #1 8342493
    kli
    Poziom 13  
    Witam,

    Może problem wyjaśnie posługując się fragmentem schematu.


    Matryca 4x4, problem ze stanami logicznymi atmega32

    Steruje matrycą przycisków w ten sposób, że na linie W1,W2,W3,W4 wystawiam "0", natomiast linie K1,K2,K3,K4 są wejściami z wewnętrznymi pull-upami. W momencie naciśnięcia przycisku pojawia się stan niski na SW_INT, co wywołuje przerwanie. Dalej wiadomo.

    Problem jest taki, że nie działa to na jednej linii, a konkretnie W4. Jest na niej stan niski i w momencie naciśnięcia SW13, SW14, SW15 lub SW16 na linii SW_INT nie pojawia się "0", tylko utrzymuje się jedynka z wewnetrznego podciagniecia. Sprawdzalem ze na nozkach przycisku sa te stany co trzeba (na jednej 1, na drugiej 0) i przycisk poprawnie zwiera, jednak jest tak jakby jedynka byla "mocniejsza" niz "0" z linii W4.

    Jakieś pomysły?
  • REKLAMA
  • Pomocny post
    #2 8342568
    rpal
    Poziom 27  
    pomysł jest taki abyś sprawdzaniem klawiatury zajął się któryś z timerów i jego przerwanie które zajmuje się tym że cyklicznie na linie w1-w4 wystawia po kolei zero i jednoczenie sprawdza stan k1-k4. jeśli na którejś z tych linii wystąpi zero to ustawia flagę naciśniecia klawisza i zapisuje bufor klawiatury kodem wcisnietego klawisza. Ten kod składa się z 4 bitów tego co wystawiłeś na w1-w2 i 4 bitów tego co odczytałeś z k1-k4. Czy diody nie wlutowałeś odwrotnie ?
  • Pomocny post
    #3 8342702
    Konto nie istnieje
    Konto nie istnieje  
  • Pomocny post
    #4 8342715
    rpal
    Poziom 27  
    Jak chcesz koniecznie mieć te zewnetrzne przerwanie do dodaj 7420 zamiast tych diod i będziesz miał przyzwoity sygnał przerwania.
  • Pomocny post
    #5 8342849
    tadzik85
    Poziom 38  
    Nie działa ci jeden rząd? pewnie któryś z boku. za szybko zapewne odczytujesz stan portu po zmienia kolumny.
  • REKLAMA
  • #6 8345785
    kli
    Poziom 13  
    Cytat:
    Czy diody nie wlutowałeś odwrotnie ?

    Diody sa dobrze wlutowane
    Może dalsza część programu działająca na całym porcie przypadkiem zmienia tobie konfiguracje tego pinu na wejście?

    Sprawdzilem, konfiguracja pinu sie nie zmienia
    Jak chcesz koniecznie mieć te zewnetrzne przerwanie do dodaj 7420 zamiast tych diod i będziesz miał przyzwoity sygnał przerwania

    Takie cos nie wchodzi w gre z powodu ograniczonego miejsca na plytce. Nie rozumiem czemu sygnal przerwania z diody mialby byc "nieprzyzwoity"?
    Nie działa ci jeden rząd? pewnie któryś z boku. za szybko zapewne odczytujesz stan portu po zmienia kolumny.

    Chodzi o to, ze nacisniecie przycisku z tego rzedu nie powoduje zerowania linii K1,K2,K3 lub K4. Na W4 faktycznie mozna odczytac 0V, na SW_INT- 5V, natomiast nacisniecie przycisku nie wywoluje obnizenia napiecia sygnalu 5V do 0V tak jak na innych wierszach...

    Dodam, że W4 jest podpieta do PA6 (ADC6)
  • Pomocny post
    #7 8345808
    tadzik85
    Poziom 38  
    Wygląda na to, że miałem racje.

    Jeśli robisz coś w tym stylu
    
    portB=0b11111110;
    if (portb = 0b01111110)
    {
    }

    To przed ifem musi być nop, procesor nie zdarzy zmienić stany wyjściowego przed odczytem.
  • Pomocny post
    #8 8345949
    Jaca
    Poziom 31  
    A podłączyłeś AVCC do VCC ? Jeśli używasz ADC to zrób to przez filtr. W przeciwnym wypadku podłącz bezpośrednio do VCC.
  • #9 8346234
    kli
    Poziom 13  
    Cytat:
    A podłączyłeś AVCC do VCC ? Jeśli używasz ADC to zrób to przez filtr. W przeciwnym wypadku podłącz bezpośrednio do VCC


    AVCC podłączone do VCC przez dławik DL1206-10 (10uH).

    przed ifem musi być nop, procesor nie zdarzy zmienić stany wyjściowego przed odczytem


    Fizycznie naciśnięcie przycisku z tego wiersza nie zeruje linii co sprawdzam miernikiem. Takie opóźnienia o jakich mówisz już dawałem, nawet 200ms i nie pomagały. Te linie nigdy nie chcą zejśc do "0"!


    
    ISR(INT1_vect)
    {
    
    	W1_PORT |=  W1;
    	W2_PORT &=  ~W2;
    	W3_PORT |=  W3;
    	W4_PORT |=  W4;
    
    	if (  (K1_PIN & K1) == 0 )
    	{ 
    	    UART_Transmit_text("SW5");
    	}
    	else if (  (K2_PIN & K2) == 0 ) 
    	{
    	    UART_Transmit_text("SW6");
    	}
    	else if (  (K3_PIN & K3) == 0 ) 
    	{
    	    UART_Transmit_text("SW7");
    	}
    	else if (  (K4_PIN & K4) == 0 ) 
    	{
    	    UART_Transmit_text("SW8");
    	}
    
    	W1_PORT &=  ~W1;
    	W2_PORT |=   W2;
    	W3_PORT |=   W3;
    	W4_PORT |=   W4;
    
    	if (  (K1_PIN & K1) == 0 ) 
    	{
    	    UART_Transmit_text("SW1\r\n");
    	}
    	else if (  (K2_PIN & K2) == 0 ) 
    	{
    	    UART_Transmit_text("SW2\r\n");
    	}
    	else if (  (K3_PIN & K3) == 0 )
    	{ 
    	    UART_Transmit_text("SW3\r\n");
    	}
    	else if (  (K4_PIN & K4) == 0 ) 
    	{
    	    UART_Transmit_text("SW4");
    	}
    
    	
    	W1_PORT |=   W1;
    	W2_PORT |=   W2;
    	W3_PORT &=  ~W3;
    	W4_PORT |=   W4;
    
    	if 		(  (K1_PIN & K1) == 0 ) 
    	{
    	    UART_Transmit_text("SW9\r\n");
    	}
    	else if (  (K2_PIN & K2) == 0 ) UART_Transmit_text("SW10\r\n");
    	else if (  (K3_PIN & K3) == 0 ) UART_Transmit_text("SW11\r\n");
    	else if (  (K4_PIN & K4) == 0 ) UART_Transmit_text("SW12\r\n");
    
    
    	W1_PORT |=   W1;
    	W2_PORT |=   W2;
    	W3_PORT |=   W3;
    	W4_PORT &=  ~W4;
    
    	if 		(  (K1_PIN & K1) == 0 ) UART_Transmit_text("SW13\r\n");
    	else if (  (K2_PIN & K2) == 0 ) UART_Transmit_text("SW14\r\n");
    	else if (  (K3_PIN & K3) == 0 ) UART_Transmit_text("SW15\r\n");
    	else if (  (K4_PIN & K4) == 0 ) UART_Transmit_text("SW16\r\n");
    
    	
    	W1_PORT &=  ~W1;
    	W2_PORT &=  ~W2;
    	W3_PORT &=  ~W3;
    	W4_PORT &=  ~W4;
    
    
    	GIMSK &= ~(1<<INT1);
    	sw_interrupt = 1;
    
    }
  • Pomocny post
    #10 8346356
    Jaca
    Poziom 31  
    Podaj typ obudowy procka oraz nr pinu (z płytki, nie ze schematu), do którego podłączyłeś W4. Mierzysz napięcie na końcówce procka czy przy klawiaturze ?
  • Pomocny post
    #11 8346764
    rpal
    Poziom 27  
    tadzik85 napisał:
    Wygląda na to, że miałem racje.

    Jeśli robisz coś w tym stylu
    
    portB=0b11111110;
    if (portb = 0b01111110)
    {
    }

    To przed ifem musi być nop, procesor nie zdarzy zmienić stany wyjściowego przed odczytem.


    to raczej tak ma wyglądać :
    
    portB=0b11111110;
    if (portb == 0b01111110)
    {
    }

    a to co piszesz o NOP to jakaś herezja bo co ma zmiana stanu do porónywania zawartości zmiennej ze stałą ?
    przyzwoity sygnał to taki co ma przebieg prostokątny a ten który otrzymujesz ma przebieg piłokształtny, sprawdź oscyloskopem jeśli masz taką możliwość.
  • Pomocny post
    #12 8346838
    Andrzej__S
    Poziom 28  
    Kod dla ostatniego wiersza wygląda następująco:
    kli napisał:

    
    ....
       W1_PORT |=   W1; 
       W2_PORT |=   W2; 
       W3_PORT |=   W3; 
       W4_PORT &=  ~W4; 
    
       if       (  (K1_PIN & K1) == 0 ) UART_Transmit_text("SW13\r\n"); 
       else if (  (K2_PIN & K2) == 0 ) UART_Transmit_text("SW14\r\n"); 
       else if (  (K3_PIN & K3) == 0 ) UART_Transmit_text("SW15\r\n"); 
       else if (  (K4_PIN & K4) == 0 ) UART_Transmit_text("SW16\r\n");
    ....
    



    Proponuję spróbować zmienić kolejność, np.:
    
    ... 
       W4_PORT &=  ~W4;
       W1_PORT |=   W1; 
       W2_PORT |=   W2; 
       W3_PORT |=   W3;
    ...
    

    skompilować i spróbować ponownie.

    EDIT:
    Sorry, nie doczytałem dokładnie:
    kli napisał:

    tadzik85 napisał:

    przed ifem musi być nop, procesor nie zdarzy zmienić stany wyjściowego przed odczytem


    Fizycznie naciśnięcie przycisku z tego wiersza nie zeruje linii co sprawdzam miernikiem. Takie opóźnienia o jakich mówisz już dawałem, nawet 200ms i nie pomagały. Te linie nigdy nie chcą zejśc do "0"!
  • REKLAMA
  • Pomocny post
    #13 8346994
    rpal
    Poziom 27  
    masz totalnie pochrzanioną obsługę przerwania pomijam już ze jest zbyt obszerny ale wpisanie tam transmisji rs232 to już piramidalna pomyłka i to powoduje że nigdy tobie to nie zadziała. Poza tym kompletnie nie widzę powodu aby wyprowadzać sygnał na przerwanie INT0 moze tylko po to aby łatwiej mozna było sprawdzać przytrzymanie klawisza ale innego powodu nie widzę. Musisz uzyć przerwania od timera aby cyklicznie przesuwać zero na połówce portu (wyjścia) jednocześnie sprawdzając stan wejść jeśli złożysz w jeden bajt jedno i drugie otrzymasz kod klawisza i to tyle.
  • Pomocny post
    #14 8347124
    tadzik85
    Poziom 38  
    rpal napisał:

    a to co piszesz o NOP to jakaś herezja bo co ma zmiana stanu do porónywania zawartości zmiennej ze stałą ?


    Dużo, i zalecam lekturę datasheta temat wałkowany wielokrotnie.
  • #15 8347452
    kli
    Poziom 13  
    Cytat:
    Podaj typ obudowy procka oraz nr pinu (z płytki, nie ze schematu), do którego podłączyłeś W4


    ATMEGA32A TQFP, nóżka 31 (PA6)

    Cytat:
    Jeśli robisz coś w tym stylu
    Kod:

    portB=0b11111110;
    if (portb = 0b01111110)
    {
    }


    Jak już coś to sprawdza się raczej PINB a nie PORTB.

    Cytat:
    Proponuję spróbować zmienić kolejność, np.:
    Kod:

    ...
    W4_PORT &= ~W4;
    W1_PORT |= W1;
    W2_PORT |= W2;
    W3_PORT |= W3;
    ...

    skompilować i spróbować ponownie.


    Robilem, zawsze "niedomaga" W4, niezaleznie kiedy jest przelaczana.

    Cytat:
    masz totalnie pochrzanioną obsługę przerwania pomijam już ze jest zbyt obszerny


    Nie uwazam ze jest pochrzaniona, sens jest taki ze procesor przez wiekszosc czasu jest w stanie uspienia i nacisniecie przycisku go wybudza przez zmiane INT0. Powiedzmy ze sposobow obslugi przyciskow jest duzo, ja potrzebuje taki. Ilosc kodu nie gra roli, to nie ma byc tez eleganckie, tylko ma dzialac.

    Cytat:
    Dużo, i zalecam lekturę datasheta temat wałkowany wielokrotnie


    Ok, ale jak juz pisalem sprawdzalem i nie o to chodzi

    Cytat:
    Mierzysz napięcie na końcówce procka czy przy klawiaturze ?


    I tu i tu jest to samo.
  • REKLAMA
  • Pomocny post
    #16 8348859
    Andrzej__S
    Poziom 28  
    kli napisał:

    Chodzi o to, ze nacisniecie przycisku z tego rzedu nie powoduje zerowania linii K1,K2,K3 lub K4. Na W4 faktycznie mozna odczytac 0V, na SW_INT- 5V, natomiast nacisniecie przycisku nie wywoluje obnizenia napiecia sygnalu 5V do 0V tak jak na innych wierszach...

    Zakładam, że klawiaturę sprawdziłeś omomierzem, czy przyciski zwierają W4 z kolumnami?

    kli napisał:

    Dodam, że W4 jest podpieta do PA6 (ADC6)

    No to odepnij od PA6 i podłącz bezpośrednio do masy, w przerwaniu ujmij w komentarz wszystkie wiersze oprócz W4 i sprawdź ponownie zachowanie programu oraz pomierz napięcia. Będziesz wiedział, czy to wina portu.
  • #17 8355933
    kli
    Poziom 13  
    Po części rozwiązałem problem. Okazało się, że scalak jest słabo przylutowany.
    Teraz natomiast jest tak, że jak się przyciska SW13, to program wykrywa naciśnięcie SW5 i SW13.
    Jestem w kropce, gdyż dzieje sie tak tylko dla tego 1 przycisku i problem wystepuje na wszystkich egzemplarzach protopytu.
  • Pomocny post
    #18 8356237
    Andrzej__S
    Poziom 28  
    A próbowałeś dać jakieś opóźnienie tutaj:
    
    ISR(INT1_vect) 
    { 
    
       W1_PORT |=  W1; 
       W2_PORT &=  ~W2; 
       W3_PORT |=  W3; 
       W4_PORT |=  W4; 
    // w tym miejscu opóźnienie
       if (  (K1_PIN & K1) == 0 )
       ...
    }
    

    Napisałeś, że korzystasz z wewnętrznych pull-up. Mają one dosyć sporą rezystancję (min. 20k, o ile dobrze pamiętam), więc trochę może potrwać, zanim na W4 pojawi się stan wysoki, bo w momencie rozpoczęcia procedury W4=0. To by się nawet zgadzało, bo procedurę rozpoczynasz od sprawdzenia wiersza W2 i zaraz za W4_PORT |= W4; masz testowanie K1 czyli właśnie przycisku S5. Dla innych przycisków może być OK, bo pojemność już zdąży się przeładować.
  • #19 8356249
    kli
    Poziom 13  
    Super wyjaśnienie. O to chodziło:)

    Wcześniej przed niedolutowanym prockiem próbowałem z opóźnieniami ale pozniej zapomnialem.

    Dzieki wszystkim za pomoc.
    Pozdrowienia.
REKLAMA