Špatná detekce stisku tlačítek na Maticové Klávesnici 8x6

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Odpovědět
Zpráva
Autor
Uživatelský avatar
HafisCZ
Příspěvky: 23
Registrován: 17 led 2014, 00:00

Špatná detekce stisku tlačítek na Maticové Klávesnici 8x6

#1 Příspěvek od HafisCZ »

Ahojec, mám maticovku 6 sloupců po 8 řadách a mám problémy se správnou detekcí stisků ...
Absolutně netuším kde by mohla být chyba - už mě nic nenapadá. Nyní to správně detekuje tlačítko č.0 a č.1, pak místo č.2 to detekuje č.3.
Zapojení je správné (mám ho kontrolované a dpsku zakázkově vyrobenou)

ŘÁDEK s 'checkKeys() == 1' kontroluje, zdali je zrovna stisknuto tlačítko č.1.

Můj kód k detekci:

Kód: Vybrat vše

#include <avr/io.h>

// PIN's Init definitions
#define O(DIR,PIN) DIR |= (1 << PIN) // Marks PIN as output pin
#define OX(DIR) DIR = 0xFF // Makes all PINs as output pins
#define I(DIR,PIN) DIR &= ~(1 << PIN) // Makes PIN as input pin
#define IX(DIR) DIR = 0x00 // Makes all PINs as input pins
// PIN's SET definitions
#define H(PORT,PIN) PORT |= (1<<PIN) // Makes PIN 5V
#define HX(PORT) PORT = 0xFF // Makes all PINs 5V
#define L(PORT,PIN) PORT &= ~(1<<PIN) // Makes PIN 0V
#define LX(PORT) PORT = 0x00 // Makes all PINs 0V
#define S(PORT,BIN) PORT = BIN // Makes PINs activated from binary pattern
// PIN's GET definitions
#define GET(GPIN,PIN) GPIN & (1<<PIN) // Reads digital value on PIN
#define GET2(GPIN,BIN) GPIN & BIN // Reads digital value of binary defined PIN

int cols = 6;
int rows = 8;
unsigned int binary[8] = {0b00000001,0b00000010,0b00000011,0b00000100,0b00000101,0b00000110,0b00000111,0b00001000};

int checkKeys();
void initPins();

int main(void)
{
   initPins();
   
   //TESTS
   OX(DDRH);
   L(PORTH,PH1);
   //TESTS
   
   while (1){
      if (checkKeys() == 1){
         H(PORTH,PH1);
      }else{
         L(PORTH,PH1);
      }
   }
   
   return 0;
}

void initPins(){
   OX(DDRK);
   IX(DDRF);
}



int checkKeys(){
   for (int x = 0; x < rows; x++){
      S(PORTK,binary[x]);
      for (int y = 0; y < cols; y++){
         if (GET2(PINF,binary[y])){
            return (x*cols + y);
         }
      }
   }
   return -1;
}
Uživatelský avatar
AB1
Příspěvky: 312
Registrován: 23 lis 2009, 00:00

#2 Příspěvek od AB1 »

Tento kód se mi zdá pře#definovaný až do nepřehlednosti.
Všeho moc škodí.

Kód: Vybrat vše

