Zaslal: so červen 28 2014, 18:41 Předmět: Špatná detekce stisku tlačítek na Maticové Klávesnici 8x6
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:
#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;
}
Tento kód se mi zdá pře#definovaný až do nepřehlednosti.
Všeho moc škodí.
kód:
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.
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:
#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};
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;
}
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 ...
Nemůžete odesílat nové téma do tohoto fóra. Nemůžete odpovídat na témata v tomto fóru. Nemůžete upravovat své příspěvky v tomto fóru. Nemůžete mazat své příspěvky v tomto fóru. Nemůžete hlasovat v tomto fóru. Nemůžete připojovat soubory k příspěvkům Můžete stahovat a prohlížet přiložené soubory
Informace na portálu Elektro bastlírny jsou prezentovány za účelem vzdělání čtenářů a rozšíření zájmu o elektroniku. Autoři článků na serveru neberou žádnou zodpovědnost za škody vzniklé těmito zapojeními. Rovněž neberou žádnou odpovědnost za případnou újmu na zdraví vzniklou úrazem elektrickým proudem. Autoři a správci těchto stránek nepřejímají záruku za správnost zveřejněných materiálů. Předkládané informace a zapojení jsou zveřejněny bez ohledu na případné patenty třetích osob. Nároky na odškodnění na základě změn, chyb nebo vynechání jsou zásadně vyloučeny. Všechny registrované nebo jiné obchodní známky zde použité jsou majetkem jejich vlastníků. Uvedením nejsou zpochybněna z toho vyplývající vlastnická práva. Použití konstrukcí v rozporu se zákonem je přísně zakázáno. Vzhledem k tomu, že původ předkládaných materiálů nelze žádným způsobem dohledat, nelze je použít pro komerční účely! Tento nekomerční server nemá z uvedených zapojení či konstrukcí žádný zisk. Nezodpovídáme za pravost předkládaných materiálů třetími osobami a jejich původ. V případě, že zjistíte porušení autorského práva či jiné nesrovnalosti, kontaktujte administrátory na diskuzním fóru EB.