Pic ile PS2 klavye Kullanımı hakkında detaylı bir makale. Klavyenin çalışma prensibi bağlantı uçlarının açılımları data transferleri hakkında bilgiler ve C dili ile hazırlanmış kütüphane dosyaları örnek yazılım uygulama görüntüleri
Tarihçesi: İlk kez yazı makinesinin mucidi olan Christopher Latham Sholes tarafından 1867’de ortaya çıkan klavye birimi o günden günümüze kadar teknolojiye ayak uydurması dışında pek bir değişikliğe uğramadı. Bugün bir çok bilgisayarda kullanılan Q klavyenin de mucidi olan Sholes, bu kadar karmaşık harf dizilimini mühendisliğe aykırı olarak yazıların daha yavaş yazılması dolayısı ile makinelerinin daha az bozulması için oluşturdu.
Çalışması: Klavye çalışma mantığı oldukça basittir. Her tuş basımında klavye kendine has 8 bitlik özel tuş bilgilerini gönderir, bu kodlar çözülerek hangi tuşun basıldığı kararı alınır ve kullanılır. Basılan tuş dahilinde hangi bilgilerin bizlere gönderildiği aşağıdaki tablolardan görülebilir.
Şekil 1 – Klavye Özel Kodları
Bağlantı Şekli: Klavyeler çeşitli bağlantı şekillerine sahip olsalar da dünya çapında en çok kullanılan bağlantı şekillerinden biri DIN ya da PS/2’dir. Aşağıdaki şekilde PS/2 yapısının giriş birimi görülmektedir.
Şekil 2 – PS/2 Bağlantı Şekli
Şekil-2’de de görüleceği üzere PS/2 yapısında 6 farklı bağlantı noktası bulunmaktadır. Sırasıyla kaç numaralı pinin ne işe yaradığını söyleyecek olursak;
1- Data hattıdır
2- Boş hat, bağlantı yapılmayacak
3- GND, toprak hat ucudur
4- VDD, güç ucudur, +5V verilecek hattır
5- Clk ucudur, iletişim saati buradan verilir
6- Boş hat, bağlantı yapılmayacak
Önemli not: Bu yapı giriş birimi olduğu için klavyeden direk hat çekilecekse, tam simetriğine göre işlem yapılmalıdır. Aksi takdirde klavyeniz zarar görebilir.
Klavye Zaman Diyagramı ve C Kodunun Yazılması
Öncelikle biz iletişimimizi klavyeden kaynağımıza doğru yapacağımız için aşağıdaki zaman diyagramını kullanacağız. Görüldüğü üzere klavye her bir tuş bilgisi için aşağıdaki şekilde 20 ile 30 Khz arasında saat darbesi ve data sinyali üretmektedir. Eğer bu sinyalleri düşen kenarda algılamayı sağlarsak iletişim birimimizi çok kolay yazabiliriz.
Şekil 3 – Kklavyeden Kaynağa
Yukarıdaki zaman diyagramını yorumlayacak olursak;
– Klavyeden hiçbir tuşa basılmaz iken saat ve data yolu yüksek seviyede duracaktır.
– Klavyeden herhangi bir tuşa basıldığında ilk saat darbesinde data hattı sıfıra çekilir.
– Daha sonraki 8 saat darbesinde tuşa ait, şekil-1’deki özel kod gönderilir.
– Daha sonra parity biti gönderilir, klavye tek parity sistemini kullanır
– En sonda da iletişimin bittiği yönünde 11. Saat darbesinde bitiş bilgisi gönderilerek iletişim sonlandırılır.
Burada belirttiğimiz bu yapıyı anlamak için aşağıdaki C fonksiyonu kullanılabilir. Parity bizim için önemli olmadığından kontrol ihtiyacı duyulmamıştır. Fonksiyon geri dönüş olarak klavyeden algıladığı özel kodu gönderecektir.
Klavye Kodunu Alan Fonksiyon
unsigned char get_byte(void) { char i; unsigned char veri=0; for(i=0;i<11;i++) //11 bitlik veri gelecek { while(Clock); //İlk önce Clock=1 olmalı if( (i0)) //2->9 bitler { veri=veri>>1; if(Data==1) veri=veri | 0x80; } while(!Clock); //Son olarak Clock=0 olmalı } return veri; //Algılanan değer gönderiliyor }
Klavye için yukarıdaki kodu yazmak başlı başına yeterli değildir. Klavyede her tuşa basıldığında o tuşun özel kodu, tuş bırakıldığında o tuşa ait başka bir kod ve tekrar o tuşun kendi kodu gönderilir. Mesela bazı tuşlara basılıp bırakıldığında aşağıdaki kodlar sırasıyla klavyeden gönderilecektir;
A: 0x1C -> 0xF0 -> 0x1C
H: 0x33 -> 0xF0 -> 0x33
1: 0x16 -> 0xF0 -> 0x16
Görüldüğü üzere 0xF0 burada kilit rol oynamaktadır. Eğer sadece yukarıdaki C kodunu kullanacak olursanız, tek tuşa bastığınızda sanki 3 ayrı tuşa basmış gibi olacaksınız. Bunu engellemek için aşağıdaki kod sistemini kullanabilirsiniz.
data=get_byte();
while(get_byte()==0xF0);
Burada algılama işlemini ister 0xF0’dan önce, isterseniz de sonda yapabilirsiniz. Daha sonrası ise algıladığınız kodun bildiğimiz ASCI karşılığını bulmaktan ibarettir. İsterseniz benim yaptığım gibi shift ve caps lock tuşlarını algılayarak büyük, küçük veya tuşların ikinci görevlerini kullanabilirsiniz. Ben papatya yayıncılığın sağladığı diziyi kullanmayı tercih ettim.
const unsigned char kucuk[67][2]={ {0x0d,0x7e},{0x0e,'"'},{0x15,'q'},{0x16,'1'}, {0x1a,'z'},{0x1b,'s'},{0x1c,'a'},{0x1d,'w'}, {0x1e,'2'},{0x21,'c'},{0x22,'x'},{0x23,'d'}, {0x24,'e'},{0x25,'4'},{0x26,'3'},{0x29,' '}, {0x2a,'v'},{0x2b,'f'},{0x2c,'t'},{0x2d,'r'}, {0x2e,'5'},{0x31,'n'},{0x32,'b'},{0x33,'h'}, {0x34,'g'},{0x35,'y'},{0x36,'6'},{0x39,','}, {0x3a,'m'},{0x3b,'j'},{0x3c,'u'},{0x3d,'7'}, {0x3e,'8'},{0x41,0xef},{0x42,'k'},{0x43,3}, {0x44,'o'},{0x45,'0'},{0x46,'9'},{0x49,7}, {0x4a,'.'},{0x4b,'l'},{0x4c,2},{0x4d,'p'}, {0x4e,'+'},{0x52,'i'},{0x54,5},{0x55,0x5f}, {0x5a,0xa3},{0x5b,0xf5},{0x5d,','},{0x61,''}, {0x69,'1'},{0x6b,'4'},{0x6c,'7'},{0x70,'0'}, {0x71,','},{0x72,'2'},{0x73,'5'},{0x74,'6'}, {0x75,'8'},{0x79,'+'},{0x7a,'3'},{0x7b,'-'}, {0x7c,'*'},{0x7d,'9'},{0,0} };
Yukarıdaki gibi dizilerimizi de tanımladıktan sonra yapmamız gereken tek şey, bastığımız kodu bulmak, onun hangi diziden seçileceğini bulmak ve onu geri döndürmektir. Tüm bu işlemleri ise aşağıdaki C fonksiyonu yapmaktadır.
Klavye Kodunun Asci’sini Bulan Fonksiyon
unsigned char keyboard(void) { unsigned char data=0; unsigned char shift=0, i; data=get_byte(); while(get_byte()==0xF0); if((data==0x12)||(data==0x59)) //Sağ ya da sol shifte mi basıldı shift=!shift; //Capslock gibi çalışacak if(data==0x58) //Capslock'a basıldıysa shift=!shift; for(i=0;kucuk[i][0]!=data && kucuk[i][0]; i++); //Tuşun ascii karşılığı bulunuyor if(kucuk[i][0]==data) //Data ascii tablolarımızda var mı bakılıyor { if(shift==0) //Capslock açık değilse küçük harf, açıksa büyük harfin ascii değeri geri gönderiliyor return kucuk[i][1]; else return buyuk[i][1]; } }
Kütüphanemiz tamamlandıktan sonra sıra pic’imize kod yazmaya geliyor. Ben pic olarak dahili kristali nedeniyle 16f628a’yı tercih ettim. Çalışmama kendi 2×16 LCD kütüphanemi de ekledikten sonra main fonksiyonu aşağıdaki gibi şekil alıyor.
#include #include "delay.h" #include "lcd.h" #include "keyboard.h" __CONFIG( PROTECT & CPD & WDTDIS & INTIO & MCLRDIS & LVPDIS & BORDIS & PWRTDIS ); void main(void) { unsigned char i; int j; PORTB=0x00; PORTA=0x00; CMCON=0x07; TRISA=0x03; TRISB=0x00; lcd_init(); lcd_komut(ImlecAltta); for(;;) { i=keyboard(); j++; if(j==17) { lcd_gotoxy(2,1); } else if(j==33) { lcd_clear(); lcd_gotoxy(1,1); j=0; } veri_yolla(i); } }
Kendime ait LCD kütüphanem ise şöyle;
lcd.h Dosyası
/* www.FxDev.org * 2x16 LCD Kullanım Klavuzu * D4,D5,D6,D7 pinlerini kullanarak 4 bit iletişim kullanır. * D4,D5,D6,D7 pinleri sırasıyla kullanılan portun 4.,5.,6. ve 7. * RW/RS/EN pinleri ise sırasıyla kullanılan portun 0.,1. ve 2. pinlerine bağlanır. * Cursor kapalıdır. * RW kullanılmadığı için direk toprağa bağlanabilir. * * lcd_init(); ile LCD'nin ilk ayarlarını yap * lcd_clear(); ile LCD'yi sil * lcd_yaz("deneme"); şeklinde yazı yazdır. * veri_yolla('F'); şeklinde tek ascii kodu yazdır. * lcd_gotoxy(1,13); şeklinde LCD'nin istenilen yerine git. * www.FxDev.org */ #define lcd_port PORTB //Pin tanımlamaları /* LCD'de kullanilan komutlarin tanimlamasi*/ #define Sil 1 // Ekrani temizler #define BasaDon 2 // Imleci sol üst köseye getirir #define SolaYaz 4 // Imlecin belirttigi adres azalarak gider #define SagaYaz 6 // Imlecin belirttigi adres artarak gider #define ImlecGizle 12 // Göstergeyi ac, kursor görünmesin #define ImlecAltta 14 // Yanip sönen blok kursor #define ImlecYanSon 15 // Yanip sönen blok kursor #define ImlecGeri 16 // Kursorü bir karakter geri kaydir #define KaydirSaga 24 // Göstergeyi bir karakter saga kaydir #define KaydirSola 28 // Göstergeyi bir karakter sola kaydir #define EkraniKapat 8 // Göstergeyi kapat (veriler silinmez) #define BirinciSatir 128 // LCD'nin ilk satir baslangic adresi // (DDRAM adres) #define IkinciSatir 192 // Ikinci satirin baslangic adresi #define KarakUretAdres 64 // Karakter üreteci adresini belirle // (CGRAM adres) /* LCD'de Kullanilan Fonksiyon Seçimi */ #define CiftSatir8Bit 56 // 8 bit ara birim, 2 satir, 5*7 piksel #define TekSatir8Bit 48 // 8 bit ara birim, 1 satir, 5*7 piksel #define CiftSatir4Bit 40 // 4 bit ara birim, 2 satir, 5*7 piksel #define TekSatir4Bit 32 // 4 bit ara birim, 1 satir, 5*7 piksel extern void veri_yolla(unsigned char); extern void lcd_clear(void); extern void lcd_yaz(const char * s); extern void lcd_gotoxy(unsigned char x, unsigned char y); extern void lcd_init(void); extern void lcd_komut(unsigned char c);
lcd.c Dosyası
#include #include "lcd.h" #include "delay.h" void lcd_busy(void) { DelayUs(250); } void lcd_komut(unsigned char c) { unsigned char temp; temp = 0x00; temp |= 0x04; lcd_port = temp; temp |= ( c & 0xF0 ); lcd_port = temp; temp &= 0xF0; lcd_port = temp; lcd_busy(); temp = 0x00; temp |= 0x04; lcd_port = temp; temp |= ( (c & 0x0F)<<4 ); lcd_port = teap; temp &= 0xF0; lcd_port = temp; lcd_busy(); } void veri_yolla(unsigned char c) { unsigned char temp; temp = 0x00; temp |= 0x05; lcd_port = temp; temp |= ( c & 0xF0 ); lcd_port = temp; temp &= 0xF1; lcd_port = temp; lcd_busy(); temp = 0x00; temp |= 0x05; lcd_port = temp; temp |= ( (c & 0x0F)<<4 ); lcd_port = temp; temp &= 0xF1; lcd_port = temp; lcd_busy(); } void lcd_clear(void) { lcd_komut(0x1); DelayMs(2); } void lcd_yaz(const char * s) { lcd_busy(); while(*s) veri_yolla(*s++); } void lcd_gotoxy(unsigned char x,unsigned char y) { if(x==1) lcd_komut(0x80+((y-1)%16)); else lcd_komut(0xC0+((y-1)%16)); } void lcd_init() { unsigned char temp=0; temp &= 0xF0; lcd_port=temp; DelayMs(15); lcd_komut(0x02); lcd_busy(); lcd_komut(CiftSatir4Bit); lcd_komut(SagaYaz); lcd_komut(ImlecGizle); lcd_clear(); lcd_komut(BirinciSatir); }
Son olarak data hattını pic’in RA1, Clk hattını da RA0 bacağına bağlayıp, klavyenin enerjisini verip devreyi çalıştırdığımızda ekranda sadece altta duran imleci göreceksiniz, daha sonra klavyeden bastığınız her tuş ekrana küçük harf olarak yazılacaktır. Bir kez shift ya da caps lock’a basarsanız harflerin büyük hallerine ya da tuşların ikinci görevlerine ulaşabilirsiniz.
Test Görüntüsü
Keyboard.c ve Keyboard.h dosyaları:
Şifre-Pass: 320volt.com
PicProje E-Dergi 2| Yazar: FxDev
Yayım tarihi: 2018/07/05 Etiketler: microchip pic projeleri, PIC16F628 örnekleri