[avr-gcc] Skanowanie klawiatury - jednak nie dziala

Jan 25, 2007 2 Replies

Witam,



Otó¿ mam klawiaturê i nie mogê odczytaæ (mimo ¿e powinienem) kolumny nr 3 (na sch, w prog. kolumna nr 1)... Schemat:

formatting link
,a tutaj funkcja skanowania i inicjacji: <code>



void Init(void) { // Interfejs I2C DDR(I2C_SDAPORT) |= 1 << I2C_SDA; DDR(I2C_SCLPORT) |= 1 << I2C_SCL; PORT(I2C_SDAPORT) |= 1 << I2C_SDA; PORT(I2C_SCLPORT) |= 1 << I2C_SCL; // zaraz po inicjacji wy¶lij zera na wyj¶cia PCF'a i2c_send8574(PCF8574_ADDR,0x00);



// Klawiatura PORT(SW_PORT) = 0xff; // "1" na wszystkie przyciski // Zera bêd± siê pojawiaæ na wierszach ,a czytane bêd± kolumny :) DDR(SW_PORT) |= 1 << SW_ROW1 | 1 << SW_ROW2 | 1 << SW_ROW3 | 1 << SW_ROW4 | 1 << SW_ROW5; DDR(SW_PORT) &= ~(0xe0); // pb5,pb6,pb7 jako wejscie



// Diody PORT(LED_PORT) |= 1 << LED1 | 1 << LED2 | 1<<LED3; PORT(LED_PORT) &= ~(1 << LED_R | 1 << LED_G);



DDR(LED_PORT) |= 1 << LED1 | 1 << LED2 | 1 << LED3 | 1 << LED_R | 1 << LED_G;



LED_G_ON; }



uint8_t key_scan(void) { PORT(SW_PORT) |= 0xff; uint8_t temp=16; // pocz±tek skanowania - odczyt kolumnowy // wiersz 1 PORT(SW_PORT) &= ~(1 << SW_ROW1); // ustaw "0" na wierszu if (!(PIN(SW_PORT) & 0x80)) { // kolumna 1 temp = 10; } else if (!(PIN(SW_PORT) & 0x40)) { // kolumna 2 temp = 0; } else if (!(PIN(SW_PORT) & 0x20)) { temp = 11; } PORT(SW_PORT) |= 1 << SW_ROW1; // ustaw "1" na wierszu // wiersz 2 PORT(SW_PORT) &= ~(1 << SW_ROW2); // ustaw "0" na wierszu if (!(PIN(SW_PORT) & 0x80)) { // kolumna 1 temp = 9; } else if (!(PIN(SW_PORT) & 0x40)) { // kolumna 2 temp = 8; } else if (!(PIN(SW_PORT) & 0x20)) { temp = 7; } PORT(SW_PORT) |= 1 << SW_ROW2; // ustaw "1" na wierszu // wiersz 3 PORT(SW_PORT) &= ~(1 << SW_ROW3); // ustaw "0" na wierszu if (!(PIN(SW_PORT) & 0x80)) { // kolumna 1 temp = 6; } else if (!(PIN(SW_PORT) & 0x40)) { // kolumna 2 temp = 5; } else if (!(PIN(SW_PORT) & 0x20)) { temp = 4; } PORT(SW_PORT) |= 1 << SW_ROW3; // ustaw "1" na wierszu // wiersz 4 PORT(SW_PORT) &= ~(1 << SW_ROW4); // ustaw "0" na wierszu if (!(PIN(SW_PORT) & 0x80)) { // kolumna 1 temp = 3; } else if (!(PIN(SW_PORT) & 0x40)) { // kolumna 2 temp = 2; } else if (!(PIN(SW_PORT) & 0x20)) { temp = 1; } PORT(SW_PORT) |= 1 << SW_ROW4; // ustaw "1" na wierszu // wiersz 5 PORT(SW_PORT) &= ~(1 << SW_ROW5); // ustaw "0" na wierszu if (!(PIN(SW_PORT) & 0x80)) { // kolumna 1 temp = 14; } else if (!(PIN(SW_PORT) & 0x40)) { // kolumna 2 temp = 13; } else if (!(PIN(SW_PORT) & 0x20)) { temp = 12; } PORT(SW_PORT) |= 1 << SW_ROW5; // ustaw "1" na wierszu return temp; } </code>



Je¶li zrobi³em jaki¶ g³upi b³±d to proszê o info i nie ¶miaæ siê :> gdy¿ dopiero zaczynam pisaæ w c :))



Saper/nolin11 napisał(a):

A cóż to za dziwadła czy nowa moda? Nie dało się normalnie zapisać dostępu do tego rejestru DDR i portu?

Jeżeli chodzi o skanowanie klawiatury - dodaj odstęp pomiędzy wysterowaniem wiersza a odczytem kolumny. Przy okazji możesz nieco uprościć i rozjaśnić kod używając pętli zamiast wielokrotnie konstrukcji podobnych do siebie. Dziwne też, że masz zdefiniowane maski wierszy (np. SW_ROW1) a nie masz masek kolumn (sprawdzasz wartości 0x80, 0x40 itp). Jeżeli chcesz zamienić numery wiersza i kolumny na kod klawisza (w innej kolejności niż skanowane wiersze i kolumny) to najszybsze jest użycie tablicy.

Odnośnie schematu: brakuje diod przy klawiaturze. Naciśnięcie jednoczesne 2 klawiszy w tej samej kolumnie spowoduje zwarcie 2 rzędów (w pewnej chwili na jednym wystawisz jedynkę a na drugim zero) i popłynie niezły prąd. Możesz w takiej sytuacji włączać pull-up na pinie zamiast wystawiać mocną jedynkę.

BTW: Dziwny masz pinout ISP. Jeżeli 6 pinów w rzędzie (zamiast atmelowego 2x5) to ten jest bardziej standardowy:

formatting link

Jako¶ mi tak wygodnie :) mogê napisaæ: DDRD |= 1 << I2C_SCL;

Odstêp czyli jakie¶ opó¼nienie rozumiem

A ja jestem dziwny cz³owiek :D ,a sprawdzam tak to mi widocznie wygodnie :)) siê pisa³o

Nie chce mi siê my¶leæ :DD tak siê szybciej napisa³o :)

Ja to g³ównie bêdê obs³ugiwa³ wiêc mi to nie przeszkadza :)

I tak robiê, kolumny maj± DDR=0 i PORT=1 ,a wiersze DDR=1 i PORT=0

Ten za du¿y...

Tak mi pasuje ¿eby ¶cie¿ek nie pl±taæ :)

Przerobi³em procedurkê tak ¿eby mi skanowa³a wierszami i jest teraz ok :)) ale problem mam teraz z i2c :/ ,ale na to ju¿ inny w±tek otworzê.....

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required