unsigned int binary[8] = {0b00000001,0b00000010,0b00000011,0b00000100,
0b00000101,0b00000110,0b00000111,0b00001000};
...
...
for (int x = 0; x < rows; x++){
      S(PORTK,binary[x]);

Klávesnice má 8 řádků, takže tady máš postupně nastavovat bity 0 až 7.
Ty ale nastavuješ jenom poslední 4 bity (někdy dokonce 2 nebo 3 současně).

Tento kód také vyžaduje externí pull-down (odpor proti zemi) na všech pinech sloupců.
Jednodušší je použít opačnou logiku a vnitřní pull-upy.
Uživatelský avatar
HafisCZ
Příspěvky: 23
Registrován: 17 led 2014, 00:00

#3 Příspěvek od HafisCZ »

Jejda, díky xD Vůbec sem si toho nevšiml. Uvidím co to udělá, když to změním.

//EDIT: Tak díky xD Opravdu xD Problém vyřešen ... zdá se, že jsem udělal chybu v opravdu triviální části xD

//EDIT2: No, tak to je opravdu s prominutím v prdeli. Teď jsem zjístil, že mi nejedeou 2 řady tlačítek: 4,5. Projistotu jsem všechny spoje přeměřil měřákem, mcu jsem znova připájel v místě kontaktů s 4,5 řadou ... ale stejně to nefunguje.

Kód: Vybrat vše

#include <avr/io.h>

// PIN's Init definitions
#define O(DIR,PIN) DIR |= (1 << PIN) // Marks PIN as output pin
#define OX(DIR) DIR = 0xFF // Makes all PINs as output pins
#define I(DIR,PIN) DIR &= ~(1 << PIN) // Makes PIN as input pin
#define IX(DIR) DIR = 0x00 // Makes all PINs as input pins
// PIN's SET definitions
#define H(PORT,PIN) PORT |= (1<<PIN) // Makes PIN 5V
#define HX(PORT) PORT = 0xFF // Makes all PINs 5V
#define L(PORT,PIN) PORT &= ~(1<<PIN) // Makes PIN 0V
#define LX(PORT) PORT = 0x00 // Makes all PINs 0V
#define S(PORT,BIN) PORT = BIN // Makes PINs activated from binary pattern
#define INV(PORT) PORT = ~PORT // Inverts all PINs values
// PIN's GET definitions
#define GET(GPIN,PIN) GPIN & (1<<PIN) // Reads digital value on PIN
#define GET2(GPIN,BIN) GPIN & BIN // Reads digital value of binary defined PIN

// Definitions for KEYBOARD ROWS and COLS
#define KEYBOARD_ROW PORTK
#define KEYBOARD_COL PINF

// Some important variables for this program
int cols = 6;
int rows = 8;
unsigned int binary[8] = {0b00000001,0b00000010,0b00000100,0b00001000,0b00010000,0b00100000,0b01000000,0b10000000};

// To be sure
int checkKeys();
void initPins();

int main(void)
{

    initPins();

    //TESTS
    TCCR1B |= (1 << CS10);
    OX(DDRH);
    L(PORTH,PH1);
    //TESTS

    while (1){
        if (TCNT1 >= 49999){
            if (checkKeys() >= 0){
                H(PORTH,PH1);
            }else {
                L(PORTH,PH1);
            }
            TCNT1 = 0;
        }
    }

    return 0;
}

void initPins(){ // Inits all PINs required
    OX(DDRK);
    IX(DDRF);
}

int checkKeys(){ // Returns ID of pressed button (0 - 47)
    for (int x = 0; x < rows; x++){
        S(KEYBOARD_ROW,binary[x]);
        for (int y = 0; y < cols; y++){
            if (GET2(KEYBOARD_COL,binary[y])){
                return (x*cols + y);
            }
        }
    }
    return -1;
}
Uživatelský avatar
HafisCZ
Příspěvky: 23
Registrován: 17 led 2014, 00:00

#4 Příspěvek od HafisCZ »

Aha, takže ... Zjístil jsem v čem je problém ... Z nějakého důvodu mám na 'čtecích' pinech 4,5 (v programu/zapojení 0,1) napětí 1V - když je aktivní :/ Nevíte čím to může být ?
Výstup z mcu je veden připojen na 10k odpor k zemi a na tlačítko spojené s napájeným pinem.

mcu: ATmega2560

//Oprava: Takže jsem zjístil, že jsem nějak vypálil půlku portu, takže nejedou 4 PINy - nezáleží na nastavení DDRx / PORTx ... No co dodat ...
Uživatelský avatar
Atlan
Příspěvky: 4514
Registrován: 10 kvě 2004, 00:00
Bydliště: Košice

#5 Příspěvek od Atlan »

Njeje tam vyvedene JTAG alebo ina periferia ? ktoru treba vypnut ?
Uživatelský avatar
HafisCZ
Příspěvky: 23
Registrován: 17 led 2014, 00:00

#6 Příspěvek od HafisCZ »

No, v tom PORTu jsou 2 piny pro JTAG, ten ale nepoužívám a na těch 2 pinech není ani nic připojeného.
Uživatelský avatar
AB1
Příspěvky: 312
Registrován: 23 lis 2009, 00:00

#7 Příspěvek od AB1 »

Máš AVCC spojené s VCC?
Nejlepší by bylo ukázat schéma.
Uživatelský avatar
HafisCZ
Příspěvky: 23
Registrován: 17 led 2014, 00:00

#8 Příspěvek od HafisCZ »

AVCC mám připojeno na standartní VCC a AGND na GND ...
Uživatelský avatar
Atlan
Příspěvky: 4514
Registrován: 10 kvě 2004, 00:00
Bydliště: Košice

#9 Příspěvek od Atlan »

HafisCZ píše:No, v tom PORTu jsou 2 piny pro JTAG, ten ale nepoužívám a na těch 2 pinech není ani nic připojeného.


A ten JTAG mas vypnuty v ppoistakach pri programovani ?
Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“