V projekte Numeric MATRIX KeyPad Interface navrhnem univerzálnu logiku pre vytvorenie interface medzi mcu a numerickou MATRIX klávesnicou.
Princíp konštrukcie numerickej matrix klávesnice spočíva v zapojení tlačidiel do matice, kde vertikálne zapojenie prvého kontaktu tlačidla predstavuje stĺpec a horizontálne zapojenie druhého kontaktu predstavuje riadok. Pole takto zapojených tlačidiel predstavuje x-rozmerné pole, kde x.I sú riadky a x.Y sú stĺpce.
Konštrukcia MATRIX klávesnice:
Väčšina klávesníc absencuje rezistorové polia.
Tie podľa schémy aplikujeme.
Spôsob činnosti MATRIX klávesnice
Činnosť tlačidiel v doporučených článkov sme už popísali. Matrix klávesnica pracuje na odlišnom princípe. Zatiaľ čo u klasických tlačidiel nastavíme daný port tlačidla ako vstupný a zisťujeme vstupnú hodnotu po stlačení, u matrix klávesnice je systém skenovania portov. Klávesnica, napríklad 3x3, má 3 riadky napojené na troch samostatných portov a 3 stĺpce sú napojené na ďalšie tri samostatné porty.
Pri ukážke budeme mať maticovú klávesnice 3x3, kde 3 stĺpce budú zapojené na registru PORTB, a to portoch RB1, RB2, RB3 a riadky budú zapojené na tom istom registre, na portoch RB9, RB10, RB11 .
Rozdelenie častí skenovania:
1. Nastavenie 1. sken - hrany:
Prvé skenovanie (sken strana) bude detekovať prítomnosť log. 0 na stĺpcoch.
-- Porty RB1-RB3 (stĺpce) budú nastavené ako vstupné, TRISB - 1 a ich hodnoty PORTB nastavíme na log. 1.
-- Porty RB9-RB11 (riadky) budú nastavené ako výstupné, TRISB - 0 a ich hodnoty PORTB nastavíme na log. 0.
2. Skenovanie - čakanie:
Procesor skenuje register PORTB, porty RB1-RB3 či sa na nich nachádza hodnota 111, alebo inak 0xE. Pokiaľ áno, čaká.
3. Skenovanie - akcia:
Pokiaľ sa na daných portoch nenachádza 0xE, teda niektoré tlačidlo je stlačené, z registra PORTB sa zistí číslo portu
a tým sa nastaví číslo stĺpca - 0,1,2.
Zistila sa log. 0 na nultom stĺpci, a teda na porte RB1. Premennej reprezentujúcej číslo stĺpca sa priradí hodnota "0".
4. Odpoveď na akciu (nastavenie 2. sken - hrany):
Ako náhle je zistené číslo stĺpca, musí sa zistiť číslo riadku. Urobí sa inverzná operácia k operácií v kroku 1. .
Druhé skenovanie (sken strana) bude detekovať prítomnosť log. 0 na riadkoch.
-- Porty RB1-RB3 (stĺpce) budú nastavené ako výstupné, TRISB - 0 a ich hodnoty PORTB nastavíme na log. 0.
-- Porty RB9-RB11 (riadky) budú nastavené ako vstupné, TRISB - 1 a ich hodnoty PORTB nastavíme na log. 1.
5. Skenovanie - čakanie:
Procesor skenuje PORTB, porty RB9-RB11 či sa na nich nachádza hodnota 111, alebo inak 0xE.
Pokiaľ áno (vrchný obrázok), čaká.
Tento stav nastáva v prípade rýchleho pustenia klávesy.
6. Skenovanie - akcia:
Ak klávesu držíme dostatočne dlho, krok 5. sa preskočí a z portov RB9-RB11 sa z registra PORTB zistí
hodnota log. 0 a tým sa uloží do premennej, reprezentujúcej číslo riadku, jeho označenie - 0,1,2.
Zistila sa log. 0 na nultom riadku, a teda na porte RB9. Premennej reprezentujúcej číslo riadku sa priradí hodnota "0".
Po skenovaní zmačknutej klávesy sme dospeli k riadku 0 a stĺpcu 0. Obe premenné vložíme ako hodnoty indexov do dvojrozmerného poľa, kde máme uložené reprezentujúce znaky v hex, podľa štandardu ASCII.
Popísali sme princíp skenovania. Navrhnem schému zapojenia:
Potencionálny návrh kódu
Pre rýchle a jednoúčelovo-ukážkové prezentovanie funkčnosti, navrhnem jednoduchý kód.
main.c |
/* externa deklarácia */ int rows = 3; int cols = 3; int current_row, current_col, a, b; byte byte_mask; byte Keys[rows][cols] = { {0x31,0x32,0x33}, {0x34,0x35,0x36}, {0x37,0x38,0x39} }; int main(void) { /* nastavenie portov RB1,RB2,RB3,RB9,RB10,RB11 - DIGITAL - riadky-stlpce */ /* nastavenie portu RB0 - DIGITAL - Led */ /* konfiguracia slucky */ while(1) { TRISB=0x000E; PORTB=0x000E; while((PORTB & 0x000E)==0x000E); ScanningRows(); TRISB=0x0E00; PORTB=0x0E00; while((PORTB & 0x0E00)==0x0E00); ScanningCols(); for(a=0;a<=rows;a++) { for(b=0;b<=cols;b++) { if(Keys[a][b]==Keys[current_row][current_col] && Keys[a][b]==0x31) { Bit_Set(PORTB,0); Delay_ms(40); Bit_Clr(PORTB,0); } } } Delay_s(1); } } void ScanningRows(void) { byte_mask=PORTB & 0x000E; switch(byte_mask) { case 0x0006: current_row=2; break; case 0x000A: current_row=1; break; case 0x000C: current_row=0; break; } } void ScanningCols(void) { byte_mask=PORTB & 0x0E00; switch(byte_mask) { case 0x0600: current_col=2; break; case 0x0A00: current_col=0; break; case 0x0C00: current_col=1; break; } } |
Návrhnutý program po predošlom algoritmovom popise však nie je efektivný, až nepoužiteľný pri snahe prenosového použitia.
Prenositeľnosť medzi rôznymi zariadeniami by znamenalo rekonfiguráciu portov registru/registrov.
Ďalší problém je v samostatnej konfigurácií registrov.
Uvedomme si, že takýmto konfigurovaním rušíme nastavenia na ostatných portov, ktoré môžme využívať v inom zapojení. Problémom je, že aj napriek vložení programu do vlákna, budú ostatné vlákna rušené.
O univerzálnosti nemôže byť ani reč.
Pri využití pointrov a logiky prepínania riadkov/stĺpcov sme schopný napísať adekvátny program, podporujúci prenositeľnosť a univerzálnosť.
Navrh nižšie:
Program
---------------------------------------------------------------------
Názov programu: matrix_keypad
Autor: Diallix
Posledná revízia: 13.02 2018
Jazyk: C
Licencia: freeware
---------------------------------------------------------------------