Kompatibilní zapojení: LCD panel s ATmega8

Ke stažení: kbd_2x3dm.c == kbd_2x3dm.pdf == kbd_2x3dm.htm


/*---------------------------------------------------------------------------

soubor: kbd_2x3dm.c
verze:  1.0
datum:  9.1.2012
popis:

Rutiny pro obsluhu maticove klavesnice 2x3 klavesy.
Prepinani rad klavesnice je rizeno pomoci signalu KBDAB.
Pokud jsou v serii s klavesami zapojeny diody, jsou presne detekovana vsechna
stisknuta tlacitka (umoznuje pouziti dvojhmatu)

rutina kbd_ini() slouzi k inicializaci portu a pinu ke kterym je pripojena klavesnice

rutina kbd_read() precte klavesnici a vrati hodnotu stiskle klavesy (klaves)
- optimalni je spoustet tuto funkci 10 - 20 krat za sekundu

---------------------------------------------------------------------------*/
#ifndef    setb    //setb = makro ze souboru "wait.c"
#include "wait.c"
#endif

//Defaultni definice portu a pinu, ke kterym je pripojena klavesnice
#ifndef PIN_KBD1
#define PIN_KBD1     PINC
#define PORT_KBD1     PORTC
#define DDR_KBD1     DDRC
#endif

#ifndef PIN_KBD2
#define PIN_KBD2     PINC
#define PORT_KBD2     PORTC
#define DDR_KBD2     DDRC
#endif

#ifndef PIN_KBD3
#define PIN_KBD3     PINC
#define PORT_KBD3     PORTC
#define DDR_KBD3     DDRC
#endif

#ifndef PORT_KBDAB
#define PORT_KBDAB     PORTC
#define DDR_KBDAB    DDRC
#endif

#ifndef       KBD1
#define        KBD1     0
#endif
#ifndef       KBD2
#define     KBD2     1
#endif
#ifndef       KBD3
#define     KBD3     2
#endif
#ifndef       KBDAB
#define     KBDAB    3
#endif

//konstanty pro klávesnici:
#ifndef   KBD_SKIP
#define        KBD_SKIP    20    //pocet vynechanych cyklu mezi opakovanym navracenim
#endif                    //hodnoty stale stiskleho tlacitka (autorepeat)

#ifndef   KBD_ACC
#define        KBD_ACC    4    //pocet cyklu, o ktery se zrychluje opakovani (autorepeat)
#endif

//inicializace klavesnice
void kbd_ini(void)
{
clrb(DDR_KBD1,KBD1);
clrb(DDR_KBD2,KBD2);
clrb(DDR_KBD3,KBD3);    //tlacitka - vstupy

setb(PORT_KBD1,KBD1);
setb(PORT_KBD2,KBD2);
setb(PORT_KBD3,KBD3);    //zapnuti pull-up rezistoru na vstupech

setb(DDR_KBDAB,KBDAB);     //prepinani rad klaves - vystup
}

//cteni klavesnice
unsigned char kbd_read(void)
{
static unsigned char klavesa_old=0, cekani=0, zrychleni=0;
unsigned char klavesa=0, i;

clrb(PORT_KBDAB,KBDAB);
for(i=0;i<2;i++)    //cyklus probehne dvakrat (2 rady tlacitek)
    {
    wait_us(5);    //cekani (kvuli fyzicke konstrukci klavesnice (parazitni kapacity)
    if((PIN_KBD1&(1<<KBD1))==0) //pokud je stisknute tlacitko 1 (na vstupu je log. nula)
        setb(klavesa,0+(3*i));    //nastav prislusny bit promenne klavesa
    if((PIN_KBD2&(1<<KBD2))==0) //pokud je stisknute tlacitko 2
        setb(klavesa,1+(3*i));    //nastav prislusny bit promenne klavesa
    if((PIN_KBD3&(1<<KBD3))==0) //pokud je stisknute tlacitko 3
        setb(klavesa,2+(3*i));    //nastav prislusny bit promenne klavesa
    negb(PORT_KBDAB,KBDAB);    //prepni na druhou radu tlacitek
    }

if(klavesa>0)  //pokud bylo stisknuto nejake tlacitko
  {
  if(klavesa_old==klavesa)    //pokud je stisknuto porad stejne tlacitko
      {
      if(cekani>KBD_SKIP)    //pokud se jiz vynechal dostatecny pocet cyklu
          {
          cekani=zrychleni;     //priste se bude cekat o nekolik cyklu mene
                      //(pocet je dan aktualni hodnotou promenne "zrychleni")
          if(zrychleni<=KBD_SKIP)    //pokud jeste ma smysl zrychlovat
              zrychleni+=KBD_ACC;    //zrychli

          return klavesa;            //vrat hodnotu klavesy volajici funkci
          }
      else  //pokud se jeste nevynechal dostatecny pocet cyklu
        cekani++; //pripocti dalsi vynechany cyklus
    }//if(klavesa_old==klavesa)
  else //pokud neni stisknuto stejne tlacitko jako minule
      {
      cekani=0;
      zrychleni=0;
      klavesa_old=klavesa;    //uloz jeho hodnotu pro priste
      return klavesa;            //a vrat tuto hodnotu volajici funkci
      }//else(klavesa_old==klavesa)
  }//if(klavesa>0)
else
    klavesa_old=0;
return 0;
}
//eof
//(c) OK1ZKV 2012