You are on page 1of 156

n Sz Antik Yunanda ilk kehribarn maddeleri ekmesiyle balayan elektrik serveni tarih iinde bir ok deiik formda bulunmu,

deimi, evrim geirmitir. Galvani, Volta, Faraday, Amper ve Ohmun katklaryla bilimsel alanda nemi artmaya balayan elektrik, her dnem kendinden sz ettirmeyi baarmtr. O kadar ki zamann Amerikan bakan Benjamin Franklinden de katklar almtr. 19. ve 20. yzyllarda altn an yaayan elektrik zellikle Tesla, Morse, Edison ve Bellin katklaryla bambaka bir yolda ilerlemeye balamtr. zellikle 2. Dnya savandan sonra g yarnda belirleyici olan enerji faktrnn en nemli esi olan elektrik, 50lerden sonra Shockley ve grubunun transistor bulmasyla bilim adamlarna ve kullanclara bambaka dnyalar aralamtr. zellikle 60 ve 70li yllardan sonra muazzam bir ykselie geen elektronik bylelikle, elektrikten konu itibariyle ayrlmtr, fakat her ne olursa olsun birbirlerinin siyam ikizi olmalarn engelleyememilerdir. Gnmze yaklatka transistorlerin belirli dizilimlerini kullancnn deitirebilmesiyle gelien elektronik 80lerin sonuna doru yeni bir yapy oluturacakt: Mikrodenetleyiciler. Dnya mikrodenetleyici firmalarnn banda gelen Microchipin Pic adn verdii mikrodenetleyiciyi anlatmay planladm derslerde zellikle 1972den bu yana sistem dili olarak kullanlan C temel alnacak, microchipin yakn tarihte satn ald Hi-Tech Pic C derleyicisi zerinde rnekler verilecektir. Frat Deveci Austos 2009 fxdev@fxdev.org Elektrik ve elektronie gnl veren herkese

FxDev.org

Sayfa 1

BLM 1 PIC GR IKI AYARLARI, LED, DOT MATRS VE SEVEN SEGMENT UYGULAMALARI
1.1) Hi-Techte Yeni Proje Oluturmak Pic programlamaya balamadan nce ksaca kullanacamz program hakknda bilgi vermek istiyorum. Hi-Tech, Microchipin kullanclara sunduu bir derleyicidir. Tek bana bu derleyici kullanmak mmkn deildir. Onun iin mutlaka bir program yazm editrne ihtiya vardr. Bunun iin en ok kullanlan ara yz programlar ise MPLAB ve Hi-Tidedr. Ben uygulama yaparken zellikle grsel adan ho, kullanmas kola, daha nce program yazanlarn alk olduu Eclipsein bir uyarlamas olan Hi-Tide arayzn kullanacam. Bu derleyici kullanmak isterseniz sitesinden cretsiz indirebilirsiniz. Hi-Tideda proje oluturmak iin ncelikle File/New/Project sekmelerine baslr. Karmza ekil-1 deki gibi bir ekran kmas gerekir. Burada daha nce yklediimiz Hi-Tech versiyonlarn grmemiz mmkndr.

ekil 1 Ykl Derleyiciler

Buraya next dedikten sonra asl derleyicinin seilecei blme gelinir. Biz 16f serisi picler zerine alacamz iin ekil-2de grlen PICC STD (9.60 PL2) seilir. Eer daha st versiyonlar kullanyorsanz yine ayn ekilde yklediiniz derleyiciyi seerek next dememiz yeterli olacaktr.

FxDev.org

Sayfa 2

ekil 2 - Derleyici Seim Ksm

Bu blmden sonra projemizi bilgisayarmzda nereye oluturmak istediimize dair bir pencere bizleri karlayacaktr. Dilediiniz yeri setikten sonra ekil-3teki ekrana da next demeniz yeterli olacaktr.

ekil 3 - Proje Oluturacamz Yeri Seme Ekran

FxDev.org

Sayfa 3

Bu blmden sonra aadaki ekrana next dememiz ve ekil-4teki blme gelmemiz gerekmektedir. Bu blm, bu ksmdaki en can alc noktadr. Hangi pic ile alacaksak onu bu blmden seip next dememiz gerekmektedir. Ben dersler iinde bir tutarllk olmas dolaysyla 16f877a ile almay uygun gryorum. Listeden bu pici seip next diyoruz.

ekil 4 - Pic Seim alan

Daha sonraki blmde ekil-5te grlecei gibi kullandmz picin paket yapsn sememiz gerekmektedir. Bizim kullandmz picler genelde DIP soket olduundan 40DIPi seip finish diyoruz.

ekil 5 - Pic zellikleri ve Paket Yaps

FxDev.org

Sayfa 4

ekil-5teki blme finish dediimizde main dosyamz kendiliinden oluacak ve artk kod yazmaya hazr hale gelecektir.

1.2) Hi-Techde lk Proje lk uygulama olarak klasik led yakp sndrme ilemini yapacaz. ekil-6daki gibi Proteusta devremizi oluturuyoruz.

ekil 6 - lk Deneyimiz

Devremizi oluturduktan sonra ncelikle gecikme yaratarak, ayn zamanda yava yava Cde ilemlerin nasl yrdne dair rnek vereceiz. Gecikme ktphanemiz olan delay.h ve delay.c dosyalarn Program Files\HI-TECH Software\PICC\STD\9.60\samples\delay klasrnden alp (siz derleyiciyi nereye kurduysanz oradan alnz) projemizi oluturduumuz klasrn iine atyoruz. Bu dosyalar proje klasrmze ekledikten sonra Hi-Tide ekranndan proje ismine gelip ekil-7deki gibi refresh yapmamz gerekmektedir.

FxDev.org

Sayfa 5

ekil 7 - Refresh Yapacamz Yer

Bu dosyalarn ne ie yaradna gelince; Cnin en byk zelliklerinden biri ktphane oluturabilmemizdir. Eer bu iki dosyay ap bakarsanz kullanacamz gecikmelerin eitli ifadelerle salandn greceksiniz. Daha sonra kendimiz ktphane oluturduumuzda bu konuyu daha kolay anlayacaksnz fakat imdilik dosyalar oraya atmakla yetinelim. Burada dikkat edilmesi gereken bir konu da delay.h doyas iindeki #define Xtal_FREQ 4MHZ yazan ksmdr; burada setiimiz kristale gre 4MHZ ksmn 8MHZ, 16MHZ eklinde deitirebilirsiniz. Fakat kristal deeriniz 4Mhz ise o ksma dokunmayabilirsiniz. Tm bunlardan sonra artk kodumuzu yazmaya geebiliriz, ilem olarak ledin her yarm saniye de bir yanp snmesi olayn C koduyla gerekletirelim.

FxDev.org

Sayfa 6

#include <htc.h> #include "delay.h"

// Gecikme yaratacak ktphane

void main(void) // Ana fonksiyon alan { TRISB=0x00; // PORTB k olarak ynlendiriliyor PORTB=0x00; // PORTB'nin tm klar sfrlanyor while (1) // Sonsuz dngye giriliyor { RB0=1; // Led yanacak DelayMs(250);DelayMs(250); // Yarm saniye beklenecek RB0=0; // Led snecek DelayMs(250);DelayMs(250); // Yarm saniye beklenecek } }

Kodlarmz ekildeki gibi yazdmzda save tuuna basarak .hex dosyamz oluturmu olacaz. .hex dosyamz proje klasrnde bulunan Release klasrnn iinde olacaktr. Proteustan bu dosyay alp altrdmzda yarm saniyede bir ledin yanp sndn greceksiniz. 1.3) Buton ile Led Kontrol imdi ise devremize bir buton balayarak bastmzda ledin yanmasn, ektiimizde de ledin snmesini salayalm. Bunun iin Proteusta ekil-8deki devreyi kuralm.

ekil 8 - Led Yakp Sndrme Uygulamas Devresi

Bu devrede delay.h ve delay.c dosyalarmz kullanmayacamz iin proje klasrnden silebilirsiniz. Unutmayn ki gereksiz her ktphane ve fonksiyon picde bo yer kaplayacaktr. stediimiz ilemi yapan C kodunu aadaki tabloda grebilirsiniz.

FxDev.org

Sayfa 7

#include <htc.h> void main(void) { ADCON1=0x07; TRISA=0x01; TRISB=0x00; PORTB=0x00; PORTA=0x00; for(;;) { RB0=RA0; } } // Ana fonksiyon alan // // // // // // PORTA dijital olarak ynlendiriliyor RA0 giri olarak ynlendiriliyor PORTB k olarak ynlendiriliyor PORTB'nin tm klar sfrlanyor PORTA'nn tm klar sfrlanyor Sonsuz dngye giriliyor

// RB0 k RA0 giriine eitleniyor

C programlama dilinde sonsuz dngye while(1) eklinde girilebilecei gibi for(;;) eklinde de girilebilir. Ayrca yine bir ok yolla sonsuz dngye girmek de mmkndr. Yukardaki kodlarda ilgin grlebilecek ADCON1, PORTA portunu dijital giri k yapmaya izin verir. Eer bunu yapmasaydk PORTA analog olacak ve dijital olarak giri ve k ilemleri yapamayacaktk. Ayrntl bilgi iin ltfen datasheete ve ileride anlatacamz ADC konusuna gz atnz. 1.4) Karaimek Uygulamas Bu uygulamamzda ise nl Kara imek dizisindeki Kitin nnde bulunan led animasyonunu gerekletireceiz. Ayrca Cnin eitli zelliklerini de bu uygulamamzda grmek maksadyla kodlar biraz daha karmaklatracaz. Devremizi ekil-9daki gibi proteusta kuralm.

ekil 9 - Karaimek Devresi

FxDev.org

Sayfa 8

#include <htc.h> #include "delay.h"

// Gecikme ktphanesi

void main(void) // Ana fonksiyon alan { char led=1; // led eklinde bir sabit tanmlanyor TRISB=0x00; // PORTB k olarak ynlendiriliyor PORTB=0x00; // PORTB'nin tm klar sfrlanyor for(;;) // Sonsuz dngye giriliyor { PORTB=led; // PORTB led deikenine eitleniyor led=led<<1; // led birimi bir sola kaydrlyor DelayMs(100); // 100ms bekleniyor if(led==0x80) // Eer PORTB=0x80 olursa alt ilemlere geiliyor { for(;;) // Tekrar sonsuz dngye giriliyor { PORTB=led; // PORTB led deikenine eitleniyor led=led>>1; // led birimi bir saa kaydrlyor DelayMs(100); // 100ms bekleniyor if(led==0x01) // Eer PORTB=0x01 olursa ikinci sonsuz dngden break; // birinci sonsuz dngye giriliyor } } } }

C kodunda girilen break kodu ierisinde bulunan dngden kmaya yarayan bir C kodudur. leriki derslerde baz uygulamalarda bu kodun olduka yararl olduunu greceksiniz. 1.5) Seven Segment Gsterimi, 0-9 ve 00-99 Sayc Birok uygulamada kullanlan seven segmentler esasen bir araya getirilmi 7 ledden oluur. ekil-10da tek bir seven segmentin balant ekli gzkmektedir.

ekil 10 - Seven Segment

Ben genelde ortak katot seven segment kullanmay tercih ediyorum ve kodlarm buna gre yazyorum. ekil-10da da grlecei zere baz saylar ve harfleri karmak iin eitli kombinasyonlarda ledleri yakmak gerekmektedir. Bu konuda da Cnin bir dier gzel zellii olan diziyi kullanmak yazacamz kod iin gayet kullanl olacaktr.
FxDev.org Sayfa 9

Kullanacamz diziyi u ekilde tanmlayabiliriz; const unsigned char segment[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; Bu diziyi tanmladktan sonra devremizi 0dan 9a ve tekrar 0a saydracak ekil-11deki devreyi kurduktan sonra C kodumuzu yazalm.

ekil 11 - 0-9 Sayc

Aadaki C kodunda constant deeri Cde sabitler iin kullanlan bir metottur. Genel itibari ile segment[0] seven segmentte 0 deerini gsteren dizi deeri, segment[1] seven segmentte 1 deerini gsteren dizi deeridir. Tm dizi deerleri bu ekilde ayarlanmtr.
#include <htc.h> #include "delay.h" // Gecikme ktphanesi

const unsigned char segment[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; void main(void) // Ana fonksiyon alan { char i; // Herhangi bir deiken tanmlanyor TRISB=0x00; // PORTB k olarak ynlendiriliyor PORTB=0x00; // PORTB'nin tm klar sfrlanyor for(;;) // Sonsuz dngye giriliyor { PORTB=segment[i]; // Seven segment deerleri alnyor i++; // i bir artrlyor DelayMs(250); // 250ms bekleniyor if(i>9) // Eer say 9'dan byk ise 0'a dn i=0; // Deiken 0 yaplyor } }

ekildeki rnei yaptktan sonra tarama metodunu retmek maksadyla 00-99 sayc devresini ekil-12deki gibi tasarlayalm. Bu tasarmda sayma ilemini aa ve yukar butonlarn da katarak etkinlik katalm.

FxDev.org

Sayfa 10

ekil 12 - 00-99 Sayc Devresi

ekil-12deki devreyi kurduktan sonra C kodumuzu yazalm.


#include <htc.h> #include "delay.h" // Gecikme ktphanesi

const unsigned char segment[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; void sayi_goster(char i) { PORTC=0x02; PORTB=segment[i/10]; DelayMs(5); PORTC=0x01; PORTB=segment[i%10]; DelayMs(5); } // Say gstermeye yarayan fonksiyon // // // // // // PORTC'de 2 deeri gnderiliyor i'nin 10'a blm gsteriliyor 5ms bekleniyor PORTC'de 1 deeri gnderiliyor i'nin 10'a blmnden kalan gsteriliyor 5ms bekleniyor

void main(void) // Ana fonksiyon alan { int i; // Herhangi bir deiken tanmlanyor ADCON1=0x07; // PORTA dijital yaplyor TRISA=0x03; // PORTA'nn ilk iki pini giri TRISB=0x00; // PORTB k olarak ynlendiriliyor TRISC=0x00; // PORTC k yaplyor PORTA=0x00; // PORTA'nin tm klar sfrlanyor PORTB=0x00; // PORTB'nin tm klar sfrlanyor PORTC=0x00; // PORTC'nin tm klar sfrlanyor for(;;) // Sonsuz dngye giriliyor { if(RA0==0) // RA0'pini 0 m? { while(!RA0); // Buton brakld m diye baklyor i++; // Deiken artrlyor if(i>99) // Eer deiken 99'dan bykse 0 oluyor i=0;

FxDev.org

Sayfa 11

} else if(RA1==0) { while(!RA1); i--; if(i<0) i=99; } sayi_goster(i); } }

// RA1'pini 0 m? // Buton brakld m diye baklyor // Deiken azaltlyor // Eer deiken 0'dan kkse 99 oluyor // O anki say gsteriliyor

Grld zere tarama yntemi bize port kazanm salyor. Bu zellikle byk saydrma ilemlerinde, saat devrelerinde olduka ie yarayan bir metottur. Biz burada bu ilemi zel bir fonksiyonla, elle yaptysak da ileriki konularda kesmelerle bu iin daha da kolaylaabileceini greceiz. 1.6) Dot Matris Uygulamas Dot matrisler zellikle tabela uygulamalarnda gnmzde sklka kullanlan aralardr. lerinde eitli ekillere dizilmi ledler bulundururlar. Gnmzde en ok kullanlanlar ise 8x8 ve 5x7lik modellerdir. Biz bu uygulamamzda 5x7lik dot matriste eitli harfleri yazmay renirken, C dilinde kullanlan dizilerin de ne kadar faydal olduunu tekrar greceiz. ncelikle ekil-13teki proteus devresini tasarlyoruz.

ekil 13 - Dot Matris Uygulamas

FxDev.org

Sayfa 12

Bu uygulamann almas iin gereken kodlar ise yledir;


#include <htc.h> #include "delay.h" unsigned unsigned unsigned unsigned unsigned char char char char char F[]={0x7f,0x09,0x09,0x09,0x01}; I[]={0x00,0x41,0x7f,0x41,0x00}; R[]={0x7f,0x09,0x19,0x29,0x46}; A[]={0x7e,0x11,0x11,0x11,0x7e}; T[]={0x01,0x01,0x7f,0x01,0x01}; // Gecikme ktphanesi // // // // // F I R A T // Say

void harf_goster(unsigned char harf[]) gstermeye yarayan fonksiyon { PORTB=0x01; // Birinci stun seiliyor PORTC=~harf[0]; // Harfin 5 stunundan 1.'si DelayMs(5); // 5ms bekleniyor PORTB=0x02; // Birinci stun seiliyor PORTC=~harf[1]; // Harfin 5 stunundan 1.'si DelayMs(5); // 5ms bekleniyor PORTB=0x04; // Birinci stun seiliyor PORTC=~harf[2]; // Harfin 5 stunundan 1.'si DelayMs(5); // 5ms bekleniyor PORTB=0x08; // Birinci stun seiliyor PORTC=~harf[3]; // Harfin 5 stunundan 1.'si DelayMs(5); // 5ms bekleniyor PORTB=0x10; // Birinci stun seiliyor PORTC=~harf[4]; // Harfin 5 stunundan 1.'si DelayMs(5); // 5ms bekleniyor }

gnderiliyor gnderiliyor gnderiliyor gnderiliyor gnderiliyor

void main(void) // Ana fonksiyon alan { int i; // Herhangi bir deiken tanmlanyor TRISB=0x00; // PORTB k olarak ynlendiriliyor TRISC=0x00; // PORTC k yaplyor PORTB=0x00; // PORTB'nin tm klar sfrlanyor PORTC=0x00; // PORTC'nin tm klar sfrlanyor for(;;) // Sonsuz dngye giriliyor { for(i=0;i<20;i++) // Belirli sre tekrar ediliyor harf_goster(F); // F harfi gsteriliyor for(i=0;i<20;i++) // Belirli sre tekrar ediliyor harf_goster(I); // I harfi gsteriliyor for(i=0;i<20;i++) // Belirli sre tekrar ediliyor harf_goster(R); // R harfi gsteriliyor for(i=0;i<20;i++) // Belirli sre tekrar ediliyor harf_goster(A); // A harfi gsteriliyor for(i=0;i<20;i++) // Belirli sre tekrar ediliyor harf_goster(T); // T harfi gsteriliyor } }

Buradaki harf deerleri internetten aratrlarak kolayca bulunabilir. stenilen ekil ise saylar deitirilerek kartlabilir. Ayrca fonksiyona dizi birimi gndermek de bu rnekte ilenmi olup, kodlarn nasl iledii comment halinde yazlmtr.

FxDev.org

Sayfa 13

BLM 2 INTERRUPT ve TIMER LEMLER


2.1) Hi-Techte Interrupt lemleri Interrupt ya da dier adyla kesme, bir ok ilemin olmazsa olmazlarndandr. Pic16f877de 15ten fazla kesme kayna bulunur. Kesme kaynaklarnn ne olduu ekil-14te detayl bir biimde grlmektedir.

ekil 144 - Kesme Kaynaklar

Bu kadar ok kesme kaynann olmas Picin ok daha etkili bir biimde kullanlmasna ve her bir ilemin kontroln kullancya brakmamasna sebebiyet veren byk bir avantajdr. Kesme birimlerini ksaca bir olaya benzetecek olursak; Diyelim evde, bilgisayarnzda bir yaz yazyorsunuz. O an telefon ald. Gidip telefona bakarsnz, telefonla iinizi hallettikten sonra tekrar yaznza kaldnz yerden devam edebilirsiniz. Veya yaz yazarken hem telefon hem de kap ayn anda ald, yine nem srasna gre bunlara cevap verip yaznza kaldnz yerden devam edebilirsiniz. te kesmeler de ayn yukarda anlatlan mantkla almaktadrlar. Telefon veya kap almas denilen olaylar her bir birimin zel bayraklarna (flag) yklenir. Bylelikle bunlara baklarak kesmenin oluup olumad kontrol edilebilir. Hi-Tech ortamnda kesmeler olduka kolay gerekletirilir. Temel olarak izlenecek yol udur; -Kesmesi izlenecek birimin flagleri temizlenir. -Kesmesi izlenecek birimin kesme izni verilir. -Genel kesme izin birimleri aktif edilir.
FxDev.org Sayfa 14

-Kesme olumu mu diye kontrol edilir. -Eer kesme olumusa, kesme oluma durumunda ilenecek program arlr ya da iletilir. -Kesme durumunda ilenecek olay bittiinde, kesme biriminin bayra sfr yaplr. Yukarda madde madde anlatlan ilem basamaklar, tm kesme birimleri iin geerlidir. Biz bu blmde sadece PORTB kanalndaki kesmelerle ilgileneceiz. Dier kesmeler de ayn mantkla altndan, dier kesme kaynaklaryla ilgili bilgilere gelecek blmlerde ksaca deineceiz. 2.2) D Kesme Uygulamas PORTB kanalnda ekil-14te de grlecei zere iki tr kesme kayna vardr. Bunlardan biri RB0/INT kesmesi iken dieri PORTB deiim kesmesidir. lk deneyimizde RB0/INT d kesmesini kullanarak led yakp sndrme ilemleri yapacaz. RB0/INT d kesmesini kontrol eden registerler ve grevleri yledir. Tm bu deerler datasheetten bire bir alnmtr. INTE INTF INTEDG GIE : D kesme izin verme biti (1: izin verildi, 0: izin verilmedi) : D kesme bayrak biti (1: kesme olutu, 0: kesme olumad) : D kesme kenar seme biti (1: ykselen kenar, 0: den kenar) : Genel kesme izin biti

Dip not: Genel itibari ile kesme izin verme bitlerinin sonu IE ile biterken, kesme bayrak bitlerinin sonu IF ile biter. ncelikle Proteusta aadaki devreyi izelim. RB0 kesmesi ykselen kenarda meydana geldiinde led yanacak, ayn kesme tekrar meydana geldiinde ise led snecektir.

ekil 15 - D Kesme Uygulamas

FxDev.org

Sayfa 15

stediimiz ilemi yerine getiren Hi-Tech programn aadaki gibi yazarak yerine getirebiliriz.
#include <htc.h> void main(void) { TRISB=0x01; PORTB=0x00; INTF=0; INTEDG=1; INTE=1; GIE=1; for(;;); } static void interrupt // isim(void) // { char i; // if(INTF) // { i++; if(i==1) RB1=1; else if(i==2) { RB1=0; i=0; } INTF=0; bayra temizleniyor } } Kesme fonksiyonu Kesme fonksiyon ismi (nemsiz) Kesme iinde bir deiken tanmlanyor D kesme olumu mu baklyor // Her bir kesmede deiken bir artrlyor // Deiken 1 ise // Led yanyor //Deiken 2 ise // Led sndrlyor // Deiken sfrlanyor // Tekrar d kesme alnabilmesi iin kesme // Ana fonksiyon alan // RB0/INT giri, dierleri k // PORTB sfrlanyor // // // // RB0/INT kesme bayra temizleniyor Ykselen kenarda kesme oluacak RB0/INT izni veriliyor Genel kesme izni veriliyor

// lemci sonsuz dngde bekletiliyor

Yukarda da grlecei zere kesme fonksiyonu genel itibari ile


static void interrupt isim(void)

eklindedir. Buradaki isim(void)yerine istenilen fonksiyon ismi yazlabilir. Bu nemsizdir. Yalnz u unutulmamaldr ki kesme altnda tanmlanan fonksiyonlara deer gnderilemez ve kesme fonksiyonu geriye deer dndremez. Bu kesme fonksiyonu yazarken en ok dikkat edilmesi gereken konudur. Ayrca ana fonksiyon altnda sonsuz dngye girilen yerde istediiniz ilemi yaptrmak mmkndr. Yalnzca kesme geldiinde, kesme fonksiyonundaki ilemler yaplacandan, ana fonksiyon altndaki ilemler bundan etkilenmeyecektir. Bu uygulamadan sonra imdi de RB4/RB7 kesmesine geelim. Buraya balayacamz 4 adet buton ile hangi butona bastysak o butona ait ledi yakacak devreyi ekil-16daki gibi kuralm.

FxDev.org

Sayfa 16

ekil 16 - RB4..RB7 Kesmesi

ekildeki devreyi kurduktan sonra istediimiz ilemi yapan kodu yazalm. RB4..RB7 kesmesini kontrol eden registerler aada sralanmtr. Bu birimler datasheetten alnmtr. RBIE RBIF GIE : RB4..RB7 kesme izin verme biti (1: izin verildi, 0: izin verilmedi) : RB4..RB7 kesme bayrak biti (1: kesme olutu, 0: kesme olumad) : Genel kesme izin biti

Bu kaydediciler gz nne alarak yazdmz kodumuz aadaki gibi olacaktr.


#include <htc.h> void main(void) { TRISB=0xF0; PORTB=0x00; RBIF=0; RBIE=1; GIE=1; for(;;); } static void interrupt // Kesme fonksiyonu isim(void) // Kesme fonksiyon ismi (nemsiz) { char i; // Kesme iinde bir deiken tanmlanyor if(RBIF) // RB4..RB7 kesme olumu mu baklyor { if(RB4) // lk butona basldysa PORTB=0x01; // lk ledi yak else if(RB5) // kinci butona basldysa PORTB=0x02; // kinci ledi yak else if(RB6) // nc butona basldysa PORTB=0x04; // nc ledi yak else if(RB7) // Drdnc butona basldysa PORTB=0x08; // Drdnc ledi yak // Ana fonksiyon alan // RB4..RB7 giri, dierleri k // PORTB sfrlanyor // RB4..RB7 kesme bayra temizleniyor // RB4..RB7 kesme izni veriliyor // Genel kesme izni veriliyor // lemci sonsuz dngde bekletiliyor

FxDev.org

Sayfa 17

PORTB=PORTB; // Son deiikliklerin alglanmas iin PORTB'yi bir kez oku RBIF=0; // Tekrar d kesme alnabilmesi iin kesme bayra temizleniyor } }

Yukardaki kodda ilgin olarak gzkebilecek tek yer PORTB=PORTBdir. Fonksiyonun srekli kesme iinde kalmamas iin PORTBdeki son deiikliklerin okunmas gerekmektedir. Bu sorunu da PORTB=PORTB eklinde giderebiliriz. Bylelikle kesme ilemlerinin nasl olacan grdk. Bundan sonra tm kesmeleri ayn ekilde, ncelii de kedimiz belirleyerek oluturulabilirsiniz. 2.3) Hi-Techte Timer lemleri Timer ya da sayclar piclerin iine yerletirilmi sayma grevine yarayan birimlerdir. 16f877ann iinde Timer0, Timer1 ve Timer2 olmak zere 3 timer birimi bulunmaktadr. Timer0 ve Timer2 birimleri 8 bitlik, Timer2 ise 16 bitliktir. Bu ekilde dnldnde Timer0 ve Timer2 ile 255e kadar olan saymlar Timer1 ile 65535e kadar yaplabilir. 2.3.1) Timer 0 Birimi

ekil 17 - Timer 0 Birimi

Timer 0 birimi 8 bitlik bir birim olup dardan ve dahili osilatrden saat sinyali alabilir, 255e kadar saym yapabilir, 255ten 0a dnerken TMR0IF kesme bayran set eder. Timer 0 kontrol eden kaydediciler ve grevleri yledir;

FxDev.org

Sayfa 18

T0CS T0SE PSA PS2, PS1, PS0 TMR0IE TMR0IF

: Timer0 sinyal seim biti (0: Dahili, 1: Harici) : Timer0 kenar seim biti (0: Den kenar, 1: Ykselen kenar) : Frekans blc seim biti (0: Prescaler Timer0 iin, 1: Prescaler WDT iin) : Blm orann belirleyen bitler, bu deerler ekil-18den grlebilir : Timer0 kesme izin biti : Timer0 kesme bayrak biti

ekil 18 - Prescaler deerleri

Timer0 uygulamamzda her yarm saniyede bir ledin yanp snmesini salayalm. ncelikle ekil-19daki Proteus devresini izelim ve hesaplamamz yapalm.

ekil 19 - Timer 0 Uygulamas - 1

Sinyalin kristalden (4MHz) geldiini ve picin bu hz 4e otomatikman bldn dnrsek her saat darbesi 1 mikro saniyede bir gerekleir. Biz ise 500ms=500000us gecikme gerekiyor. O halde 500.000 kere saydrmamz gerekmekte fakat Timer 0 ile en fazla 255e

FxDev.org

Sayfa 19

kadar saydrabiliriz. 250 birim saydrdmz dnrsek (bata o deere TMR0 birimine 50 yklersek); 500.000/250=2000 yapar. Prescaler deerini 1:16 seersek 2000:16=125 yapar. O halde bir deikeni 125e kadar saydracaz ve deiken bu deere ulatnda istediimiz sinyale bize verecek. Bu ilemi yapan C kodu aadaki gibi olur.
#include <htc.h> void main(void) { TRISB=0x00; PORTB=0x00; TMR0=55; T0CS=0; PSA=0; PS2=0; PS1=1; PS0=1; T0IF=0; T0IE=1; GIE=1; for(;;); } static void interrupt // Kesme fonksiyonu isim(void) // Kesme fonksiyon ismi (nemsiz) { char i; // 125'e kadar sayacak deiken if(TMR0IF) // TMR0 kesmesi olumu mu { i++; if(i>0 & i<125) // 0 ile 125 aras 1 ol { RB0=1; } else if(125<i && i<250) //125 ile 250 aras 0 ol { RB0=0; } else if(i>250) // 250'yi aarsa deiken 0 olsun i=0; TMR0=55; // 255-55=200 birim sayacak TMR0IF=0; // Tekrar d kesme alnabilmesi iin kesme bayra temizleniyor } } // Ana fonksiyon alan // PORTB k olarak ayarlanyor // PORTB sfrlanyor // // // // TMR0=55 oluyor Dahili osilatr Prescaler TMR0 iin 1:16 blm deeri

// TMR0 kesme bayra temizleniyor // TMR0 kesmesine izin veriliyor // Genel kesme izni veriliyor // lemci sonsuz dngde bekletiliyor

Grld zere Timer 0 kesmesini bu yolla kullanarak olduka kolay sinyal elde ettik. Esasen 500mslik zaman dilimi 1 ve 0 olmas aslnda sinyalimizin 1Hzlik olduunu gsterir, bunu da proteus dosyamza koyduumuz frekansmetre ile grebiliriz. Yine de oluturduumuz sinyal grltler ve scaklk gibi d etkenler yznden deiebileceinden rettiimiz sinyal tam anlamyla verimli olmayabilir bu yzden genel itibari ile saat devrelerinde kullanlmamas tavsiye edilir.
FxDev.org Sayfa 20

imdi de Timer 0 iin d kayna kullanarak, 5 kere butona bastmzda 4 ledin srasyla yanmasn salayalm. Bunun iin ncelikle aadaki devreyi Proteusta izelim.

ekil 150 - Timer 0 Uygulamas - 2

Grdnz gibi buton yapmz den kenara gre setim. Bunu gz nne alarak yazamz C kodu aadaki gibi olacaktr.
#include <htc.h> void main(void) { ADCON1=0x07; TRISA=0x10; TRISB=0x00; PORTA=0x00; PORTB=0x00; TMR0=-5; T0SE=0; T0CS=1; PSA=1; PS2=0; PS1=0; PS0=0; T0IF=0; T0IE=1; GIE=1; for(;;); } static void interrupt isim(void) { char i; if(TMR0IF) // Kesme fonksiyonu // Kesme fonksiyon ismi (nemsiz) // Deikenler tanmlanyor // TMR0 kesmesi olumu mu // Ana fonksiyon alan // // // // // // // // // // PORTA dijital yaplyor RA4 giri yaplyor PORTB k olarak ayarlanyor PORTA sfrlanyor PORTB sfrlanyor Esasen 250 yklenmi oluyor Den kenar tetikleme Harici osilatr Prescaler TMR0 iin 1:1 blm deeri

// TMR0 kesme bayra temizleniyor // TMR0 kesmesine izin veriliyor // Genel kesme izni veriliyor // lemci sonsuz dngde bekletiliyor

FxDev.org

Sayfa 21

{ i++; if(i==16) i=0; PORTB=i; TMR0=-5; TMR0IF=0; bayra temizleniyor } } // PORTB'de gzkecek deer // Deiken 16 olursa onu tekrar 0 yap // Deiken deeri PORTB'ye yanstlyor // Esasen 250 yklenmi oluyor // Tekrar d kesme alnabilmesi iin kesme

Grld zere dardan elle verdiimiz sinyalde dahi picin kolayca alt gzkmekte. Ayrca Timer deikenlerine negatif(-) atamalarn yaplabilecei de grlebilir. 2.3.2) Timer 1 Birimi

ekil 161 - Timer1 Birimi

ekil-21de gzken timer birimi olduka fonksiyonel bir yapdr. 16bitlik olmas 0dan 65535e kadar saym yapabilmeye olanak salar. Dahili ve harici saat girii seimiyle istenilen uygulamalarda kullanlabilinir. Timer 1i kontrol eden kaydediciler ve grevleri yledir; T1CKPS1, T1CKPS0 T1OSCEN TMR1CS T1SYNC TMR1ON TMR1H TMR1L TMR1IE TMR1IF : Prescalar deeridir, (1:1, 1:2, 1:4, 1:8) : Timer1 osilatr kontrol biti (0: Kapal, 1: Ak) : Saat kayna seme biti (0: Dahili, 1: Harici) : Senkronizasyon biti (1: Senk. Yok, 0: Senk. Var) : Timer1 ama kapama biti (0: Kapal, 1: Ak) : Timer1 saycsnn yksek deerlikli bitini tutan kaydedici : Timer1 saycsnn dk deerlikli bitini tutan kaydedici : Timer1 kesme izin biti : Timer1 kesme bayrak biti

FxDev.org

Sayfa 22

Timer 1e zel d kaynakl saat frekans alnmak istenirse gerekli pinlere dk gl kristaller balanr. Bu kristal deerlerinden en ideali 32Khz olandr ve 33pf ile srlr. imdiki uygulamamzda Timer 1 ile bir saniyede bir yanp snen led uygulamas yapalm. ncelikle ekil-22deki proteus devresini oluturup, hesaplamalarmz yapalm.

ekil 22 - Timer 1 Uygulamas

imdi hesaplamamz yapacak olursak. 4Mhzlik kristal kullandmz ve picin bunu 4e blerek kullandn dnrsek bize 1mikrosaniyelik bir gecikme yaratacaktr. 1.000.000 saym iin Timer 1in ncelikle 50.000e kadar saydracamz dnrsek; 1.000.000/50.000=20 deeri kar. Prescaler orann 1:4 seersek her 5 kesmede bir deer artrm bize istediimiz gecikme olan 1 saniyeyi salayacaktr. Bunu yapan C kodu aada grlmektedir.
#include <htc.h> void main(void) { TRISB=0x00; PORTB=0x00; TMR1H=-50000/256; TMR1L=-50000%256; TMR1CS=0; T1CKPS1=1; T1CKPS0=0; T1SYNC=1; TMR1IF=0; TMR1IE=1; TMR1ON=1; PEIE=1; GIE=1; // Ana fonksiyon alan // PORTB k olarak ayarlanyor // PORTB sfrlanyor // TMR1'e 65536-50000 ykleniyor. // Dahili osilatr // Prescaler 1:4 oluyor // // // // // // Senkronizasyon yok TMR1 kesme bayra temizleniyor TMR1 kesmesine izin veriliyor TMR1 altrlyor Yardmc kesme izni veriliyor Genel kesme izni veriliyor

FxDev.org

Sayfa 23

for(;;); }

// lemci sonsuz dngde bekletiliyor

static void interrupt // Kesme fonksiyonu isim(void) // Kesme fonksiyon ismi (nemsiz) { char i; // Deikenler tanmlanyor if(TMR1IF) // TMR1 kesmesi olumu mu { i++; // Deiken 1 artrlyor if(i<5) // Deiken 5 olursa led yansn { RB0=1; } else if(i>5) // Deiken 5'ten byk olursa led snsn { RB0=0; } if(i==10) // 2 saniye olduunda deiken sfrlansn i=0; TMR1H=-50000/256; // TMR1'e 65536-50000 ykleniyor. TMR1L=-50000%256; TMR1IF=0; // Tekrar d kesme alnabilmesi iin kesme bayra temizleniyor } }

Kodlarda grld zere -50000 deeri TMR1 kaydedicisine aslnda 15535 deeri yklemektedir. PEIE ise yardmc kesme izin bitidir. 2.3.3) Timer 2 Birimi

ekil 23 - Timer 2 Birimi

Timer 2 birimi 16f877ada bir ok grevde kullanlan zel bir Timerdr. zellikle kullanm amac PWM retmek olan Timer 2, Timer 0 gibi 8 bitliktir. Blme deerleri olduka genitir. Timer 2yi kontrol eden kaydediciler aada sralanmtr;

FxDev.org

Sayfa 24

TMR2=PR2 : Timer2 saycsnn yksek deerlikli bitini tutan kaydedici TOUTPS3, TOUTPS2, TOUTPS1, TOUTPS0 : Postscale deerler, ekil-24e baknz. TMR2ON : Timer2 saycsn ama biti T2CKPS1, T2CKPS0 : Prescaler deerler (1:1, 1:4, 1:16) TMR2IE : Timer2 kesme izin biti TMR2IF : Timer2 kesme bayrak biti

ekil 24 - Prescale Deerler

Timer 2 birimindeki uygulamamzda Timer2 kesmesi ile bir deikeni artrp, deiken deerinin PORTBye bal ledlere istediimiz zaman yansmasn yapacaz. Bunun iin ncelikle aadaki devreyi Proteusta kuruyoruz.

ekil 25 - Timer 2 Uygulamas

FxDev.org

Sayfa 25

Timer 2 saycs iin Poscalei 1:16, Postscaleri 1:16, PR2yi de 250 yapyoruz. Bu deerleri saladmzda yaklak her 0.064 saniyede bir kesme elde ederiz. Butona bastmzda ise anlk saym deerini ledlerde gzlemleyebilir, butona basl tuttuumuzda ise deiim ann gzleyebiliriz. Bu ilemi yapan C kodu aadadr.
#include <htc.h> char i; // Genel deiken tanmlanyor // Ana fonksiyon alan // // // // // PORTA dijital yaplyor RA0 giri PORTB k olarak ayarlanyor PORTA sfrlanyor PORTB sfrlanyor

void main(void) { ADCON1=0x07; TRISA=0x01; TRISB=0x00; PORTA=0x00; PORTB=0x00; PR2=250; T2CKPS1=1; T2CKPS0=1; TOUTPS3=1; TOUTPS2=1; TOUTPS1=1; TOUTPS0=1; TMR2IF=0; TMR2IE=1; TMR2ON=1; PEIE=1; GIE=1;

// PR2 deerine 250 ykleniyor // Prescaler 1:16 oluyor // Prescale 1:16 oluyor

// // // // //

TMR1 kesme bayra temizleniyor TMR1 kesmesine izin veriliyor TMR1 altrlyor Yardmc kesme izni veriliyor Genel kesme izni veriliyor

for(;;) { if(RA0) PORTB=i; } } static void interrupt isim(void) { if(TMR2IF) { i++; TMR2IF=0; bayra temizleniyor } }

// Butona basld m // Deikenin deeri PORTB'ye yanstlyor

// Kesme fonksiyonu // Kesme fonksiyon ismi (nemsiz) // TMR2 kesmesi olumu mu // Deiken 1 artrlyor // Tekrar d kesme alnabilmesi iin kesme

Grld zere Timer 2 birimini de kullanmak Hi-Tech altnda olduka kolay. Bu blmde Interrupt ve Timer ilemlerini irdeledik, zellikle register (kaydedici) birimlerin bitlerinin ak halde kullanlmas, kodlar uzatyor gibi gzkse de deerleri kartrmamak adna olduka faydaldr.

FxDev.org

Sayfa 26

BLM 3 CAPTURE/COMPARE/PWM ve TU TAKIMI LEMLER


3.1) Hi-Techte CCP lemleri Pic ierisinde dahili olarak bulunan CCP modl Copture (yakalama), Compare (karlatrma) ve PWM blmlerinin ba harflerinin bir araya gelmesinden oluur. Pic 16f877ann iinde 2 adet CCP modl bulunmaktadr. CCP iin kullanlan kaydedici ekil-26da grlecei zere 16 bitliktir. CCPRx kaydedicisi Timer 1in kaydedicisi ile ortak alarak Capture ve Compare ilemlerinde kullanlabilir.

ekil 26 CCP Kaydedicileri

Genel itibari ile CCP ilemleri CCPxCON registeriyle kontrol edilir. x ifadesi bu blmde kullanlan birime gre 1 ya da 2 olabilir. CCPxCON registerinin yaps ve grevi ekil-27de gzkmektedir.

ekil 27 CCPxCON Kaydedicisi

ekil-27de verilen kaydedicinin bit bit grevleri ise yledfir; CCPxX, CCPxY CCPxM3, CCPxM2, CCPxM1, CCPxM0 : PWM dk deerlikli bitleri. Yksek deerlikli 8 bit ise CCPRxL kaydedicisinde bulunur. : CCP mod seme bitleri. Modlarn ne olacaklar aadaki tabloda gsterilmitir.

0000 0100 0101 0110 0111 1000 1001 1010 1011 11xx

: CCP etkin deil : Capture modu, her den kenarda : Capture modu, her ykselen kenarda : Capture modu, her 4. ykselen kenarda : Capture modu, her 16. ykselen kenarda : Compare modu, denklik durumunda CCPx pini 1 olsun, CCPxIF bayra ekilsin : Compare modu, denklik durumunda CCPx pini 0 olsun, CCPxIF bayra ekilsin : Compare modu, denklik durumunda CCPx pini deimesin, CCPxIF bayra ekilsin : Compare modu, denklik durumunda CCPx pini deimesin, CCPxIF bayra ekilsin, timer 1 resetlensin ve ADC balasn : PWM modu

FxDev.org

Sayfa 27

3.1.1) Capture Modu Pic ierisinde bulunan Capture birimi ekil-28den de grlecei zere Timer 1 ile ortak alr. Capture biriminin grevi yakalama yapmaktr. Modlarna gre her den, ykselen, 4. veya 16. ykselen kenarda yakalama yaparak ne kadar sre getiyse, geen sreyi Timer 1 zamanlaycsndan alarak CCP biriminin zel kaydedicilerine ykler. Daha sonra CCP birimine kaydedilen zamanlar okunarak gerekli ilemler yaplr.

ekil 28 Capture Blm

Capture birimini kullanmak iin ncelikle Timer 1 ve CCP birimi ayarlar yaplr. Kesmeden yararlanlacaksa CCPxIE ve CCPxIF birimleri set edilir veya temizlenir. Capture uygulamamzda CCP1in her ykselen kenar yakalamasnda bir deikeni artrmas, CCP2nin ise her 4. ykselen kenar yakalamasnda yine ayn deikeni bir azaltmas ve bu deikenin PORTBden grlmesi amalanmtr. ncelikle uygulamamzla ilgili aadaki ekil-29daki Proteus devremizi iziyoruz.

ekil 29 Capture Uygulamas

FxDev.org

Sayfa 28

Devremizi kurduktan sonra Hi-Techte kodumuzu yazalm.


#include <htc.h> char i; void main(void) { TRISB=0x00; TRISC=0x06; PORTB=0x00; PORTC=0x00; CCP1M0=1; CCP1M1=0; CCP1M2=1; CCP1M3=0; CCP2M0=0; CCP2M1=1; CCP2M2=1; CCP2M3=0; CCP1IF=0; CCP2IF=0; CCP1IE=1; CCP2IE=1; PEIE=1; GIE=1; for(;;); } static void interrupt isim(void) { if(CCP1IF) { i++; PORTB=i; CCP1IF=0; } if(CCP2IF) { i--; PORTB=i; CCP2IF=0; } } // CCP2 kesmesi varsa // Deiken bir azaltlyor // Deiken deeri PORTB'ye yanstlyor // Yeni CCP2 kesmesi iin bayrak temizleniyor // Kesme fonksiyonu // Kesme fonksiyon ismi (nemsiz) // CCP1 kesmesi varsa // Deiken bir artrlyor // Deiken deeri PORTB'ye yanstlyor // Yeni CCP1 kesmesi iin bayrak temizleniyor // Genel deiken tanmlanyor // Ana fonksiyon alan // // // // PORTB k olarak ayarlanyor CCP1 ve CCP2 giri PORTB sfrlanyor PORTC sfrlanyor

// CCP1 her ykselen kenar modunda

// CCP1 her 4. ykselen kenar modunda

// CCP1 ve CCP2 kesme bayraklar temizleniyor // CCP1 ve CCP2 kesme izinleri veriliyor // Yardmc kesme izni veriliyor // Genel kesme izni veriliyor

Yukarda grld gibi genel kesme fonksiyonun iinde birden ok kesme bayra kontrol yaplabilir.

FxDev.org

Sayfa 29

3.1.2) Compare Modu Compare modu pic ierisinde karlatrma ilemlerinde kullanlan birimdir. ekil-30dan da grlecei zere Timer1 ile ortaklaa alrlar. Genel itibariyle alma mant yledir; - ncelikle Timer1 ve Compare modu ayarlar yaplr, - CCPRxH ve CCPRxL kaydedicilerine yakalanmak istenen say yklenir, - Genellikle Timer1 harici kaynak beslemesi kullanlr - TMR1 kaydedicisi ile CCPRx kaydedicisi birbirine eit olduunda kesme bayra set edilir.

ekil 30 Compare Birimi

Compare uygulamamzda CCP1 birimine 500 yklenerek dahili Timer1 birimi deeri saylarak CCP1 eitliinde RB0a bal ledin yanp snmesi salanacaktr. Bu uygulama iin ncelikle ekil-31deki devreyi iziyoruz.

ekil 31 Compare Uygulamas

FxDev.org

Sayfa 30

ekildeki devreyi altran C kodu ise aadaki gibidir;


#include <htc.h> void main(void) { TRISB=0x00; PORTB=0x00; TMR1CS=0; T1SYNC=0; TMR1ON=1; CCP1M0=1; CCP1M1=1; CCP1M2=0; CCP1M3=1; CCPR1H=500/256; CCPR1L=500%256; CCP1IF=0; CCP1IE=1; PEIE=1; GIE=1; for(;;); } static void interrupt // isim(void) // { char i,j; // if(CCP1IF) // { i++; // if(i==1) // RB0=1; else if(i==2) { RB0=0; i=0; } CCP1IF=0; } } Kesme fonksiyonu Kesme fonksiyon ismi (nemsiz) Deikenler tanmlanyor CCP1 kesmesi varsa Deiken bir artrlyor Deiken 1 ise RB0=1 olur // Deiken 2 ise RB0=0 olur // Ana fonksiyon alan // PORTB k olarak ayarlanyor // PORTB sfrlanyor // Timer1 Harici kaynaktan besleniyor // Senkronizasyon yok // Timer1 alyor // CCP1 compare modunda, timer1 resetlenecek

// 500'e eitlenecek // // // // CCP1 ve CCP2 kesme bayraklar temizleniyor CCP1 ve CCP2 kesme izinleri veriliyor Yardmc kesme izni veriliyor Genel kesme izni veriliyor

// Yeni CCP1 kesmesi iin bayrak temizleniyor

Esasen kurulan devre 1000Hzlik sinyal oluturacaktr. Bu deeri ekil-31de bulunan frekansmetreden grebilirsiniz.

FxDev.org

Sayfa 31

3.1.3) PWM Modu PWM, Pulse Width Modulationn ksaltmasdr. 16f877ada iki adet PWM modl bulunmaktadr. ekil-32de grld zere PWM modl Timer 2 ile ortaklaa almaktadr.

ekil 32 PWM Birimi

Pic ile PWM sinyalini retmek iin aadaki admlar izlenir; - PWM periyodunu ayarlayarak PR2 deerine yazlr, - PWM Duty Cycle CCPRxL ve CCPxCON<5:4>e yazlr, - CCPx output yaplr, - Timer 2 prescale oran belirlenir ve Timer 2 altrlr, - CCPx modl PWM olarak ayarlanr.

ekil 33 PWM Periyodu ve Doluluk Oran

FxDev.org

Sayfa 32

Burada nemli olan bir dier faktrde ekil-33te gzken PWM periyodu ve doluluk orandr. Bu oranlar aadaki matematiksel ilemler izlenerek hesaplanr ve ilgili kaydedicilere yklenirler. PWM Periyodu=*(PR2)+1+.4.Tosc.*TMR2 Prescale Deeri+ PWM Duty Cycle=*CCPRxL:CCPxCON<5:4>+.Tosc.*TMR2 Prescale Deeri+ PWM sinyali aadaki admlarda oluur; - TMR2, PR2ye eit olduunda TMR2 temizlenir, - CCPx pini set edilir (Duty cycle=%0 ise set edilmez), - CCPRxLden CCPRxHa ykleme gerekleir. - Duty cycle, PWM periyodundan byk olamaz. PWM znrl ise aadaki formlle hesaplanr;

PWM uygulamamzda picin CCP1 birimindeki PWM kullanarak, duty cycle deitirmeden, sadece periyodu deitirerek buzzer sayesinde sesin nasl deitiini grelim. Duty Cycle periyodunu 1ms kabul edelim. PWM periyodunu ise iki butonla artrp azaltalm. ncelikle bu uygulama iin ekil-34teki devreyi izelim.

ekil 34 PWM Uygulamas

FxDev.org

Sayfa 33

stediimiz ilemi yapan Hi-Tech kodu ise aadaki gibi olacaktr.


#include <htc.h> void main(void) { char i=100; ADCON1=0x07; TRISA=0x03; TRISC=0x00; PORTA=0x00; PORTC=0x00; CCPR1L=0x3E; CCP1X=1; CCP1Y=0; T2CKPS1=1; T2CKPS0=1; TOUTPS3=0; TOUTPS2=0; TOUTPS1=0; TOUTPS0=0; CCP1M0=1; CCP1M1=1; CCP1M2=1; CCP1M3=1; TMR2ON=1; // Ana fonksiyon alan // // // // // PORTA dijital oluyor RA0 ve RA1 giri PORTC k olarak ayarlanyor PORTA sfrlanyor PORTC sfrlanyor

// Duty registere 250 ykleniyor // Duty cycle 1ms periyodunda // Prescaler 1:16 oluyor // Postscale 1:1 oluyor

// CCP1 PWM modunda

// Timer 2 altrlyor

for(;;) { if(RA0) // Azalt butonuna baslm m { while(RA0); // Butondan elin ekilmesi bekleniyor i-=5; // PR2 birimi 5 azaltlyor if(i<65) // Deiken 65'ten kkse i=65; // Tekrar 65'e eit olsun } if(RA1) // Artr butonuna baslm m { while(RA1); // Butondan elin ekilmesi bekleniyor i+=5; if(i>250) // Deiken 250'den btkse i=250; // Tekrar 250'ye eit olsun } PR2=i; // Deiken PR2'ye eitleniyor } }

lemler kark gibi grnse de aslnda tm i Duty Cycle ve PWM periyodunu ayarlamaktadr. Bu i iin internette gelitirilen birok program bulabilirsiniz.

FxDev.org

Sayfa 34

3.2) Tu Takm Uygulamas Dardan bilgi girmek iin en ok kullanlan ve ekil-35te gzken keypad, esasen belirli ekillerde oluturulmu pull-up butonlardan oluur.

ekil 35 4x4 Keypad

Bu blmde keypadi kullanmak iin tarama yntemini irdeleyeceiz. Uygulamamzda D portuna balanm, ak emas bulunan keypadin tarama yntemiyle srlp, B portuna bal ledlere hangi butonun basld yanstlacaktr. Bunun iin ncelikle ekil-36daki devreyi iziyoruz.

ekil 36 4x4 Keypad Uygulamas - 1

Grld zere ak devresi grlen keypadin aslnda normal pull-up butonlarndan fark yoktur. stediimiz ilemi yapan Hi-Tech kodu ise aadaki gibi olacaktr.

FxDev.org

Sayfa 35

#include <htc.h> #include <delay.h> #define #define #define #define #define #define #define #define sut1 sut2 sut3 sut4 sat1 sat2 sat3 sat4 RD0 RD1 RD2 RD3 RD4 RD5 RD6 RD7

// Gecikme fonksiyonu // // // // // // // // sut1 sut2 sut3 sut3 sat1 sat2 sat3 sat4 ifadesi ifadesi ifadesi ifadesi ifadesi ifadesi ifadesi ifadesi RD0 RD1 RD2 RD3 RD4 RD5 RD6 RD7 ifadesine ifadesine ifadesine ifadesine ifadesine ifadesine ifadesine ifadesine eitleniyor eitleniyor eitleniyor eitleniyor eitleniyor eitleniyor eitleniyor eitleniyor

char keypad_oku(void) // Fonksiyon ismi { char tus=0; PORTD=0x00; // D portu k sfrlanyor sat1=1; // 1. satr lojik-1 yaplyor if(sut1) // 1. stun okunuyor { DelayMs(20); tus=1; } if(sut2) // 2. stun okunuyor { DelayMs(20); tus=2; } if(sut3) // 3. stun okunuyor { DelayMs(20); tus=3; } if(sut4) // 4. stun okunuyor { DelayMs(20); tus=0x0A; } sat1=0; // 1. satr lojik-0 yaplyor sat2=1; // 2. satr lojik-1 yaplyor if(sut1) // 1. stun okunuyor { DelayMs(20); tus=4; } if(sut2) // 2. stun okunuyor { DelayMs(20); tus=5; } if(sut3) // 3. stun okunuyor { DelayMs(20); tus=6; } if(sut4) // 4. stun okunuyor { DelayMs(20); tus=0x0B; } sat2=0; // 2. satr lojik-0 yaplyor

FxDev.org

Sayfa 36

sat3=1; // 3. satr if(sut1) // 1. stun { DelayMs(20); tus=7; } if(sut2) // 2. stun { DelayMs(20); tus=8; } if(sut3) // 3. stun { DelayMs(20); tus=9; } if(sut4) // 4. stun { DelayMs(20); tus=0x0C; } sat3=0; // 3. satr sat4=1; // 4. satr if(sut1) // 1. stun { DelayMs(20); tus=0x0E; } if(sut2) // 2. stun { DelayMs(20); tus=0; } if(sut3) // 3. stun { DelayMs(20); tus=0x0F; } if(sut4) // 4. stun { DelayMs(20); tus=0x0D; } sat4=0; // 4. satr

lojik-1 yaplyor okunuyor

okunuyor

okunuyor

okunuyor

lojik-0 yaplyor lojik-1 yaplyor okunuyor

okunuyor

okunuyor

okunuyor

lojik-0 yaplyor

return tus; // Fonksiyon "tus" deeri ile geri dner } void main(void) // Ana fonksiyon alan { TRISB=0x00; TRISD=0x0F; PORTB=0x00; PORTD=0x00; for(;;) { PORTB=keypad_oku(); } }

FxDev.org

Sayfa 37

Grld zere tarama metodu zellikle byk projelerde sorun yaratacak dzeyde uzundur. Tarama ilemini 2. blmde grdmz Timer0 kesmesiyle yaparak, programsal adan srekli kontrol ilemini gereksiz hale getirip, projenize etkinlik kazandrabilirsiniz.

BLM 4 KAREKTER LCD ve ADC LEMLER


4.1) Hi-Techte Karekter LCD lemleri ekil-37de bir rnei grlen karakter LCDler darya bilgi aktarmak iin kullanlan en yaygn birimlerdendir. Genel itibari ile Hitachi firmasnn HD44780 entegresini ve trevlerini tayan karakter LCDler eitli metotlarla srlrler. Biz bu blmde ekil-37de de grlebilecek 2x16 yani 2 satr ve her satrda 16 karakter yazabilen karakter LCDleri inceleyeceiz.

ekil 37 2x16 Karekter LCD

Karakter LCDlerin genelinde her harf ekil-38de grlecei gibi 5x7lik birimler halinde ekillenirler. Altta bo kalan son birim ise imle iindir.

ekil 38 5x7 Karekter Oluumu

LCD birimi genellikle normal entegre g biriminden ayr bir de arka aydnlatma gc verilerek kullanlrlar. Bu birimin nasl srlecei ise ekil-39de gzkmektedir.

ekil 39 LCD G Balants

FxDev.org

Sayfa 38

Karakter LCDlerin oluturabilecei her bir karakter ise karakter LCDnin zel CGROM hafzasna kaydedilmilerdir. ASCII karakter uyumu olan karakterlerin listesi ekil-40da grlebilmektedir.

ekil 40 LCD Karakter Tablosu

ekil-40da da grlecei zere CGROMun ilk 8 karakterlik (0x00..0x0F) ksm botur ve yazlabilirdir. Bu kullancya tabloda olmayan karakterleri kendisi tanmlamasna olanak salar. Karakter LCDlerin genelin 16 bacak bulunur. Bunlarn 14 tanesi LCDyi kontrol etmek amal kullanlrken, 15 ve 16. bacaklar genellikle LCD arka iin kullanlrlar. LCD arka yazlarn daha belirgin gzkmesi iin gereklidir.

FxDev.org

Sayfa 39

Bu bacaklarn grevini srasyla verecek olursak; 1 - GND : Toprak ucudur 2 - VCC : +5V verilecek utur 3 - VEE : Kontrast ucudur, bir pot vastasyla +5V-0V aralnda srlmelidir 4 - RS : Gelen bilginin komut mu data m olduu bu ula belirlenir (0: Komut, 1: Data) 5 - RW : LCDye veri yazma ya da okuma yetkilendirme ucudur (0: Yazma, 1: Okuma) 6-E : Enable ucudur, LCDye bilgi giri kn kontrol eden utur, den kenar tetiklemelidir 7..14 - Data : Data ulardr, bilgi giri klar bu bacaklar sayesinde olur 15,16 - BL : Backlight anot, katot uardr Karakter LCDlerin kullanlmas, led, diren srm gibi olmamaktadr. Karakter LCD kullanmnda, enerjiyi ilk verdiimiz anda karakter LCDyi nasl kullanmak istediimizi LCDye belirli kurallar erevesinde iletmemiz gerekmektedir. Biz ekil-41deki metodu kullanarak karakter LCDmizi altracaz.

ekil 41 LCD Karakter Tablosu

Bu metot LCD srmede klasik haline gelmitir. ekil-41de grlen balantda bilgi gnderimi 8 bitlik veriler yerine 4 bitlik veriler halinde iki kez gnderilerek yaplmaktadr. Bylelikle bize mikro denetleyicide 4 bacak kazanm salarken, karakter yazm hznda ise 2 kat yavalamaya neden olmaktadr. Fakat bu, ok komplike ilemler yaplmadktan sonra gzle grlr bir yavalamaya neden olmamaktadr. Ayrca biz ilemlerimizde karakter LCDye sadece yazm yapacamz iin RW bacan direk toprak hattna balayabilir, toplamda 6 mikro denetleyici baca kullanarak LCDmizi altrabiliriz.

FxDev.org

Sayfa 40

Bunlar gz nne alnarak yaplacak ilk n yklemede aadaki ilk ykleme bilgileri seilmeli ve karakter LCDye gnderilmelidir. Bu bilgiler karakter LCD datasheetinden bire bir alnmtr. 1) Display sfrlanmal : Bunun iin LCDye 0x02 veya 0x03 gnderilip 2ms beklenir 2) Display silinmeli : Bunun iin LDDye 0x01 gnderilip 1ms beklenilmeli 3) Fonksiyon ayar yaplmal : 4 bitlik iletiim 5x7 karakter kullanacamzdan 0x28 gnderilip 40us beklenilmeli 4) Giri modu ayarlanmal : mle her karakterden sonra saa kayacandan 0x06 gnderilip 40us beklenilmeli 5) mle ayar : Display kapal uygulama yapacamzdan 0x0B gnderilir 4.1.1) LCD Ktphanesini Oluturmak Cnin en byk avantajlarndan birisi kendi ktphanelerimizi oluturabilmek ve bunlar istediimiz zaman kullanabilmektir. Ktphane oluturmada .h ve .c uzantl iki dosya oluturmamz gerekmektedir. .h uzantl dosya, .c uzantl dosyada tanmlayacamz fonksiyon isimlerini ierirken, .c uzantl dosya da ise kullanacamz fonksiyonlarn ilevleri yer almaldr. Biz oluturacamz LCDde istenildii an imlecin gzkp, kapatlmas, LCDnin temizlenmesi gibi ilemlerin hepsini yapabilmek iin tm komutlarn numaralarn yazacamz C ktphanesine koyacaz. ncelikle lcd.h dosyamz proje klasrmzde oluturalm, bunu yapann en kolay yolu bo bir metin dosyas oluturup sonundaki .txt uzantsn .h eklinde deitirmektir. Daha sonra Hi-Tech altnda blm 1de anlatlan refresh ilemi gerekletirildikten sonra bo lcd.h dosyas karmza kacaktr. lcd.h balk dosyamz aadaki ekilde oluturalm.
/* * * * * * * * * * * */ www.FxDev.org D4,D5,D6,D7 pinlerini kullanarak 4 bit iletiim kullanr. Cursor kapaldr. RW kullanlmad iin direk topraa balanabilir. 2x16 LCD Kullanm Klavuzu lcd_init(); ile LCD'nin ilk ayarlarn yap lcd_clear(); ile LCD'yi sil lcd_yaz("deneme"); eklinde yaz yazdr. veri_yolla('F'); eklinde tek ascii kodu yazdr. lcd_gotoxy(1,13); eklinde LCD'nin istenilen yerine git. www.FxDev.org rs RC0 rw RC1 e RC2 lcd_port //Pin tanmlamalar PORTB

#define #define #define #define

/* LCD'de kullanilan komutlarin tanimlamasi*/ #define Sil 1 // Ekrani temizler #define BasaDon 2 // Imleci sol st kseye getirir #define SolaYaz 4 // Imlecin belirttigi adres azalarak gider #define SagaYaz 6 // Imlecin belirttigi adres artarak gider #define ImlecGizle 12 // Gstergeyi ac, kursor grnmesin #define ImlecAltta 14 // Yanip snen blok kursor #define ImlecYanSon 15 // Yanip snen blok kursor

FxDev.org

Sayfa 41

#define #define #define #define #define

// Kursoru bir karakter geri kaydr // Gstergeyi bir karakter saa kaydr // Gstergeyi bir karakter sola kaydr // Gstergeyi kapat (veriler silinmez) // LCD'nin ilk satir balang adresi // (DDRAM adres) #define IkinciSatir 192 // kinci satirin balang adresi #define KarakUretAdres 64 // Karakter reteci adresini belirle // (CGRAM adres) /* LCD'de Kullanilan Fonksiyon Seimi */ #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 extern extern extern extern extern void void void void void void veri_yolla(unsigned char); lcd_clear(void); lcd_yaz(const char *s); lcd_gotoxy(unsigned char x, unsigned char y); lcd_init(void); lcd_komut(unsigned char c);

ImlecGeri KaydirSaga KaydirSola EkraniKapat BirinciSatir

16 24 28 8 128

ekildeki kodlarn ne ie yaradklar yanlarndaki aklamalarda bulunmaktadr. Bu kodlar lcd.h iine koyduktan sonra kaydedelim. Kullanm klavuzunda da belirtildii gibi bacaklarn nasl balanaca da lcd.h dosyasnda belirlenmektedir. Daha sonra grld zere extern uzantl fonksiyonlarn ne ie yaradklarn aklayan lcd.c dosyamz aynen yukarda anlatlan yeni metin dosyas metoduyla yarattktan sonra aadaki kodlar iine kaydedelim.
#include #include #include <pic.h> "lcd.h" "delay.h" // lcd.h dosyas tanmlanp, deerler alnyor // Gecikme fonksiyonu tanmlanyor

void lcd_busy(void) { DelayUs(250); } void lcd_komut(unsigned char c) // Komut gnderme fonksiyonu { rw=0; // LCD'ye yazma yaplacak rs=0; // LCD'ye komut gnderilecek e=1; // Den kenar tetikleme olduu iin E nce 1 lcd_port = ( c & 0xF0 ); // Yksek deerlikli bitler gnderiliyor e=0; // E, 0 yaplyor lcd_busy(); //Belirli sre bekleniyor e=1; // E, 1 yaplyor lcd_port = ( (c & 0x0F)<<4 ); // Dk deerlikli bitler gnderiliyor e=0; // E, 0 yaplyor lcd_busy(); // Belirli bir sre bekleniyor } void veri_yolla(unsigned char c) { rw=0; rs=1; // Komut yolladan tek fark, RS'nin 1 olmas

FxDev.org

Sayfa 42

e=1; lcd_port = ( c & 0xF0 ); e=0; lcd_busy(); e=1; lcd_port = ( (c & 0x0F)<<4 ); e=0; lcd_busy(); } void lcd_clear(void) { lcd_komut(0x1); DelayMs(2); } // LCD siliniyor

void lcd_yaz(const char * s) // LCD'ye string ifade gnderiliyor { lcd_busy(); while(*s) veri_yolla(*s++); } void lcd_gotoxy(unsigned char x,unsigned char y) //LCD'nin belli //blgesine gidiliyor { if(x==1) lcd_komut(0x80+((y-1)%16)); else lcd_komut(0xC0+((y-1)%16)); } void lcd_init() { rs = 0; e = 0; rw = 0; DelayMs(15); e=1; lcd_komut(0x02); DelayMs(2); lcd_komut(CiftSatir4Bit); lcd_komut(SagaYaz); lcd_komut(ImlecGizle); lcd_clear(); lcd_komut(BirinciSatir); } // LCD ilk ykleme ayarlar yaplyor

lcd.c dosyamz da kaydettikten sonra artk yapmamz gereken tek ey bunu ana proje dosyamz olan main.cde ktphane olarak tanmlayarak kullanmaktr. nemli Not: Sonraki konularda ska kullanlacak olan LCD ktphanesi bu olacaktr. Projelerimize lcd.h dosyasn eklediimizde, esasen eklenen ktphane, bu oluturduumuz ktphane olacaktr.

FxDev.org

Sayfa 43

4.1.2) lk LCD Uygulamamz LCD ktphanelerimizi oluturduktan sonra ilk denememize geelim. lk uygulamamzda LCDye admz soyadmz ve ikinci satra da tm rakamlar yazalm. ncelikle ekil-42deki devremizi lcd.h ktphanesinde tanmladmz bacaklara dikkat ederek kuralm. Devreyi altrdmzda LCDnin nasl gzkecei de ekil-42de gzkmektedir.

ekil 42 LCD Karakter Uygulamas

Bu ilemi yapan Hi-Tech kodu ise aada grld zere olduka sadedir.
#include <htc.h> #include <delay.h> #include "lcd.h" void main(void) { TRISB=0x00; TRISC=0x00; PORTB=0x00; PORTC=0x00; lcd_init(); // Gecikme ktphanesi // LCD ktphanesi tanmlanyor // Ana fonksiyon alan // LCD'ye bal portlar k yaplyor

// LCD ilk ayarlar yaplyor // // // // lk satra isim yazlyor kinci satra geiliyor Rakamlar yazlyor Sonsuz dngye giriliyor

lcd_yaz(" FIRAT DEVECI"); lcd_gotoxy(2,1); lcd_yaz(" 1234567890"); for(;;); }

FxDev.org

Sayfa 44

lcd.h dosyasnn lcd.h eklinde tanmlanmasnn nedeni, ktphanenin proje klasrnde olmasndandr. Son olarak sonsuz dngye girilmesinin nedeni ise srekli ekilde LCDye yazm engellemektir. Grld zere ktphane kullanmak, ana kodumuzu olduka ksaltmaktadr. 4.1.3) Tu Takm ve LCD Uygulamas Bu uygulamamzda 3. blmde grdmz keypad ile LCD uygulamasn birletirelim. Tarama metodunu kullanarak LCDde bastmz tuun gzkmesini salayalm. Bunun iin uygulama ann da grebileceiniz ekil-43teki devreyi izelim.

ekil 43 Tu Takm ve LCD Karakter Uygulamas

Bu devreyi altracak olan Hi-Tech kodu ise aadaki gibidir.


#include <htc.h> #include <delay.h> #include "lcd.h" #define #define #define #define #define #define #define #define sut1 sut2 sut3 sut4 sat1 sat2 sat3 sat4 RD0 RD1 RD2 RD3 RD4 RD5 RD6 RD7 // Gecikme ktphanesi tanmlanyor // LCD ktphanesi tanmlanyor // // // // // // // // sut1 sut2 sut3 sut3 ifadesi ifadesi ifadesi ifadesi RD0 RD1 RD2 RD3 ifadesine ifadesine ifadesine ifadesine eitleniyor eitleniyor eitleniyor eitleniyor

sat1 sat2 sat3 sat4

ifadesi ifadesi ifadesi ifadesi

RD4 RD5 RD6 RD7

ifadesine ifadesine ifadesine ifadesine

eitleniyor eitleniyor eitleniyor eitleniyor

char keypad_oku(void) // Fonksiyon ismi { char tus=0; PORTD=0x00; // D portu k sfrlanyor

FxDev.org

Sayfa 45

sat1=1; // 1. satr if(sut1) // 1. stun { DelayMs(20); tus=1; } if(sut2) // 2. stun { DelayMs(20); tus=2; } if(sut3) // 3. stun { DelayMs(20); tus=3; } if(sut4) // 4. stun { DelayMs(20); tus=0x0A; } sat1=0; // 1. satr

lojik-1 yaplyor okunuyor

okunuyor

okunuyor

okunuyor

lojik-0 yaplyor

sat2=1; // 2. satr lojik-1 yaplyor if(sut1) // 1. stun okunuyor { DelayMs(20); tus=4; } if(sut2) // 2. stun okunuyor { DelayMs(20); tus=5; } if(sut3) // 3. stun okunuyor { DelayMs(20); tus=6; } if(sut4) // 4. stun okunuyor { DelayMs(20); tus=0x0B; } sat2=0; // 1. satr lojik-0 yaplyor sat3=1; // 3. satr if(sut1) // 1. stun { DelayMs(20); tus=7; } if(sut2) // 2. stun { DelayMs(20); tus=8; } if(sut3) // 3. stun { DelayMs(20); lojik-1 yaplyor okunuyor

okunuyor

okunuyor

FxDev.org

Sayfa 46

tus=9; } if(sut4) // 4. stun okunuyor { DelayMs(20); tus=0x0C; } sat3=0; // 1. satr lojik-0 yaplyor sat4=1; // 4. satr if(sut1) // 1. stun { DelayMs(20); tus=0x0E; } if(sut2) // 2. stun { DelayMs(20); tus=0; } if(sut3) // 3. stun { DelayMs(20); tus=0x0F; } if(sut4) // 4. stun { DelayMs(20); tus=0x0D; } sat4=0; // 4. satr } void main(void) { TRISB=0x00; TRISC=0x00; TRISD=0x0F; PORTB=0x00; PORTC=0x00; PORTD=0x00; // Ana fonksiyon alan // LCD iin k // Tu takm iin giri ve k lojik-1 yaplyor okunuyor

okunuyor

okunuyor

okunuyor

lojik-0 yaplyor

return tus; // Fonksiyon "tus" deeri ile geri dner

lcd_init(); // LCD ilk ayarlar yaplyor lcd_yaz("Basilan Tus="); for(;;) { lcd_gotoxy(1,13); // LCD 1x13e gidiliyor while(keypad_oku()!=0); // Keypad deeri 0dan farkl m veri_yolla(keypad_oku()/10+48); // Onlar yazlyor veri_yolla(keypad_oku()%10+48); // Birler yazlyor } }

FxDev.org

Sayfa 47

Grld zere main fonksiyonumuz ok sade olmasna karn kodu en ok uzatan keypad tarama fonksiyonudur. Bu fonksiyonu da ktphane haline getirip kullanmak mmkndr.
veri_yolla(keypad_oku()/10+48);

Bu blmde dikkat edilmesi gereken blm yukardaki fonksiyon kullanmdr. veri_yolla fonksiyonu LCDye Ascii karakter gndermeye yarayan fonksiyondur, 48 ise 0n Ascii kodudur, dolays ile yaplan ilemin sonucu 2 ise 48+2=50 yapar ve 50, 2nin Ascii kodudur. Aslnda Cde bu ilemi yapan sprintf fonksiyonu vardr, fakat picde ok fazla yer igal etmektedir, biz tm blmlerde veri_yolla vb. fonksiyonlar kullanarak aslnda bu iin o kadar da karmak olmadn greceiz. 4.1.4) zel Karakter LCD Uygulamas ekil-40da da grlecei zere CGROM zerinde tanmlanm herhangi bir Trke karakter mevcut deildir. Fakat nceden de sylediimiz gibi CGROMun ilk 8 karakterlik bo ksm yazmaya msaittir ve dilediimiz ekli oraya koymak mmkndr. Bu uygulamamzda Trke karakterleri bu bo adreslere yerletirecek ve kullanacaz. ncelikle ekil-44te uygulamasn da grebileceiniz devreyi iziyoruz.

ekil 44 zel Karekter LCD Uygulamas

Yukarda grld gibi , , i, , , , | ve derece iareti gibi zel karakterler LCDnin CGROMuna yklenmi ve gsterilmitir. Bunu gerekleyen C kodu ise yledir.

FxDev.org

Sayfa 48

#include <htc.h> #include <delay.h> // Gecikme ktphanesi tanmlanyor #include "lcd.h" // LCD ktphanesi tanmlanyor void ozel_karakterler(void) { // CGRAM'de 1. Adrese "" Karakteri Kaydediliyor lcd_komut(0x40);veri_yolla(14); lcd_komut(0x41);veri_yolla(17); lcd_komut(0x42);veri_yolla(16); lcd_komut(0x43);veri_yolla(16); lcd_komut(0x44);veri_yolla(16); lcd_komut(0x45);veri_yolla(21); lcd_komut(0x46);veri_yolla(14); lcd_komut(0x47);veri_yolla(0); // CGRAM'de 1. Adrese "" Karakteri Kaydediliyor lcd_komut(0x48);veri_yolla(14); lcd_komut(0x49);veri_yolla(0); lcd_komut(0x4A);veri_yolla(15); lcd_komut(0x4B);veri_yolla(16); lcd_komut(0x4C);veri_yolla(19); lcd_komut(0x4D);veri_yolla(17); lcd_komut(0x4E);veri_yolla(15); lcd_komut(0x4F);veri_yolla(0); // CGRAM'de 2. Adrese "" Karakteri Kaydediliyor lcd_komut(0x50);veri_yolla(4); lcd_komut(0x51);veri_yolla(0); lcd_komut(0x52);veri_yolla(4); lcd_komut(0x53);veri_yolla(4); lcd_komut(0x54);veri_yolla(4); lcd_komut(0x55);veri_yolla(4); lcd_komut(0x56);veri_yolla(4); lcd_komut(0x57);veri_yolla(0); // CGRAM'de 3. Adrese "" Karakteri Kaydediliyor lcd_komut(0x58);veri_yolla(10); lcd_komut(0x59);veri_yolla(0); lcd_komut(0x5A);veri_yolla(14); lcd_komut(0x5B);veri_yolla(17); lcd_komut(0x5C);veri_yolla(17); lcd_komut(0x5D);veri_yolla(17); lcd_komut(0x5E);veri_yolla(14); lcd_komut(0x5F);veri_yolla(0); // CGRAM'de 4. Adrese "" Karakteri Kaydediliyor lcd_komut(0x60);veri_yolla(14); lcd_komut(0x61);veri_yolla(17); lcd_komut(0x62);veri_yolla(16); lcd_komut(0x63);veri_yolla(14); lcd_komut(0x64);veri_yolla(1); lcd_komut(0x65);veri_yolla(21); lcd_komut(0x66);veri_yolla(14); lcd_komut(0x67);veri_yolla(0); // CGRAM'de 5. Adrese "" Karakteri Kaydediliyor lcd_komut(0x68);veri_yolla(10); lcd_komut(0x69);veri_yolla(0); lcd_komut(0x6A);veri_yolla(17); lcd_komut(0x6B);veri_yolla(17);

FxDev.org

Sayfa 49

lcd_komut(0x6C);veri_yolla(17); lcd_komut(0x6D);veri_yolla(17); lcd_komut(0x6E);veri_yolla(14); lcd_komut(0x6F);veri_yolla(0); // CGRAM'de 6. Adrese "I" Karakteri Kaydediliyor lcd_komut(0x70);veri_yolla(4); lcd_komut(0x71);veri_yolla(4); lcd_komut(0x72);veri_yolla(4); lcd_komut(0x73);veri_yolla(4); lcd_komut(0x74);veri_yolla(4); lcd_komut(0x75);veri_yolla(4); lcd_komut(0x76);veri_yolla(4); lcd_komut(0x77);veri_yolla(0); // CGRAM'de 7. Adrese "'" Karakteri Kaydediliyor lcd_komut(0x78);veri_yolla(12); lcd_komut(0x79);veri_yolla(18); lcd_komut(0x7A);veri_yolla(18); lcd_komut(0x7B);veri_yolla(12); lcd_komut(0x7C);veri_yolla(0); lcd_komut(0x7D);veri_yolla(0); lcd_komut(0x7E);veri_yolla(0); lcd_komut(0x7F);veri_yolla(0); lcd_komut(BirinciSatir); } void main(void) { TRISB=0x00; TRISC=0x00; PORTB=0x00; PORTC=0x00; // Ana fonksiyon alan // LCD iin k

lcd_init(); ozel_karakterler(); veri_yolla(0); veri_yolla(1); veri_yolla(2); veri_yolla(3); veri_yolla(4); veri_yolla(5); veri_yolla(6); veri_yolla(7); for(;;); }

// LCD ilk ayarlar yaplyor // zel karekterler ykleniyor // // // // // // // // 1. 2. 3. 4. 5. 6. 7. 8. zel zel zel zel zel zel zel zel karekter karekter karekter karekter karekter karekter karekter karekter yazdrlyor yazdrlyor yazdrlyor yazdrlyor yazdrlyor yazdrlyor yazdrlyor yazdrlyor

Burada dikkat edilmesi gereken konu ise CGRAM adresine ykleme yapldktan sonra tekrar ilk satra dnlmesi gerektiidir. Yoksa cursor LCDnin grnmez blgelerine geerek, istediimiz gibi almamaktadr. Bu blmde LCDnin kullanlmasnn Hi-Tech altnda ne kadar kolay olabileceini grm olduk. zel ekilleri oluturan programlar internetten kolaylkla bulabilirsiniz.

FxDev.org

Sayfa 50

4.2) ADC lemleri Pic 16f877a ierisinde dahili olarak bulunan ADC modl 0-5V aralndaki analog bilgiyi 10 bitlik znrlk ile digital bilgiye dntrr. Bu da bize yaklak binde bir hassasiyet kazandrr. ekil-45te de grlecei zere Pic16f877a ierisinde tam 8 kanal ADC birimi mevcuttur ve girileri PORTA ve PORTE birimleri tarafndan salanr.

ekil 45 ADC Birimi

ADC birimi ADCON0 ve ADCON1 adl iki adet kaydedici ile kontrol edilir. Bu kaydedicilerin bit bit grevleri aada verilmitir.

ADCS1, ADCS0

: Frekans kayna seim bitleridir, ayrntl bilgi aadaki tablodadr.

CHS2, CHS1, CHS0


FxDev.org

: Kanal seme bitleridir, ayrntl bilgi aadaki tablodadr.


Sayfa 51

GO/DONE (ADGO) ADON

: ADC evrimini balatan bittir, evrim bitince 0 olur. : ADC birimini aan bittir.

ADFM

: Sonucun ekil-46da grlecei gibi ADRESH ve ADRESL kaydedicilerinde saa m sola m yaslanacana bu bit karar verir. (1: Saa dayal, 0: Sola dayal)

ekil 46 ADFMin Grevi

ADCS2 PCFG3, PCFG2, PCFG1, PCFG0

: Yardmc frekans seme biti. : Portlarn grevlerini ayarlayan bitler. Ayrnt aadaki ekil-47de gzkmektedir.

ekil 47 PCFG3, PCFG2, PCFG1, PCFG0n Grevi

FxDev.org

Sayfa 52

ADC birimi kesmeleri ise ADIE ve ADIF bitleri ile kontrol edilir. ADC birimini altrmak iin aadaki admlar izlenir; - Hangi pin kullanlacaksa o seilir, - ADC modl alr, - Kesme kullanlacaksa, gerekli birimler ayarlanr, - Yaklak 20us beklenir, - evrim balatlr (ADGO=1 veya GODONE=1), - evrimin bitmesi beklenir, - ADRESH ve ADRESL, ADFM bitinin durumuna gre okunur. 4.2.1) lk ADC Uygulamas ADC biriminin nasl altn rendikten sonra ilk uygulamamzda ilk iki analog kanalna bal potlardan okunan 0-5V arasndaki voltajlarn LCDde grnmesi ve kesmeden faydalanarak her evrim kesimine gidildiinde RC5e bal ledin yanp snmesi amalanmaktadr. imdi ekil-48deki devremizi izelim ve gerekli hesaplamalarmz yapalm.

ekil 48 lk ADC Denemesi

16f877de ADC 10 bitlik derinlie sahiptir, referans voltajmzn maksimum 5V olduunu dnrsek; 5/1024=0.0048=0.005 yapar. Virglden sonra iki basamak grmek istiyorsak bu deeri 3 kere sola telediimeli yani 0.5 yapmalyz. Bylelikle deerleri srasyla 1000e, 1000e blmden kalan 100e, 100e blmden kalan 10a sonunda da 10a blmden kalan alarak salayabiliriz. Bylelikle ondalkl saylar da rahata grebiliriz. Tm bunlar yapan C kodu ise aadaki ekilde olacaktr.
FxDev.org Sayfa 53

#include <htc.h> #include "delay.h" // Gecikme ktphanesi tanmlanyor #include "lcd.h" // LCD ktphanesi tanmlanyor int voltaj_1; int voltaj_2; char i=1; void main(void) { TRISA=0x03; TRISB=0x00; TRISC=0x00; PORTB=0x00; PORTC=0x00; PCFG3=0; PCFG2=1; PCFG1=0; PCFG0=0; ADFM=1; ADON=1; ADIF=0; ADIE=1; PEIE=1; GIE=1; lcd_init(); // Ana fonksiyon alan // Analog giri iin // LCD iin k

// AN0 ve AN1 analog

// Saa dayal yazlyor // ADC alyor // ADC bayra temizleniyor // ADC kesmesi izni veriliyor // Genel ve yardmc kesme izinleri veriliyor // LCD ilk ayarlar yaplyor

lcd_yaz("1.Voltaj="); lcd_gotoxy(2,1); lcd_yaz("2.Voltaj="); for(;;) { CHS2=0; // AN0 seiliyor CHS1=0; CHS0=0; DelayUs(25); ADGO=1; // evrim balatlyor while(ADGO); voltaj_1=(int)((ADRESH*256+ADRESL)/2); // Hesaplama yaplyor lcd_gotoxy(1,10); // Okunan deer LCD'ye yazlyor veri_yolla(voltaj_1/1000+48); veri_yolla((voltaj_1%1000)/100+48); veri_yolla('.'); veri_yolla((voltaj_1%100)/10+48); veri_yolla(voltaj_1%10+48); veri_yolla('V'); CHS2=0; // AN1 seiliyor CHS1=0; CHS0=1; DelayUs(25); ADGO=1; // evrim balatlyor while(ADGO); voltaj_2=(int)((ADRESH*256+ADRESL)/2); // Hesaplama yaplyor lcd_gotoxy(2,10); // Okunan deer LCD'ye yazlyor veri_yolla(voltaj_2/1000+48); veri_yolla((voltaj_2%1000)/100+48); veri_yolla('.');

FxDev.org

Sayfa 54

veri_yolla((voltaj_2%100)/10+48); veri_yolla(voltaj_2%10+48); veri_yolla('V'); } } static void interrupt led_yaz_son(void) { if(ADIF) { i=!i; RC5=i; ADIF=0; } }

// evrim biti kesmesi bekleniyor // Her kesme de deili alnyor // Deer RC5'e aktarlyor // Kesme bayra sfrlanyor

ADC ilemlerini belirttiimiz srada yaptktan sonra devremizi altrdmzda ledin srekli yanp sndn greceksiniz. Bu evrim biti kesmesinin doru ekilde altn gstermektedir. Dilerseniz, ADC evrim bitiinden sonra istediiniz ilemi kesme de yaptrabilirsiniz. 4.2.2) LM35 Uygulamas LM35, 3-4 derece hata payna sahip, kullanm kolayl itibariyle hassasiyet gerekmeyen scaklk uygulamalarnda ska tercih edilen bir scaklk sensrdr. Sensr genel itibariyle her 1 birimlik scaklk deiiminde 10mV voltaj deiimine giderek lm yapmamz salar. 16f877ann 10 bit derinliindeki ADC birimi bunu alglamak iin olduka yeterlidir. Bu uygulamamzda LM35 birimini AN0 giriine balayp scaklk lm yaplacak ve llen deer LCDye yanstlacaktr. Uygulamadan nce ekil-49daki devreyi iziyoruz.

ekil 49 LM35 Uygulamas

FxDev.org

Sayfa 55

Derece iaretini LCDnin ASCII tablosundan baktmzda 0xDF ifadesinin bunu salad grlebilir. Bu dikkate alnarak yazlan Hi-Tech kodu aadaki gibi olacaktr.
#include <htc.h> #include "delay.h" #include "lcd.h" void main(void) { int sicaklik; TRISA=0x03; TRISB=0x00; TRISC=0x00; PORTB=0x00; PORTC=0x00; PCFG3=1; PCFG2=1; PCFG1=1; PCFG0=0; ADFM=1; ADON=1; lcd_init(); // Gecikme ktphanesi tanmlanyor // LCD ktphanesi tanmlanyor // Ana fonksiyon alan // Analog giri iin // LCD iin k

// AN0 analog

// Saa dayal yazlyor // ADC alyor // LCD ilk ayarlar yaplyor

lcd_yaz("Sicaklik Degeri"); for(;;) { CHS2=0; // AN0 seiliyor CHS1=0; CHS0=0; DelayUs(25); ADGO=1; // evrim balatlyor while(ADGO); sicaklik=(int)((ADRESH*256+ADRESL)*48); // Hesaplama yaplyor lcd_gotoxy(2,5); // Okunan deer LCD'ye yazlyor veri_yolla(sicaklik/1000+48); veri_yolla((sicaklik%1000)/100+48); veri_yolla('.'); veri_yolla((sicaklik%100)/10+48); veri_yolla(sicaklik%10+48); veri_yolla(0xDF); // Derece iareti oluturuyor veri_yolla('C'); } }

Grld gibi bu ekilde herhangi bir ortamn, kt de olsa, scakl kolaylkla okunup LCD ekrana yanstlabilir. Bu blmde de grdmz gibi ktphanelerin nemi bir kez daha vurgulanmtr, ayrca matematiksel hesaplarn ve hangi kaydedicilerin nerelerde kullanlacan bilmek de ilemleri ok kolaylatrmaktadr.

FxDev.org

Sayfa 56

BLM 5 DAHL EEPROM


5.1) Hi-Techte Dahili EEPROM lemleri EEPROM, Electronically Erasable Programmable Read-Only Memory yani elektriksel olarak silinip yazlabilen hafza birimidir. Pic16f877ann iinde 256 byte yani 256x8 bitlik EEPROM bulunmaktadr. Kullanacamz ilemlerdeki bilgilerin, enerji kesildiinde de korunmasn istiyorsak picin EEPROM birimini kullanabiliriz. Eer kaydedeceimiz deerler 256bytetan byk ise harici EEPROMlar kullanarak istediimizi yine gerekletirebiliriz. Pic ierisinde bulunan EEPROM birimini EECON1 ve EECON2 kaydedicileri kontrol eder. EECON2 aslnda fiziksel olarak bulunmayan bir birimdir. EECON1 kaydedicisindeki bitlerin grevleri aada verilmitir.

EEPGD WRERR WREN WR RD EEIE EEIF

: Eeprom seme biti (1: Program Eeprom, 0: Data Eeprom) : Eeprom yazma hatas var (1: Hata var, 0: Hata yok) : Eeprom yazm izni verme biti (1: zin ver, 0: zin verme) : Yazma ilemini balatma biti (1: Yazma ilemini balat, 0: Yazma ilemi tamamland) : Okuma ilemini balatma biti (1: Okuma ilemini balat, 0: Okuma ilemi tamamland) : Eeprom yazm/okuma bitti kesmesi izin biti : Eeprom yazm/okuma bitti kesmesi bayra

Datasheette belirtilen ifadelere gre Eepromu okumak iin aadaki ifadeler srasyla yaplmaldr. - ncelikle EEADR kaydedicisine 8bitlik adres yazlr. - RD=1 yaplarak yazm ilemi komutu verilir - Okunan deer EEDATA kaydedicisine gelir Datasheette belirtilen ifadelere gre Eeproma yazmak iin aadaki ifadeler srasyla yaplmaldr. - EEADR kaydedicisi ile Eeprom boyutu almayacak ekilde adres belirtilir - EEDATA kaydedicisi ile Eeproma yaztlacak bilgi belirtilir - WREN=1 ile yazma izni verilir - EECON2=0x55 ve ardndan EECON2=0xAA yaplmak zorundadr - WR=1 ile yazma ilemi balatlr - WR bitinin 0 olmas beklenir - WREN=0 yaplarak yazm engellenir Bu ilemleri ktphane haline getirerek istediimiz zaman Eeprom ilemi yapacamzda bunu kullanabiliriz. Yukardaki ilemleri yapacak eeprom.h ktphane bal aadaki gibi olacaktr.
FxDev.org Sayfa 57

/* www.FxDev.org * EEPROM Kullanm Klavuzu * data_eeprom_write(address, data); ile eepromun istenilen adresine istenilen bilgi yazlr. * data_eeprom_read(address); ile eepromun istenilen adresi okunur. * www.FxDev.org */ extern void data_eeprom_write(unsigned char address, unsigned char data); extern unsigned char data_eeprom_read(unsigned char address);

Fonksiyonlar belirttiimiz ekilde iletecek eeprom.c kodu ise aadaki gibi olacaktr.
#include <pic.h> #include "eeprom.h" #include "delay.h" void data_eeprom_write(unsigned char address, unsigned char data) { EEADR=address; EEDATA=data; WREN=1; EECON2 = 0x55; EECON2 = 0xAA; WR=1; while(WR); WREN=0; } unsigned char data_eeprom_read(unsigned char address) { EEADR=address; RD=1; return(EEDATA); }

FxDev.org

Sayfa 58

5.1.1) Eeprom Uygulamas Eeprom uygulamasnda eeproma yazdmz ismimizin LCDye yanstlmas salanacaktr. Bunun ncelikle ekil-50deki devreyi iziyoruz.

ekil 50 Eeprom uygulamas

ekil-50de almas gzken devrede eeprom hafzasn grmek iin Proteusta pause tuuna basp ve pice sa tklanarak, PIC CPU/EPROM Memory ksmna tklanmaldr. Eeprom hafzas ekil-51de gzkmektedir.

ekil 51 Eeprom hafzas

FxDev.org

Sayfa 59

Tm bu ilemleri yapan C kodu ise aadaki gibidir.


#include #include #include #include <htc.h> "delay.h" // Gecikme ktphanesi tanmlanyor "lcd.h" // LCD ktphanesi tanmlanyor "eeprom.h" // Eeprom ktphanesi tanmlanyor // Ana fonksiyon alan // LCD iin k

void main(void) { TRISB=0x00; TRISC=0x00; PORTB=0x00; PORTC=0x00; lcd_init();

// LCD ilk ayarlar yaplyor

data_eeprom_write(0x00,'F'); // Admz eeproma yazlyor data_eeprom_write(0x01,'I'); data_eeprom_write(0x02,'R'); data_eeprom_write(0x03,'A'); data_eeprom_write(0x04,'T'); lcd_yaz("Eeprom'daki Veri"); lcd_gotoxy(2,1); veri_yolla(data_eeprom_read(0x00)); // Eepromdaki bilgi LCD'ye yazdrlyor veri_yolla(data_eeprom_read(0x01)); veri_yolla(data_eeprom_read(0x02)); veri_yolla(data_eeprom_read(0x03)); veri_yolla(data_eeprom_read(0x04)); for(;;); }

Grld zere Eeproma yaz yazmak datasheette sylenildii yapldktan sonra olduka kolaydr. Bu ilemden sonra eer Eeproma kayt yaptnz pice baka programlar (Eeeproma yazm yapmayan programlar) yazdnzda dahi, Eepromdaki isminiz aynen korunacaktr.

FxDev.org

Sayfa 60

BLM 6 RS232 SER LETM LEMLER


6.1) Hi-Techte RS232 Seri letiim lemleri Mikrodenetleyiciler ile dier mikrodenetleyiciler, cihazlar, bilgisayarlar arasnda iletiim kurmak istenildiinde kullanlan metotlardan bir ka seri ve paralel iletiimdir. Paralel iletiimde 8 bit bilgi, 8 adet data kablosuyla gerekli aygtlara balanr ve iletiim salanr. Fakat bu uzun mesafelerde fazla kablo kullanmna yol amaktadr. Paralel iletiimden yava olmasna karn bu sorunu amak iin kullanlan seri iletiim protokolnde ise sadece 2 adet veri kablosu kullanlr ve bilgi yine bu iki kablo zerinden alnr veya gnderilir. Seri haberleme protokol kendi ierisinde senkron ve asenkron olmak zere ikiye ayrlr; Senkron Seri letiim: ekil-52de grlen senkron seri iletiimde, yardmc bir saat iareti kullanlr. Gnderilecek veya alnacak bilgi bu saat iaretine uyarak gelmek veya gnderilmek zorundadr. Hzl iletiim yaplaca zaman bu iletiim metodu kullanlr.

ekil 52 Senkron Seri letiim

Asenkron Seri letiim: ekil-53te grlen asenkron seri iletiim, yardmc bir saat iareti yerine balang, biti bitleri ile kontrol edilir. Herhangi bir anda iletiim balatlabilir veya durdurulabilir. letiim bittii zaman hat IDLE denilen duruma geer. Senkron seri iletiime gre yavatr.

ekil 53 Asenkron Seri letiim

Biz bu blmde ok sk kullanlan asenkron seri iletiim metodunu kullanarak uygulama yapacaz. Asenkron seri iletiime gemeden nce bu metotla ilgili birka terimi renmekte fayda vardr. Bu terimler aada aklanmtr. letiim Hz : Verici ve alc belirli iletim hzlarnda alrlar. Bu konuda standart haline gelmi iletim hzlar mevcuttur.
Sayfa 61

FxDev.org

Balang Biti : Gnderilecek bilgiden nce iletiimin balayacan bildiren bittir. Veri Uzunluu : Gnderilecek verinin uzunluudur, genel bir sabiti olmamasna karn kolayl nedeniyle genellikle 8 bit uzunluundadr. Elik Biti : Veri iletimi esnasnda kullanlan bu bit, veri bozukluu kontrolnde kullanlr. Dur Biti : Veri iletiminin bittiini, alcya bildiren bittir. Max232 Entegresi: Bilgisayarlardaki RS232 birimi logic-0 iin -3V..-12V, logic-1 iin ise +3V..+12V arasnda gerilimler retmektedir. Oysa pic gibi TTL mantyla alan aygtlar iin bu deerler geerli deildir. Bu deerlerin 0V..+5V aralna indirmek iin zel gerilim dengeleyici entegreler kullanlmaktadr. Gnmzde bu entegrelerin en ok kullanlan ise Maxim firmasnn rettii Max232 entegresidir. Bu entegrenin i yaps entegreyle birlikte kullanlmas gereken kapasitr deerleri ekil-54te gzkmektedir.

ekil 54 Max232 Entegresi

Max232 entegresini bilgisayara balamak iin ise ekil-55te grlen konektr kullanlr.

ekil 55 RS232 Konektor

Bizim kullanacamz Pic16f877a ierisinde hazr olarak bulunan bir adet seri iletiim birimi bulunmaktadr. RC6/TX ve RC7/RX ular ise bu i iin zel olarak ayrlm pinlerdir. Seri iletiimi kullanmak iin picde TXSTA ve RCSTA kaydedicileri ayarlanmaldr. Bu kaydedicilerin grevleri bit bit aada grlmektedir.

FxDev.org

Sayfa 62

CSRC TX9 TXEN SYNC BRGH TRMT TX9D

: Senkron modda, (1: Master, 0: Slave) : letiim modu seme biti (1: 9 Bitlik letiim, 0: 8 Bitlik letiim) : Transfere izin verme biti (1: Transfere izin ver, 0: Transfere izin verme) : 1: Senkron mod, 0: Asenkron mod : Hzl/yava boudrate seme biti (1: Hzl mod, 0: Yava mod) : letim kaydedicisi bo/dolu biti (1: Dolu, 0: Bo) : 9 bitlik modda parity veya 9. bit

SPEN RX9 SREN CREN

: 1: Seri port ak, 0: Seri port kapal : Alm modu seme biti (1: 9 bitlik iletiim, 0: 8 bitlik iletiim) : Senkron modda (1: Tek alm ak, 0: Tek alm kapal) : Asenkron modda (1: Devaml almaya izin ver, 0: Devaml almaya izin verme) Senkron modda (1: CREN sfrlanncaya kadar alma izin ver, 0: Almay kes) ADDEN: Asenkron modda RX9=1 ise (1: 8bit yklemede kesmeye git, 9. bit parity olarak kullanlabilir) FERR : Almda hata alglamas biti (1: Hata var, 0: Hata yok) OERR : st ste yazm hatas kontrol (1: Hata var, 0: Hata yok) RX9D : 9 bitlik modda parity veya 9. bit Bu kaydedicilerden baka seri iletiim hz ayar yapmak iin SPBRG kaydedicisine ihtiya vardr. Bu 8 bitlik kaydediciye yklenecek deerler ile standart haline gelmi hzlar ayarlanr. Bu kaydediciye yklenecek deer aadaki formlle hesaplanr.

Grld zere belirlenen X deerlerine gre boudrate hzlar ayarlanr. Genelde dk hzlarda seri iletiim kurulmadndan biz hzl iletiim metodunu kullanacaz. Bunun iin gerekli X deerini ekil-56dan bulup SPBRG registeri ierisine ykleyebilir ya da bizim iin gerekli Xi bulma formlmz olan X=(FOSC/(16UL * BAUD) -1) eitliini kullanabiliriz.

FxDev.org

Sayfa 63

ekil 56 eitli Boudrateler iin SPBRG Deerleri

Son olarak SPBRG deerini belirledikten sonra RCIF ile alm, TXIF ile de gnderim kesme bayraklar kontrolleri ile gnderim veya alm iinin bittii kontrol edilerek RCREG kaydedicisi ile alnan bilgi, TXREG ile de gnderilmek istenen bilgiler istenilen ekilde kullanlabilir. Biraz kark grnse de uygulamada tm bu sylediklerimiz olduka kolay bir ekilde yaplmaktadr. Seri iletiim yaparken ncelikle iletiim metotlarmz (Ka bitlik iletii metodu, ka baudrate hznda vb.) belirlemeli, daha sonra ise kesme bayraklar kontrolyle iletiim kurmalyz. Daha sonra kullanmak iin seri iletiimi de ktphane haline getirirsek usart.h dosyamz aadaki gibi olacaktr.
/* www.FxDev.org * USART Kullanm Klavuzu * usart_init(); ile USART'n ilk ayarlarn yap * putch('A'); eklinde tek byte veri gnder * A=getch(); ile tek byte'lk veri al * www.FxDev.org */ #define BAUD 19200 //Boudrate #define FOSC 4000000L //Kristal hz #define NINE 0 //9 bit iletiim kullanlacaksa 1 yaplmal #define HIGH_SPEED 1 //Hzl iletiim yaplacaksa 1 yaplmal #define RX_PIN TRISC7 #define TX_PIN TRISC6 //Seri port pinleri

FxDev.org

Sayfa 64

#define DIVIDER

((int)(FOSC/(16UL * BAUD) -1))

extern void usart_init(void); extern void putch(unsigned char byte); extern unsigned char getch(void);

Grld gibi boudrate hesab (FOSC/(16UL * BAUD) -1) eklinde ktphane balnda tanmlanmtr. Ayrca kullanlan kristal de burada rnein 4MHz iin 4000000L veya 20MHz iin 20000000L eklinde tanmlanr. Standart haline gelmi boudrateler ve seri port pinleri de burada tanmlanarak seri iletiim ktphane ilemleri tamamlanr. Gerekli ilemleri yapan usart.c dosyas ise aadaki gibidir.
#include <pic.h> #include "stdio.h" #include "usart.h" void usart_init(void) { unsigned char speed,nine_bits; unsigned int divider; RX_PIN = 1; TX_PIN = 1; // Seri iletiim pinleri giri olarak tanmlanyor

if(HIGH_SPEED==1) // Hzl iletiim yaplacaksa speed=0x4; else // Yaval iletiim yaplacaksa speed=0x00; if(NINE==1) nine_bits=0x04; else nine_bits=0x00; // 9 bitlik iletiim yaplacaksa // 8 bitlik iletiim yaplacaksa

SPBRG = DIVIDER; // Hz deeri SPBRG'ye ykleniyor RCSTA = (nine_bits|0x90); // Alm kaydedicisi ayarlanyor TXSTA = (speed|nine_bits|0x20); // Gnderim kaydedicisi ayarlanyor } void putch(unsigned char byte) { // Tek byte gnder while(!TXIF); // Transfer tamponu bo mu TXREG = byte; } unsigned char getch(void) { // Tek byte al while(!RCIF); // Alm tamponu bo mu return RCREG; // Tek byte alnyor } // Tek byte gnderiliyor

FxDev.org

Sayfa 65

6.2) RS232 Seri letiim Uygulamas Ktphanelerimizi tamamladktan sonra ekil-57de grlen uygulamaya geebiliriz. Bu uygulamada seri porttan gnderdiimiz bilgilerin LCDye yazlmasn salayacaz. ncelikle ekil-57de alma an grlebilecek devreyi kuruyoruz.

ekil 57 RS232 Seri letiim Uygulamas

ekil-57deki devrede max232nin nasl kullanlaca da gsterilmitir. Boudrate 19200 olarak kabul ettiimizde, istediimizi gerekletirecek C program aadaki gibi olacaktr.
#include <htc.h> #include <stdio.h> ktphanesi #include "delay.h" #include "lcd.h" #include "usart.h" void main(void) { char i,j; TRISB=0x00; TRISC=0xF0; PORTB=0x00; lcd_init(); usart_init(); // printf iin gerekli C standart giri k // Gecikme ktphanesi tanmlanyor // LCD ktphanesi tanmlanyor // USART ktphanesi tanmlanyor // Ana fonksiyon alan // LCD iin k // USART pinleri giri olarak kabul ediliyor // LCD ilk ayarlar yaplyor // USART ilk ayarlar yaplyor

lcd_yaz(" www.FxDev.org"); lcd_gotoxy(2,1); lcd_yaz(" LCD / USART"); DelayMs(250);DelayMs(250);DelayMs(250);DelayMs(250); lcd_clear(); lcd_komut(ImlecYanSon); // Imlec yanp snecek

FxDev.org

Sayfa 66

printf("www.FxDev.org\n\rSunar!"); printf("\n\rLCD ve USART Denemesi"); printf("\n\rIstenilen Yazi LCD'de Gozukur!\n\r\n\r"); printf("1x16:"); for(;;) { j++; i=getch(); // Karekter alnyor veri_yolla(i); // LCD'ye baslyor putch(i); // Virtual terminal'e baslyor if(j==16) // lk satra geiliyor { printf("\n\r2x16:"); lcd_gotoxy(2,1); } else if(j==32) // 2. satra geiliyor { veri_yolla(i); lcd_clear(); printf("\n\r1x16:"); j=0; } } }

ekildeki program yazp Proteusta uygulamay altrrsanz virtual terminal ekran ekil58deki gibi gzkecektir.

ekil 58 Virtual Terminal Ekran

Uygulamalarmzda da grdmz gibi ktphane tanmlamak ilerimizi olduka kolay hale getirmektedir. Bu ilemi dier piclerle de yapmak istersek sadece seri port pinlerini ktphane balk dosyasnda tanmlamamz yeterlidir. Virtual terminal programndaki grnty Windows Vista ncesi iletim sistemlerinde Hyper Terminal ile ya da zel seri port yazlmlar ile grmek mmkndr.

FxDev.org

Sayfa 67

BLM 7 SPI ve I2C VER LETM LEMLER


7.1) Hi-Techte SPI letiim lemleri SPI, 8 bitlik veri iletiimi yapmaya olanak salayan ve pic ierisinde MSSP (The Master Synchronous Serial Port) modlnde bulunan birimdir. Eeprom okuma ilemlerinde, ekran srmelerde ve hz gerektiren bir ok ilemde SPI birimi kullanlr. SPI birimi ekil-59da da grld zere 3 adet pin kullanr, eer slave modunda iletiim yaplacaksa ekstra bir pin daha kullanlr.

ekil 59 Virtual Terminal Ekran

16f877a ierisinde bir adet MSSP dolays ile de bir adet SPI birimi bulunur. SPI biriminin pin grevleri ise unlardr; SDO : Seri data k SDI : Seri data girii SCK : Seri saat sinyali Slave modunda iletiim yaplacaksa; SS : Slave seme pini Pic ierisinde bulunan SPI birimini kontrol etmek iin SSPSTAT ve SSPCON kaydedicileri kullanlr. Bu kaydedicilerin grevleri bit bit aada verilmitir.

SMP

: SDI pininden alnacak her bitin okunma zamann belirleyen bit 0: Okuma her aktif zamannn (bit gnderme sresinin) ortasnda 1: Okuma her aktif zamannn (bit gnderme sresinin) sonunda SPI slave ise SMP=0 olmak zorundadr CKE : 1: Transfer aktiften IDLE durumuna geerken olacak 0: Transfer IDLE durumundan aktife geerken olacak 5,4,3,2,1. Bitler I2Cde kullanlyor BF : Alm modunda (1: Alm tamamland (SSPBUF dolu), 0: Alm tamamlanmad)

FxDev.org

Sayfa 68

WCOL

: Gnderim yaplrken yazld m (1: Yazld, hata var, 0: Yazlmad) Balangta WCOL=0 yaplmal. SSPOV : Alm yaplrken yeni alm yapld m (1: Yapld, hata var, 0: Yaplmad) Balangta SSPOV=0 yaplmal. SSPEN : 1: SCK, SDO, SDI ve SS pinleri SPI iin ayarland, 0: Normal pin CKP : IDLE seviyesi belirleme biti (1: IDLE yksek seviye, 0: IDLE dk seviye) SSPM3:SSPM0: Mod seim bitleri, aada SPI iin gerekli olan tanmlamalar gsterilmitir.

SPI iletiimi yapmak iin aadaki admlar srasyla uygulanr; - SMP biti ayarlarlanr, slave modda kullanlacaksa 0 yaplr. - SSPBUF temizlenir, bylelikle SSPBUF yeni veriler iin hazr olur. - BF=0 yaplarak SSPBUFn bo olduu belirtilir. - CKE ile transferin den kenarda m yoksa ykselen kenarda m olaca belirlenir. - CKP ile IDLE durumu belirlenir. - WCOL=0 ve SSPOV=0 yaplarak balangta hatalarn olmad varsaylr. - SSPM3, SSPM2, SSPM1 ve SSPM0 ile iletiim hz belirlenir - SSPEN=1 ile pinlerin SPI iin kullanlaca belirtilir SPI birimini daha sonra da kullanmak iin ktphane haline getirirsek, ktphane balk dosyas spi.h aadaki gibi olur.
/* www.FxDev.org * SPI Kullanm Klavuzu * spi_init(); ile SPI'nn ilk ayarlarn yap * spi_write(0x02); eklinde veri yaz, adres gnder * a=spi_read(0xFF); eklinde veri al * www.FxDev.org */ #define IDLE #define TRANSFER 0 0 // IDLE durumu // IDLE'->IDLE: 0, IDLE->IDLE':1

extern void spi_init(void); extern void spi_write(unsigned char veri); extern unsigned char spi_read(unsigned char veri);

FxDev.org

Sayfa 69

lk yaplacak ayarlar gz nne yazlan spi.c ise aadaki gibi olacaktr.


#include <pic.h> #include "spi.h" void spi_init(void) { //SSPSTAT->SMP,CKE,BF //SSPCON1->WCOL,SSPOV,SSPEN,CKP,SSPM3:SSPM0 SMP=1; SSPBUF=0; BF=0; // Data 8. bitten sonra alnyor // SSPBUF siliniyor. // SSPBUF bo

if(TRANSFER==1) // Transfer aktiften IDLE durumuna geerken olacak CKE=1; else // Transfer IDLE'dan aktif durumuna geerken olacak CKE=0; if(IDLE==1) // IDLE durumun yksek mi dk m olduu belirleniyor CKP=1; else CKP=0; WCOL=0; //Bata alm veya gnderim hatalarnn olmad varsaylyor SSPOV=0; /* Clock 0101: 0100: 0011: 0010: 0001: 0000: */ SSPM3=0; SSPM2=0; SSPM1=1; SSPM0=0; SSPEN=1; } void spi_write(unsigned { BF=0; SSPBUF=veri; while(!BF); } char veri) //BF sfrlanyor //BF=1, SSPBUF dolu //SSPBUF '0' oluncaya kadar bekleniyor // Fosc/64 hz SPI SPI SPI SPI SPI SPI ayar yaplyor... Slave, SS disabled Slave, SS enabled Master, Clk=TMR2/2 Master, Clk=Fosc/64 Master, Clk=Fosc/16 Master, Clk=Fosc/4

//SCK, SDO, SDI, SS ser port pini oldu

unsigned char spi_read(unsigned char veri) { BF=0; //BF sfrlanyor SSPBUF=veri; //SCK gndermek iin tanmlanmam kod gnderiliyor while(!BF); return SSPBUF; }

FxDev.org

Sayfa 70

Burada dikkat edilmesi gereken nokta SSPBUFa yazlan deerlerdedir. SSPBUFa gnderilmek istenen deerler yazld an SPI birimi ayarlamalarmza gre kendi saat sinyalini, IDLE durumunu belirleyerek iletiimi kuracaktr. Alm modunda SSPBUFa veri yazlmasnn nedeni ise yeni bilginin alnmas iin gerekli olan saat sinyalini oluturmaktr. 7.1.1) TC72 ile SPI Uygulamas Bu uygulamada Microchip firmasna ait olan TC72 SPI scaklk sensrn kullanacaz. ekil-60 da DIP soket yaps grlebilecek TC72 scaklk sensr yaklak 7,5MHza kadar kabilen iletiim hzna ve 10 bit znrle sahiptir.

ekil 60 TC72 Pin Yaps

TC72nin yazma okuma zaman tablosu da ekil-61deki gibidir. Bu tablolar datasheetten bire bir alnmtr.

ekil 61 25LC640 Zaman Diyagramlar

FxDev.org

Sayfa 71

ekil-61den de grlecei zere TC72nin IDLE durumu dk seviyededir. Tm bit yazm gnderimleri ise den kenarda gereklemektedir. Bunu spi.h ktphane balk dosyasnda belirtmemiz gerekmektedir. Tm okuma ya da yazm ilemlerinden nce TC72ye belirli komutlar gnderilmelidir. Bu komutlar ekil-62de listelenmitir.

ekil 62 TC72 Komutlar

Tm bunlar dikkate alarak TC72den veri okumak iin; - 0x80 ile kontrol byte olarak 0x04 gnderilerek sensr alr. - Adres bilgisi gnderilir (0x02) - Sonra srasyla scaklk ve kontrol bilgileri alnr. Biz bu uygulamamzda harici TC72 ile scaklk deerini lerek TC72nin kontrol kaydedicisinin deerini LCDde greceiz. ncelikle ekil-63teki devreyi kuruyoruz.

ekil 63 TC72 Uygulamas

FxDev.org

Sayfa 72

stediimizi gerekletiren Hi-Tech kodu ise aadaki gibidir.


#include #include #include #include <htc.h> "delay.h" // Gecikme ktphanesi tanmlanyor "lcd.h" // LCD ktphanesi tanmlanyor "spi.h" // SPI ktphanesi tanmlanyor

#define CE RC6 void tc72_init(void) { spi_init(); CE=1; spi_write(0x80); spi_write(0x04); CE=0; } //TC72 ilk yklemeleri yaplyor

void tc72(unsigned char *msb, unsigned char *lsb, unsigned char *control) { CE=1; spi_write(0x02); *msb=spi_read(0xFF); *lsb=spi_read(0xFF); *control=spi_read(0xFF); CE=0; } void main(void) // Ana fonksiyon alan { unsigned char onlar, ondalar, control; TRISB=0x00; // LCD iin k TRISC=0x10; CE=0; lcd_init(); tc72_init(); // LCD ilk ayarlar yaplyor // SPI ilk ayarlar yaplyor

lcd_yaz("Sicaklik:"); for(;;) { lcd_gotoxy(1,11); tc72(&onlar, &ondalar, &control); veri_yolla(onlar/100+48); veri_yolla((onlar%100)/10+48); veri_yolla(onlar%10+48); veri_yolla(0xDF); veri_yolla('C'); lcd_gotoxy(2,1); lcd_yaz("Control : "); veri_yolla(control/16+48); veri_yolla(control%16+48); veri_yolla('H'); } }

// Scaklk ve kontrol // Deerleri alnp // LCD'ye yazdrlyor

FxDev.org

Sayfa 73

Grld zere SPI iletiimini donanm ile yapmak kodlarmz olduka ksaltm ve mikroilemciye yklenen yk azaltmtr. Ayrca LM35tan baka bir scaklk sensrnn daha nasl kullanldn bylelikle grm olduk. 7.2) Hi-Techte I2C letiim lemleri I2C (Inter-Integrated Circuit) seri iletiimi yine SPI iletiim gibi mikrodenetleyicinin dier elemanlarla iletiim kurmasn salayan ve Philips firmas tarafndan gelitirilen bir protokoldr. zellikle hz gerektiren, pin saysnn nemli olduu ilemlerde tercih edilir. Pic 16f877a ierisinde MSSP biriminde bulunan I2C biriminin dier elemanlarla balants ekil64te grlebilir.

ekil 64 TC72 Uygulamas

I C protokolnde bir pin seri giri/k (SDA) grevini stlenirken dier bir pin ise seri saat sinyali (SCL) retmek iin kullanlr. Bu iletiim metodunda cihazlardan biri master olur, master grevinde bulunan cihaz saat sinyalini kendi oluturur. Dier cihaz ise slave olur ve sadece bilgi giri k grevini yerine getirir. I2C protokolnde yava (100kbit/s), hzl (400kbit/s) ve yksek hzl (3,4 Mbit/s) olmak zere eitli hzlarda iletiim salanabilir.

ekil 65 I C Veri letim Protokol

FxDev.org

Sayfa 74

I2C iletiiminde ekil-65te grlecei zere ilk bata balama biti, ardndan adres bilgisi ve veri bitleri gnderilir. Veri gnderimi stop biti ile son bulur. Her bir byte gnderiminde ise kar taraf bir alnd biti (ACK) geri gnderir. letiim iin gerekli durumlar zetlersek; Yol megul deil Veri transferine bala Veri transferini durdur Geerli veri : SDA ve SCL logic-1 olmaldr. : SCL logic-1 iken, SDA logic-1den logic-0 seviyesine getirilir. : SCL logic-1 iken, SDA logic-0dan logic-1 seviyesine getirilir. : Her bilgi iletimi balama biti ile balar ve stop biti ile son bulur. Her bilgi 1 byte eklinde gnderilir, kardan gelen 9. bit ACK bitidir.

ekil 66 I C Pinleri ve Pull-up direnleri

ekil-66da de grlecei zere mikrodenetleyici ile I2C iletiimi yaplacaksa SCL ve SDA ularna yaklak 10k pull-up direnci balanmaldr. I2C protokoln ayarlamak iin Pic 16f877ada SSPSTAT, SSPCON ve SSPCON2 kaydedicileri kullanlr. Bu kaydedicilerin grevleri aada bit bit verilmitir.

SMP CKE D/A P S R/W UA BF

: 1: I2C modunda dk hzlarda (100KHz, 1MHz) slew rate kullanm ddr, 0: I2C modunda yksek (400KHz) hzlarda slew rate kullanm aktiftir : 1: Transfer aktiften IDLE durumuna geerken olacak 0: Transfer IDLE durumundan aktife geerken olacak : I2C modunda veri ve adres bilgilerini gsteren bittir. (1: Data gnderilmi ya da alnm, 0: Adres gnderilmi ya da alnm) : I2C modunda sonlandrma bitidir. (1: Durdurma biti son bulur, 0: Son bulmaz) : I2C modunda balang bitidir. (1: Balang biti son bulur, 0: Son bulmaz) : SPI ya da I2C modunda okuma m yoksa yazma m yaptn belirten bittir. (1: Okuma, 0: Yazma) : 10 bitlik I2C modunda adres gncelleme bitidir. UA=1 ise SSPADD kaydedicisine gnderilen adres gncellenir. : Alm modunda (1: Alm tamamland (SSPBUF dolu), 0: Alm tamamlanmad)

FxDev.org

Sayfa 75

WCOL

: Gnderim yaplrken yazld m (1: Yazld, hata var, 0: Yazlmad) Balangta WCOL=0 yaplmal. SSPOV : Alm yaplrken yeni alm yapld m (1: Yapld, hata var, 0: Yaplmad) Balangta SSPOV=0 yaplmal. SSPEN : 1: SCL, SDA iin ayarland, 0: Normal pin CKP : IDLE seviyesi belirleme biti (1: IDLE yksek seviye, 0: IDLE dk seviye) SSPM3:SSPM0: Mod seim bitleri, aada I2C iin gerekli olan tanmlamalar gsterilmitir.

GCEN ACKSTAT ACKDT ACKEN

RCEN PEN RSEN SEN

: Slave modda genel arma yetkilendirme bitidir. GCEN=1 olduunda 0000h adresi arldnda kesmeye gidilir. : I2C modunda iletim durumunda stat kabul bitidir. (1: Alnan veri kabul edilmemitir, 0: Alnan veri kabul edilmitir) : I2C modunda master alm durumunda veri kabul bitidir. (1: letilen veri kabul edilmemitir, 0: Veri kabul edilmitir) : I2C modunda e zamanl art arda veri alm yetkilendirme bitidir. (1: Yetkilendirme alr ve ACKDT veri biti iletilir, bit donanm tarafndan otomatik temizlenir) : I2C modunda alm yetkilendirme bitidir. (1: I2C modunda alm vaziyetine geilir, 0: Alm modu devre d) : I2C modunda stop durum ayarnn yapld bittir. (1: SDA ve SCL pinleri stop durumu alr, 0: Stop durumu oluturulmaz) : I2C modunda start durumu yenileme bitidir. (1: SDA ve SCL pinlerinin start durumu tekrarlanr, 0: Yenileme olumaz) : I2C modunda start durum ayarnn yapld bittir. (1: SDA ve SCL pinleri start durumu alr, 0: Start durumu oluturulmaz)
Sayfa 76

FxDev.org

Slew Rate: Data sinyalleri birer kare dalga gibi dnlrse, yksek hzlarda voltaj tepe noktas ve inen kan kenarlarn dikeylikleri bozulabilir. Slew rate bunu (0-5V, 400KHz) gz nne alarak logic seviyeye karar verilmesini salar. I2C birimi grld zere SPI birimine kyasla olduka karmak bir yapya sahiptir. Biz uygulamalarmzda kolaylk olmas amacyla picimizi master olarak kabul edeceiz. Picin datasheetinde yazanlara gre I2C birimini master ayarlamak iin aadaki admlar srayla izlemeliyiz; - SSPCON kaydedicisinden I2C birimi master olarak ayarlanr. SSPEN=1 - SDA, SCL portlar tanmlanyor CKP=1 - IDLE seviyesi 1 olacak SSPM3:SSPM0=0b1000 - I2C master mode, clock=Fosc/[4(SSPAD+1)] - SSPCON2 kaydedicisinin tm birimleri sonraki kontroller iin sfrlanr. - SSPAD ile standart olan ve ekil -67de grlen hzlardan biri seilir (rn: SSPAD=0x0A). - SMP ayarlanarak slew rate kullanlp kullanlmayaca bildirilir. - CKE ile ykselen veya den kenar seimi yaplr. - Kullanlacaksa kesme bayraklar temizlenir (PSPIF=0, BCLIF=0).

ekil 67 I C Hz Deerleri

Tm bu sylediklerimizi bir ktphane haline getirir ekstra fonksiyonlar da yazarsak i2c.h ktphane balk dosyamz aadaki gibi olacaktr.
/* * * * * * * * * * * * */ www.FxDev.org I2C Kullanm Klavuzu i2c_init(); ile i2c'nin ilk ayarlarn yap i2c_wait(); ile IDLE iin beklenir, yazm yaplmaz i2c_start(); ile SCK ve SDA start durumu alr i2c_restart(); ile SCK ve SDA start durumu tekrarlanr i2c_stop(); ile SCK ve SDA stop durumu alr veri=i2c_read(ack); ile okuma yaplr ack=i2c_write(veri); ile yazma yaplr SSPADD hz ayar i2c.c dosyas ierisinde yaplmaldr. www.FxDev.org TRISC3 TRISC4 // SCK ve SDA ular belirlenir

#define TRIS_SCK #define TRIS_SDA

extern void i2c_init(void); extern void i2c_wait(void);

FxDev.org

Sayfa 77

extern extern extern extern extern

void i2c_start(void); void i2c_restart(void); void i2c_stop(void); unsigned char i2c_read(unsigned char ack); unsigned char i2c_write(unsigned char i2c_data);

Yukardaki ilemleri yerine getiren i2c.c dosyamz ise aadaki gibi olacaktr.
#include <pic.h> #include "i2c.h" void i2c_init(void) { TRIS_SCK=1; TRIS_SDA=1;

// SCK ve SDA giri olarak ayarlanyor

SSPCON = 0x38; SSPCON2 = 0x00; // SSPCON2 sonraki ayarlamlar iin temizlniyor /* 4Mhz'de * SSPADD=0x0A: 400KHz * SSPADD=0x0D: 308KHz * SSPADD=0x28: 100Khz */ SSPADD = 0x0A; CKE=0; SMP=1; PSPIF=0; BCLIF=0; } void i2c_wait(void) { while (( SSPCON2 & 0x1F ) | RW ); // IDLE iin beklenir, yazm yaplmaz } void i2c_start(void) { i2c_wait(); SEN=1; } // Slew rate kullanlacak // Kenar: Aktiften IDLE'a // Kesme bayraklar temizleniyor

// IDLE beklenir // SCK ve SDA start durumu alr

void i2c_restart(void) { i2c_wait(); // IDLE beklenir RSEN=1; // SCK ve SDA start durumu tekrarlanr } void i2c_stop(void) { i2c_wait(); PEN=1; }

// IDLE beklenir // SCK ve SDA stop durumu alr

unsigned char i2c_read(unsigned char ack) { unsigned char i2c_data; i2c_wait(); RCEN=1; // IDLE beklenir // Alm vaziyetine geilir

FxDev.org

Sayfa 78

i2c_wait(); i2c_data=SSPBUF; i2c_wait(); if(ack) { ACKDT=1; } else { ACKDT=0; } ACKEN=1; return(i2c_data); }

// IDLE beklenir // Veri alnr // IDLE beklenir // ACK biti durumu // Alm kabul edilmedi

// Alm kabul edildi // ACKDT veri biti iletilir

unsigned char i2c_write(unsigned char i2c_data) { i2c_wait(); // IDLE beklenir SSPBUF=i2c_data; // Veri gnderiliyor return(ACKSTAT); } // 1: Alnan veri kabul edilmemitir // 0: Alnan veri kabul edilmitir

Kodlardan da grlecei zere anlatm karmak da olsa yaplan ilemler olduka basittir. Bu blmden sonra I2C iletiimi kullanlmak istendiinde, ktphane de sadece hz ayarlamas yapmak yeterli olacaktr. 7.2.1) I2C letiim Uygulamas Bu uygulamamzda Atmelin I2C iletiimini kullanan 24C02 harici eepromunu kullanacaz. ekil-68de DIP yaps grlebilecek 24C02, 100Khz ve 400Khz hzlarnda I2C iletiimini kullanabilecek zellie ve 256bytelk hafzaya sahiptir.

ekil 68 24C02 Pin Yaps

ekil-68de de grlecei zere SCL ve SDA pinleri picimizin belirli bacaklarna, Vcc +5Vta, Vss, A0, A1 ve A2 ise toprak hattna balanmaldr. 24C02nin komut yaps olduka basittir bylelikle okuma ve yazma yapmak olduka kolay bir hal alr.

FxDev.org

Sayfa 79

ekil-69dan da grlecei zere 24C02ye yazm yapmak iin ncelikle I2C start verilir, daha sonra slave address denilen komut gnderilir.

ekil 69 24C02ye Yazma Protokol

Slave adress denilen komut ekil-70de grlen yap zerinden kurulur.

ekil 70 24C02Slave Address Kontrol

Grld zere yazm yapmak iin 0xA0, okuma yapmak iin ise 0xA1 komutu kullanlr. Yazm tamamlamak iin ise ncelikle bilginin yazlaca adres ve bilgi gnderilirek I2C stop komutu ile iletiim sonlandrlr ve yaklak 10-15 milisaniye beklenir. Eepromdan bilgi okumak iin ise ekil-71de grlen iletiim metodu kullanlr.

ekil 71 24C02den Okuma Protokol

ncelikle I2C start verilir. Daha sonra slave address olarak 0xA0 gnderilir, daha sonrasnda ise okunacak adres bilgisi gnderilerek I2C tekrar balatlr. kinci kez slave address olarak bu sever okuma yapacamz belirten 0xA1 komutu gnderilerek, istenen adresteki bilgi alnr ve I2C stop komutu ile iletiim sonlandrlr. Biz ktphanemizde tm bu ilemleri tanmladmz iin yapmamz gereken ufak bir fonksiyon yazarak istediimiz ilemi gerekletirmekir.

FxDev.org

Sayfa 80

Bu uygulamada 24C02 eepromunun ilk 0h,8h,10h,18h,20h,28h.. adreslerine ismimizi yazdrp, tekrar eepromun bu adreslerini okuyarak ismimizi LCDye yazdracaz. Uygulamaya gemeden nce ekil-72deki devreyi iziyoruz.

ekil 72 24C02 Uygulamas

ekil-72de de grlecei zere devremiz olduka sadedir. Burada dikkat edilmesi gereken en nemli konu Pull-Up direnleridir. stediimiz ilemi yerine getiren Hi-Tech kodu ise aadaki gibidir.
#include #include #include #include <htc.h> "delay.h" // Gecikme ktphanesi tanmlanyor "lcd.h" // LCD ktphanesi tanmlanyor "i2c.h" // I2C ktphanesi tanmlanyor

void write_ext_eeprom(unsigned char address, unsigned char data) { i2c_start(); i2c_write(0xA0); i2c_write(address); i2c_write(data); i2c_stop(); DelayMs(15); } unsigned char read_ext_eeprom(unsigned char address) {

FxDev.org

Sayfa 81

unsigned char data; i2c_start(); i2c_write(0xA0); i2c_write(address); i2c_restart(); i2c_write(0xA1); data=i2c_read(0); i2c_stop(); return(data); } void main(void) { unsigned char i=0; PORTB=0x00; PORTC=0x00; TRISB=0x00; TRISC=0x00; lcd_init(); i2c_init(); // Portlar sfrlanyor // klar ayarlanyor // LCD ve I2C ilk ayarlar yaplyor // Ad eeproma yazdrlyor

write_ext_eeprom(0x00,'F'); write_ext_eeprom(0x08,'I'); write_ext_eeprom(0x10,'R'); write_ext_eeprom(0x18,'A'); write_ext_eeprom(0x20,'T');

// Eepromdaki bilgi LCD'ye yazdrlyor lcd_yaz("Eepromdaki Veri"); lcd_gotoxy(2,1); veri_yolla(read_ext_eeprom(0x00)); veri_yolla(read_ext_eeprom(0x08)); veri_yolla(read_ext_eeprom(0x10)); veri_yolla(read_ext_eeprom(0x18)); veri_yolla(read_ext_eeprom(0x20)); for(;;); }

Grld zere devremiz gibi kodlarmz da olduka sadedir. Yazma ilemimiz bittiinde proteus simlasyonunu duraklatp, eeproma sa tklatp Internal Memory ksmna tklarsanz ekil-73teki hafza yapsn grmeniz mmkndr.

FxDev.org

Sayfa 82

ekil 73 24C02nin Son Hali

Grld zere I2C iletiimini anlamak zor olsa da kullanmay rendikten sonra iletiim kurmak, sadece donanmn zel komutlarn bilmekten daha zor olmamaktadr.

FxDev.org

Sayfa 83

BLM 8 MOTOR UYGULAMALARI


8.1) DC Motor DC motorlar sabit bir mknats ve iinde dnen yap olan rotordan oluurlar. Yksek akm ektikleri iin direk mikrodenetleyiciye balanmazlar. Kontrol iin H-Kprs denilen zel bir yaplarla mikrodenetleyicilere balanrlar. Gnmzde bu i iin gelitirilmi, ierisinde HKprs bulunan L293, L298, L6201, L6202 gibi birok entegre mevcuttur. Biz bu blmde ekil-74te grlen L298 entegresini temel alarak uygulamalarmz yapacaz.

ekil 74 L298 Entegresi

L298 entegresine iki adet motor balanp ayr ayr saa, sola dnleri veya hzlca durdurulmalar salanabilir. Biz bu uygulamamzda bir adet DC motoru L298 entegresine balayp, saa, sola dnmesini ya da frenleme yapmasn salayacaz. ncelikle ekil-75teki devreyi proteusta iziyoruz.

ekil 75 DC Motor Uygulamas

ekil-75ten de grlecei zere butonlarmz ykselen kenar iin aktif olacaktr. Bunu dikkate alarak yazdmz Hi-Tech kodu ise aadaki gibi olacaktr.

FxDev.org

Sayfa 84

#include <htc.h> void main(void) { ADCON1=0x07; PORTA=0x00; PORTB=0x00; TRISA=0x07; TRISB=0x00; RB2=1; RB3=0; for(;;) { if(RA0) { RB0=1; RB1=0; } if(RA1) { RB0=0; RB1=1; } if(RA2) { RB0=0; RB1=0; } } }

// PORTA dijital oluyor // Portlar sfrlanyor // RA0, RA1, RA2 giri // PORTB k // A kprs seiliyor

// leri tuuna m basld

// Geri tuuna m basld

// Durdurulmak m isteniyor

Grld gibi kodlarmz olduka sadedir. Ayrca bu motorlardan iki tane yan yana koyarak ve birka yer yn alglayc sensr ile izgi izleyen robot yapm olduka basit hale gelebilmektedir. 8.2) Step Motor
Step motorlar genel itibari ile frasz motorlardr. Dier motorlardan fark ise verilen eitli sinyallere gre istenilen ekilde yn alabilmesidir. ekil-76da grlebilecek Step motorun iyapsnda birok bobin ve genelde rotorda ise sabit bir mknats bulunur. eitli bobin iftlerine verilen enerji ile bu mknats istenilen blgeye ynlenir.

ekil 76 Step Motorun Yaps

FxDev.org

Sayfa 85

Step motorlar genellikle 4-5-6 adet uca sahiptirler. Genel uygulamalarda 5 ulu step motorlar tercih edilir. Bu ulardan bir tanesi ortak u iken dierleri sinyalin verilecei ulardr. Step motorlarda dikkat edilmesi gereken bir konu da adm cevab denilen durumdur. Bu step motorun bir admn ne kadar srede aldn belirten bir ifadedir. Eer motora bu sreden daha ksa bir srede sinyal gnderilirse step motor istenildii gibi almayacaktr. DC motorlar gibi step motorlar da miktrodenetleyiciye direk balayarak sremeyiz. Bunun iin gelitirilmi ve ekil-77de i yaps gzken ULN2003, ULN2004 gibi entegreler kullanlr.

ekil 77 ULN2003 Yaps

Step motorlarda bir dier nemli konu da adm asdr. rnein 1,8 derece adm asna sahip bir step motor 200 adm hareket sonra 360 derece dnn tamamlayacaktr. Step motorlar srmek iin eitli metotla gelitirilmitir. Bunlardan en ok kullanlanlar ise tam ve yarm a yntemleridir. Bu metotlar ile 5 ulu step motorun nasl srlecei aadaki tablolarda gsterilmitir. Adm U-1 U-2 U-3 U-4 1 1 0 0 1 2 1 1 0 0 3 0 1 1 0 4 0 0 1 1
Tam Adm Metodu

Adm U-1 1 1 2 1 3 0 4 0 5 0 6 0 7 0 8 1

U-2 0 1 1 1 0 0 0 0

U-3 0 0 0 1 1 1 0 0

U-4 0 0 0 0 0 1 1 1

Yarm Adm Metodu

FxDev.org

Sayfa 86

Eer step motorun her adm 1,8 derece ise tam adm metoduyla her adm 1,8 dereceye, yarm adm metodu ile de 0,9 dereceye denk gelecektir. Buradan da grld zere yarm adm metodu ile step motor srldnde admlar daha da hassaslamaktadr. 8.2.1) ULN2003 ile Step Motor Kontrol
Bu uygulamamzda ULN2003 entegresini ve yarm ad metodunu kullanarak step motorun bir adm ileri ya da geri dnmesini salayacaz. ncelikle ekil-78deki devremizi proteusta iziyoruz.

ekil 78 Step Motor Uygulamas

stediimiz ilemi yerine getiren Hi-Tech kodu ise aadaki gibi olacaktr.
#include <htc.h> // Yarm adm iin dizi tanmlanyor const unsigned char yarim_adim[]={0x01,0x03,0x02,0x06,0x04,0x0C,0x08,0x09}; void main(void) { char i=0; ADCON1=0x07; PORTA=0x00; PORTB=0x00; TRISA=0x03; TRISB=0x00;

// PORTA dijital oluyor // Portlar sfrlanyor // RA0, RA1 giri // PORTB k

for(;;) { if(RA0) // leri tuuna m basld { PORTB=yarim_adim[i]; while(RA0); if(i==7) i=-1;

FxDev.org

Sayfa 87

i++; } if(RA1) // Geri tuuna m basld { if(i==0) i=8; i--; PORTB=yarim_adim[i]; while(RA1); } } }

Kodlarda dikkat edilmesi gereken yer yarim_adim[] dizisidir. Yarm a tablosunda grlen deerler buraya yazlarak ilemlerin daha kolay gereklemesi salanmtr.

8.2.2) Bilgisayar le Step Motor Kontrol


Bu uygulamamzda bilgisayardan gnderdiimiz komutlarla step motorun saa ya d sola srekli dnmesini salayacaz. ncelikle ekil-79daki devreyi iziyoruz.

ekil 79 Bilgisayar ile Step Motor Kontrol

stediimizi yerine getiren Hi-Tech kodlar ise aadaki gibi olacaktr.


#include #include #include #include <htc.h> <stdio.h> "delay.h" "usart.h" // printf iin // Gecikme ktphanesi // Seri haberleme iin

// Yarm adm iin dizi tanmlanyor const unsigned char yarim_adim[]={0x01,0x03,0x02,0x06,0x04,0x0C,0x08,0x09}; void main(void) { char i,karakter=0; PORTB=0x00;

FxDev.org

Sayfa 88

TRISB=0x00; usart_init();

// PORTB k

printf("ADIM MOTOR KONTROLU"); printf("\n\rwww.FxDev.org Sunar!"); printf("\n\r\n\rIslem Seciniz:"); printf("\n\r -Saga Dondur (R) ya da (r)"); printf("\n\r -Sola Dondur (L) ya da (l)"); printf("\n\r -Durdur (R),(r),(L),(l) disinda bir tus"); printf("\n\r\n\rYapmak istediginiz islemi seciniz>"); for(;;) { karakter=getch(); putch(karakter); if(karakter=='R'|| karakter=='r') // R ya da r tuuna m basld { printf("\n\rSaga Donuyor"); printf("\n\rYapmak istediginiz islemi seciniz>"); for(;;) { PORTB=yarim_adim[i]; if(i==7) i=-1; i++; DelayMs(100); if(RCIF) { printf("\n\rMotor Durdu"); printf("\n\rYapmak istediginiz islemi seciniz>"); break; } } } if(karakter=='L'|| karakter=='l') // L ya da l tuuna m basld { printf("\n\rSola Donuyor"); printf("\n\rYapmak istediginiz islemi seciniz>"); for(;;) { if(i==0) i=8; i--; PORTB=yarim_adim[i]; DelayMs(100); if(RCIF) { printf("\n\rMotor Durdu"); printf("\n\rYapmak istediginiz islemi seciniz>"); break; } } } } }

FxDev.org

Sayfa 89

Kodlarda da grlecei zere RCIF kesme bayrandan yararlanlmtr. Bunun nedeni baka bilgi gnderildiinde tamponun dolma kesme bayran set etmesidir. Bu kontrol edilerek sonsuz dnglerden break komutuyla klmtr.

8.3) R/C Servo Motor


Servo motorlar genel itibari ile ierlerinde bir DC motor ve aft konum bilgisi devresi barndrrlar. Bu devre aftn ka derece dndnn alglanmasnda kullanlr. Servo motorlarn i yaps ekil80de gzkmektedir.

ekil 80 Servo Motor Yaps

Servo motorlar 20ms periyotlu, 1msden 2mse kadar deien duty cyclel PWM sinyali ile srlrler. Verilen duty cycle periyotlarna gre servo motorun 0-180 derece aral arasnda alacaklar deerler ekil-81de verilmitir.

ekil 81 Servo Motor Kontrol Sinyalleri

Burada sinyal verilirken rnein 1,5ms ile 1ms aras 90a blnerek istenilen aya gidilebilir. Picin CCP modl genellikle kullandmz 4Mhz kristal iin 50Hzlik PWM sinyalleri retememektedir. Bu yzden yukardaki sinyalizasyonu elle ayarlamamz gerekmektedir.

FxDev.org

Sayfa 90

8.3.1) R/C Servo Motor Uygulamas


Bu blmde kullanacamz servo motaru 0 derece, 90 derece ve 180 dereceye, basacamz butonlarla ynlendireceiz. Sinyalizasyon ilemini hazr delay.h fonksiyonlar ile salayacaz. ncelikle ekil-82deki devremizi Proteusta iziyoruz.

ekil 82 Servo Motor Uygulamas

stediimiz ilemi yerine getiren Hi-Tech kodu ise aadaki gibi olacaktr.
#include <htc.h> #include "delay.h" // Gecikme ktphanesi

void main(void) { char i,karakter=0; ADCON1=0x07; // PORTA dijital oluyor PORTB=0x00; TRISA=0x07; // RA0, RA1 ve RA3 giri TRISB=0x00; // PORTB k for(;;) { if(RA0) { for(;;) { RB0=1; // 1ms Gecikme DelayUs(250);DelayUs(250);DelayUs(250);DelayUs(250); RB0=0; // 19ms Gecikme DelayMs(19); if(RA1 | RA2) break; }

FxDev.org

Sayfa 91

} if(RA1) { for(;;) { RB0=1; // 1,5ms Gecikme DelayUs(250);DelayUs(250);DelayUs(250);DelayUs(250); DelayUs(250);DelayUs(250); RB0=0; // 18,5ms Gecikme DelayMs(18); DelayUs(250);DelayUs(250); if(RA0 | RA2) break; } } if(RA2) { for(;;) { RB0=1; // 2ms Gecikme DelayMs(2); RB0=0; // 18ms gecikme DelayMs(18); if(RA0 | RA1) break; } } } }

Simlasyonu altrdmzda 0,1 veya 0,2 derecelik hatalar gzkecektir. Bunlar gecikme fonksiyonlarnn bire bir almamasnn sonulardr. Fakat normal uygulamalarda fark edilmeyecek kadar kk hata paylardr.

FxDev.org

Sayfa 92

BLM 9 1-WIRE (TEK HAT) LETM ve DS18B20


9.1) 1-Wire (Tek Hat) letiim 1-Wire ya da dier adyla tek hat iletiim Maxim-Dallas firmas tarafndan gelitirilmi ift ynl veri iletiimine izin veren bir protokoldr. Master olan denetleyici ekil-83'te de grlecei zere birden fazla cihaz ayn hattan kontrol edebilir.

ekil 83 Tek Hat Protokol le Birden Fazla Cihaz Kontrol

1-Wire iletiime sahip tm cihazlar kendilerine ait 64 bitlik kayt koduna sahiptirler. Bu kodun ilk dk deerlikli 7 biti cihazn aile kodunu, sonraki 48 bit seri numarasn ve son kalan 8 bit ise hata denetim kodunu ierir. Bylelikle tek hatta bulunan her ayr birim kendi kayt kodu ile arlarak ileme tabi tutulurlar. 1-Wire iletiimde bir dier husus ise 1-Wire iletiimde kullanlacak hattn mutlaka pull-up direnciyle Vdd hattna balanma zorunluluudur. 9.2) 1-Wire (Tek Hat) letiim lemleri 1-Wire iletiimde sfr veya bir bilgisi gnderme, cihaza reset atma gibi ilemler bir kereye mahsus tanmlanr ve tm cihazlar ayn mantk erevesinde bu ilemleri kullanr. Ayrca 1-Wire iletiim ilemleri standart ve yksek hzlarda olabilmektedir. 1-Wire iletiimin standart hz 15kbps iken, yksek hz ise 115kbpsdr. 1-Wire protokolnde zamanlamalar olduka nemli olduu iin biz ilemlerimizi standart hza gre yapacaz. 1-Wire protokol ekil-84te de grlecei gibi u admlarla iler; 1-Wire Hat Reseti verilir ROM komutlar gnderilir Fonksiyon komutlar gnderilir

ekil 84 1-Wire Admlar

FxDev.org

Sayfa 93

9.2.1) Reset lemi ekil-85te zaman diyagram grlecek reset ilemi u admlarla gerekleir; Hat mikroilemci tarafndan logic-0 yaplr, 480 ile 640 mikrosaniye beklenir, Mikroilemci pini giri olarak ayarlanr ve hat pull-up direnci sayesinde logic-1 olur, Yaklak 70 mikro saniye sonra hattaki cihaz, hatt logic-0 yapar Bylelikle hatta cihaz olduu alglanr. Hattn tekrar pullup tarafndan logic-1 olmas ise yaklak 420 mikrosaniye gerektirir.

ekil 85 1-Wire Reset lemi Zaman Diyagram

9.2.2) Yazm veya Okuma lemleri 1-Wire protokoln en can alc noktas hatta bilgi gnderip alma ksmdr. Bunun iin zamanlamalar hatta 0 veya 1 gnderme ya da hattan 0 veya 1 bilgisi alma ksmlarnda zellemektedir. ekil-86dan grlecei gibi hatta 0 veya 1 bilgisi gndermek iin aadaki admlar uygulanmaldr; Hat mikrodenetleyici tarafndan logic-0 konumuna getirilir, Hatta 0 yazlmak isteniyorsa 1-2 mikrosaniye sonra, Hatta 1 yazlmak isteniyorsa yaklak 60 mikrosaniye sonra hat mikrodenetleyici tarafndan okuma konuma getirilerek pull-up direncinin hatt logic-1e getirmesi beklenir. Hattan 0 veya 1 bilgisi okumak iin ise aadaki admlar uygulanr; Hat mikrodenetleyici tarafndan logic-0 yaplr ve 5 mikrosaniye beklenir, Mikrodenetleyici hatt okuma moduna getirir, Eer hat yaklak 10 mikrosaniye sonra pullup tarafndan logic-1 olursa cihazn gnderdii bilgi 1, eer hat bu sre sonunda hala logic-0 ise cihazn gnderdii bilgi logic-0dr, Yaklak 60 mikrosaniye sonra bu iletiim son bulur.
FxDev.org Sayfa 94

ekil 86 1-Wire Okuma Yazma Zaman Diyagramlar

Tm bu sylediklerimizi bir ktphane haline getirirsek ileride herhangi bir 1-Wire iletiim protokoln kullanan aygtla iletiim salamak istediimizde kolaylkla hazrladmz dosyay projeye ekleyip istediimizi gerekletirebilir. Yukardaki bilgiler dorultusunda yazdmz ve ek birka zellik daha eklediimiz one_wire.h dosyas aadaki gibi olacaktr.
/* www.FxDev.org * One Wire Kullanm Klavuzu * onewire_reset(); ile one wire aracna reset atp, * geri dn deeriyle aletin hazr olur olmadn kontrol et * onewire_read_byte(DATA); eklinde veri yazdr veya komut gnder * onewire_read_byte(); eklinde okuma yap * www.FxDev.org */ #define TRIS_W TRISA0 //Balantlar #define WIRE RA0 extern extern extern extern extern unsigned char onewire_reset(void); unsigned char onewire_read_bit(void); void onewire_write_bit(unsigned char veri); unsigned int onewire_read_byte(void); void onewire_write_byte(unsigned char data);

Bu fonksiyonlar altran one_wire.c dosyamz ise aadaki gibi olacaktr.


#include <pic.h> #include "one_wire.h" #include "delay.h" unsigned char onewire_reset(void) { unsigned char sonuc;

FxDev.org

Sayfa 95

WIRE=0; TRIS_W=0; DelayUs(250);DelayUs(250); TRIS_W=1; DelayUs(70); sonuc=WIRE; DelayUs(250);DelayUs(250); return sonuc; }

// // // // // // //

Hat sfra ekiliyor Hat k yaplyor 640us>x>480us arasnda bekleniyor Pull-up ykseltmesi bekleniyor 70us bekleniyor 0 Hazr, 1 Hazr deil x>420us'den byk olmal

unsigned char onewire_read_bit(void) { unsigned char veri; WIRE=0; TRIS_W=0; DelayUs(5); TRIS_W=1; DelayUs(10); if(WIRE) veri=1; else veri=0; DelayUs(60); return veri; } void onewire_write_bit(unsigned { if(veri) // { TRIS_W=0; // WIRE=0; DelayUs(5); // TRIS_W=1; // DelayUs(60); // } else // { TRIS_W=0; // WIRE= 0; DelayUs(60); // TRIS_W=1; // } } char veri) 1 gnderiliyor Hat sfrlanyor 5 mikrosaniye bekleniyor Pull-Up'n hatt ykseltmesi bekleniyor 60 mikrosaniye bekleniyor 0 gnderiliyor Hat sfrlanyor 60 mikrosaniye bekleniyor Pull-Up'n hatt ykseltmesi bekleniyor // Hat sfra ekiliyor // 5 mikrosaniye bekleniyor // Pull-Up'n hatt ykseltmesi bekleniyor // 10 mikrosaniye bekleniyor // Hat okunuyor // Okunan veri 1 // Okunan veri 0

unsigned int onewire_read_byte(void) { unsigned char i,veri=0, bitler=1; for(i=0;i<8;i++) { if ( onewire_read_bit() == 1 ) veri |= bitler; bitler=bitler<<=1; } return veri; }

FxDev.org

Sayfa 96

void onewire_write_byte(unsigned char veri) { unsigned char bitler=1, i; for (i=0;i<8;i++) { if (veri&bitler) { onewire_write_bit(1); } else { onewire_write_bit(0); } bitler=bitler<<=1; } }

Kodlarda da grlecei zere zamanlar bire bir alnmaldr. 1-Wire protokolnde dikkat edilmesi gereken en byk husus budur. 9.3) DS18B20 ile 1-Wire (Tek Hat) Uygulamas DS18B20 Maximin kullanclara sunduu, 1-Wire protokol kullanan, klf yaps ekil-87de grlebilecek, 12bit znrle sahip scaklk sensrdr. Tek hattan iletiim kurmas, ok az enerji tketmesi, znrlnn yksek olmas bir ok projede scaklk sensr olarak kullanlmasnn balca nedenidir. -55C ile +125C scaklk lm aral ile gnlk uygulamalarda olduka yeterlidir.

ekil 87 1-Wire Okuma Yazma Zaman Diyagramlar

DS18B20 sensrn altrmak iin 1-Wire protokolnn yannda, sensrn anlayaca kodlara da ihtiyacmz vardr. DS18B20 datasheetinde tm sensr detaylar anlatlsa da biz ksaca scaklk okuma ilemini nasl gerekletirdiimize deineceiz.

FxDev.org

Sayfa 97

Tm 1-Wire cihazlarnda olduu gibi DS18B20de de okuma veya yazm ilemleri ekil-88deki srayla gerekleir. ncelikle reset sinyali cihaza gnderilir, daha sonrasnda ROM ve fonksiyon komutlar ya da bilgileri cihaza gnderilir ya da alnr.

ekil 88 1-Wire Cihaz Bilgi Gnderme Alma Rutinleri

Datasheetin scaklk okuma konusunda bizi ynlendirmesi ekil-89daki gibidir.

ekil 89 Scaklk Okuma in Gerekli lemler

ekil-89daki ynergeleri dikkate alarak DS18B20den scaklk okuma ilemimizi kolayca tamamlayabiliriz. ncelikle ekil-90daki devremizi izelim.

FxDev.org

Sayfa 98

ekil 90 DS18B20 Uygulamas

Uygulama annda dikkat edilmesi gereken bir dier husus ise 4k7lik direntir. Tm 1-Wire cihazlar gibi DS18B20de pull-up dirensiz almamaktadr. Uygulamamz altran Hi-Tech kodu ise aadaki gibi olacaktr.
#include #include #include #include <htc.h> "delay.h" "lcd.h" "one_wire.h" // Gecikme ktphanesi tanmlanyor // LCD ktphanesi tanmlanyor // 1-Wire ktphanesi tanmlanyor

void ds18b20(unsigned int *sicak, unsigned int *onda) { unsigned char sayi1,sayi2,busy=0; while(onewire_reset()); onewire_write_byte(0xCC); onewire_write_byte(0x44); DelayMs(250); DelayMs(250); DelayMs(250); while (onewire_reset()); onewire_write_byte(0xCC); onewire_write_byte(0xBE); sayi2 = onewire_read_byte(); sayi1 = onewire_read_byte(); while (onewire_reset());

FxDev.org

Sayfa 99

*onda=0; *sicak=(sayi1*16)+(sayi2>>4); if(sayi2 & 0x08) *onda=500; if(sayi2 & 0x04) *onda+=250; if(sayi2 & 0x02) *onda+=125; if(sayi2 & 0x01) *onda+=62; } void main(void) { unsigned int sicaklik,onda; PORTB=0x00; // PORTB ve PORTC sfrlanyor PORTC=0x00; TRISB=0x00; // PORTB k TRISC=0x00; // PORTC k lcd_init(); // LCD ilk ayarlar yaplyor

lcd_yaz("Sicaklik:"); for(;;) { lcd_gotoxy(2,1); ds18b20(&sicaklik , &onda); veri_yolla(sicaklik/100+48); veri_yolla((sicaklik%100)/10+48); veri_yolla(sicaklik%10+48); veri_yolla('.'); veri_yolla(onda/100+48); veri_yolla((onda%100)/10+48); veri_yolla(onda%10+48); veri_yolla(0xDF); veri_yolla('C'); } }

Kodlarmz grld gibi gittike karmaklamaktadr. Bu rneimiz Cnin en nemli zelliklerinden biri olan pointer yapsnn da nasl kullanlacana dair rnek tekil etmektedir. LCD ekranmzda derece iaretini karan 0xDF kodudur.

FxDev.org

Sayfa 100

BLM 10 RTC ve DIJITAL POT UYGULAMALARI


10.1) RTC lemleri Pic ile tarih, saat ilemlerini yapmann birok yolu vardr. Bunlardan birisi kendi zaman gecikmelerimizi (DelayMs(), DelayUs() gibi) kullanmak ya da timer kesmelerinden faydalanmaktr. Fakat her iki durumda da scaklk farkllklar, parazitler, programsal sorunlar gibi birok etmenden dolay gnde 1-2 saniyelie varan hatalar oluturabilmektedir. Bunun nne gemek iin ise bu i iin zel olarak gelitirilmi RTC yani Real Time Clock entegreleri kullanlmas gerekmektedir. Biz bu blmde Dallas Maximin rettii DS1302 entegresinin ktphanesini yazarak, tarih saat uygulamas yapacaz. 10.1.1) DS1302 Entegresi ekil-91de DIP soket yaps grlebilecek DS1302 entegresi 2100 ylna kadar tarih tutabilen, 5V ile 2V aralnda alabilen, 2Vta 300nA gibi ok az akm eken, 3-Wire iletiim metodunu kullanan, ayrca ierisinde 31 bytelk eeprom barndran bir yapdr.

ekil 91 DS1302 Entegresi

ekil-90da grlen yapda Vcc2 bacana +5V, Vcc1 bacana g kesilse bile entegrenin almasna devam etmesini salayacak arj edilebilir bir pil, X1 ve X2 bacaklarna entegreye zel 32.768KHz kristal balanr. CE ucu entegreyi aktif etme ucudur. I/O ucu ise hem okuma hem de yazma yapmak iin zelletirilmitir. SCLK ucu ise veri iletim ya da almnda senkronizasyonu salayan bacaktr. Tm alm ya da gnderim ilemleri SCLKnin ykselen kenarnda gereklemektedir. DS1302ye yazm ya da DS1302den okuma yapmak iin ekil-92deki zaman diyagram kullanlr. ekil-92den de grlecei zere DS1302den okuma yapmak iin ncelikle CE=1 olmal. Daha sonra ise ekl-93te grlen ve hangi adresi okumak istediimize dair 1 bytelk bilgi gnderilir. 1 veya 2 mikrosaniye sonra ise mikrodenetleyici okuma moduna alnarak okunmak istenen 1 bytelk bilgi alnr. DS1302ye yazm ilemi de aynen okuma ilemi gibidir; ncelikle CE=1 yaplr, daha sonra yazlmak istenen adres 1 byte eklinde gnderilir ve 1-2 mikrosaniye sonra yazlmak istenen 1 bytelk veri gnderilir.

FxDev.org

Sayfa 101

ekil 92 DS1302 Zaman Diyagramlar

DS1302 kullanlacakken yaplmas gereken ilk ayarlar yledir, tm kodlar ekil-93te grlebilmektedir; - Write Protect yani yazm korumas kaldrlmaldr, (0x8Eye 0x00 yazlmal), - Vcc2 ile Vcc1 arasnda diyot veya diren arj edilecek pile gre ayarlanr (Biz rnek olarak 0x90a 0xA6 yazalm), - Daha sonra saatin altrlmas salanlmaldr. (0x81 okunarak 0 olup olmad kontrol edilir, 0 deilse 0x80e 0 yazlarak saat altrlr)

ekil 93 DS1302 Komutlar

FxDev.org

Sayfa 102

ekil-93te dikkat edilmesi gereken en nemli konu belirli blgeye yazm yaplacanda veya okunacanda birer fazla ya da eksik adres bytelarnn kullanlmasdr. rnein saniye ayarlamas yapmak iin, istediimiz deeri 0x80 adresine yazmakta iken, saniye deerini okumak iin ise 0x81 adresini kullanmak zorundayz. Ayn ey ram iin de sz konusudur, mesela ilk adrese 0xC0 ile yazm yaplabilirken, 0xC1 ile okuma yaplabilmektedir. Tm bunlar dikkate alnarak hazrladmz ktphanemizin ds1302.h dosyas aadaki gibi olacaktr.
/* www.FxDev.org * DS1302 Kullanm Klavuzu * ds1302_init(); ile RTC1302'nin ilk ayarlarn yap * rtc_ram_write(0xC0, 13); eklinde 0x0C ile 0xFC arasndaki hafzaya veri yaz * rtc_ram_read(0xC1); eklinde 0x0C ile 0xFC arasndaki hafzay oku * rtc_set_datetime(GUN,AY,YIL,HAFTA,SAAT,DAKIKA,SANIYE); eklinde zaman ayarla * rtc_get_date(&GUN,&AY,&YIL,&HAFTA); eklinde tarihi al * rtc_get_time(&SAAT,&DAKIKA,&SANIYE); eklinde saati al * www.FxDev.org */ #define TRIS_IO TRISD1 //IO portu neye balysa //TRISxy'deki xy ona gre belirlenmeli #define SCLK RD0 //Balantlar #define IO RD1 #define RST RD2 extern void send_one(void); extern void send_zero(void); extern void ds1302_write(unsigned char ram, unsigned char veri); extern unsigned char ds1302_read(unsigned char ram); extern void ds1302_init(void); extern unsigned char get_bcd(unsigned char veri); extern unsigned char rakam(unsigned char veri); extern void rtc_ram_write(unsigned char address, unsigned char data); extern unsigned char rtc_ram_read(unsigned char address); extern void rtc_set_datetime(unsigned char day,unsigned char mth,unsigned char year,unsigned char dow,unsigned char hr,unsigned char min, unsigned char sec); extern void rtc_get_date(unsigned char *day, unsigned char *mth, unsigned char *year, unsigned char *dow); extern void rtc_get_time(unsigned char *hr, unsigned char *min, unsigned char *sec);

Yukarda da grlecei zere DS1302yi kontrol edebilmek iin olduka fazla fonksiyon kullanlmtr. Hangi fonksiyonun ne ie yarad ise ds1302.h dosyasnn kullanm klavuzu ksmnda aklanmtr. Fonksiyonlarda grlecei zere *hr gibi ifadeler pointer zellikli deikenlerdir. Yerleri picin herhangi bir blgesindedir ve bu yer asla deimez. Okuma yapmak iin ise & ifadesiyle rnein &saat eklinde baka bir deikene, bu belirtilen blgedeki bilgiyi atamak mmkndr.

FxDev.org

Sayfa 103

Tm bu ilemleri yapan ds1302.c dosyas ise aadaki gibi olacaktr.


#include <pic.h> #include "ds1302.h" #include "delay.h" void send_one(void) { TRIS_IO=0; IO=1; DelayUs(2); SCLK=0; DelayUs(2); SCLK=1; DelayUs(2); } void send_zero(void) { TRIS_IO=0; IO=0; DelayUs(2); SCLK=0; DelayUs(2); SCLK=1; DelayUs(2); } void ds1302_write(unsigned char ram, unsigned char veri) { unsigned char i; RST=1; DelayUs(2); for(i=0;i<8;i++) { if((ram>>i)&0x01) send_one(); else send_zero(); } for(i=0;i<8;i++) { if((veri>>i)&0x01) send_one(); else send_zero(); } RST=0; DelayUs(2); SCLK=0; DelayUs(2); } unsigned char ds1302_read(unsigned char ram) { unsigned char i,veri=0; RST=1; DelayUs(2); for(i=0;i<8;i++) {

FxDev.org

Sayfa 104

if((ram>>i)&0x01) send_one(); else send_zero(); } TRIS_IO=1; DelayUs(2); for(i=0;i<8;i++) { SCLK=0; if(IO==1) veri=veri|(1<<i); else veri=veri|(0<<i); SCLK=1; } RST=0; DelayUs(2); TRIS_IO=0; DelayUs(2); SCLK=0; DelayUs(2); return veri; } void ds1302_init(void) { unsigned char x; RST=0; DelayUs(2); SCLK=0; DelayUs(2); ds1302_write(0x8E,0); ds1302_write(0x90,0xA6); x=ds1302_read(0x81); if((x & 0x80)!=0) ds1302_write(0x80,0); } unsigned char get_bcd(unsigned char veri) { unsigned char nibh; unsigned char nibl; nibh=veri/10; nibl=veri-(nibh*10); return((nibh<<4)|nibl); } unsigned char rakam(unsigned char veri) { unsigned char i; i=veri; veri=((i>>4)&0x0F)*10;

FxDev.org

Sayfa 105

veri=veri+(i&0x0F); return veri; } void rtc_ram_write(unsigned char address, unsigned char data) { ds1302_write(address, data); } unsigned char rtc_ram_read(unsigned char address) { return rakam(ds1302_read(address)); } void rtc_set_datetime(unsigned char day,unsigned char mth,unsigned char year,unsigned char dow,unsigned char hr,unsigned char min, unsigned char sec) { ds1302_write(0x86,get_bcd(day)); ds1302_write(0x88,get_bcd(mth)); ds1302_write(0x8c,get_bcd(year)); ds1302_write(0x8a,get_bcd(dow)); ds1302_write(0x84,get_bcd(hr)); ds1302_write(0x82,get_bcd(min)); ds1302_write(0x80,get_bcd(sec)); } void rtc_get_date(unsigned char *day, unsigned char *mth, unsigned char *year, unsigned char *dow) { *day = rakam(ds1302_read(0x87)); *mth = rakam(ds1302_read(0x89)); *year = rakam(ds1302_read(0x8d)); *dow = rakam(ds1302_read(0x8b)); } void rtc_get_time(unsigned char *hr, unsigned char *min, unsigned char *sec) { *hr = rakam(ds1302_read(0x85)); *min = rakam(ds1302_read(0x83)); *sec = rakam(ds1302_read(0x81)); }

Yukarda da grlecei zere ktphane dosyas olduka uzundur. Aslnda ilemlere bakldnda o kadar da karmak ilemlerin yaplmad grlecektir. Bu ilemleri ksaltmak iin daha nce grdmz SPI haberlemesi kullanlabilir.

FxDev.org

Sayfa 106

10.1.2) DS1302 Uygulamas Bu uygulamamzda DS1302 kullanarak LCD ile tarih saat uygulamas yapacaz. Tarihimizi 31.12.2009 saat 23:59:50 Perembeye ayarlayp tarihin tam deime ann greceiz. Ayrca DS1302nin eepromuna da admz kaydedeceiz. Uygulamamzn kodlarn yazmadan nce ekil-94teki devreyi iziyoruz.

ekil 94 DS18B20 Uygulamas

stediimiz ilemi yerine getiren kodumuz ise aadaki gibi olacaktr.


#include #include #include #include <htc.h> "delay.h" "lcd.h" "ds1302.h" // Gecikme ktphanesi tanmlanyor // LCD ktphanesi tanmlanyor // ds1302 ktphanesi tanmlanyor

void main(void) { unsigned char gun,ay,yil,hafta,saat,dakika,saniye; PORTB=0x00; // PORTB ve PORTC sfrlanyor PORTC=0x00; TRISB=0x00; // PORTB k TRISC=0x00; // PORTC k lcd_init(); ds1302_init(); // LCD ilk ayarlar yaplyor // ds1302 ilk ayarlar yaplyor

//31.12.2009 Perembe, 23:59:50'a ayarlanyor rtc_set_datetime(31,12,9,5,23,59,50); //smimizi eeproma yazyoruz rtc_ram_write(0xC0, 'F'); rtc_ram_write(0xC2, 'I'); rtc_ram_write(0xC4, 'R'); rtc_ram_write(0xC6, 'A'); rtc_ram_write(0xC8, 'T');

FxDev.org

Sayfa 107

for(;;) { // Tarih ve saat ds1302'den alnyor rtc_get_date(&gun,&ay,&yil,&hafta); rtc_get_time(&saat,&dakika,&saniye); lcd_gotoxy(1,1); // Tarih ve saat LCD'e yazdrlyor veri_yolla(gun/10+48); veri_yolla(gun%10+48); veri_yolla('.'); veri_yolla(ay/10+48); veri_yolla(ay%10+48); veri_yolla('.'); veri_yolla(yil/10+48); veri_yolla(yil%10+48); switch(hafta) { case 1: lcd_yaz(" PAZR");break; case 2: lcd_yaz(" PZTS");break; case 3: lcd_yaz(" SALI");break; case 4: lcd_yaz(" CRSM");break; case 5: lcd_yaz(" PERS");break; case 6: lcd_yaz(" CUMA");break; case 7: lcd_yaz(" CMTS");break; } lcd_gotoxy(2,1); veri_yolla(saat/10+48); veri_yolla(saat%10+48); veri_yolla(':'); veri_yolla(dakika/10+48); veri_yolla(dakika%10+48); veri_yolla(':'); veri_yolla(saniye/10+48); veri_yolla(saniye%10+48); } }

Burada dikkat edilmesi gereken nokta switch/case yapsdr. DS1302 haftann balang gnn pazar gn olarak kabul etmektedir. Dolays ile ayarlamalarmz yaparken buna dikkat edilmesi gerekmektedir. Ayrca simlasyonu duraklatp DS1302nin ramine bakarsanz isminizin ekil-95tekine benzer ekilde yazldn grebilirsiniz.

ekil 95 DS1302 Eepromu

Bu uygulamaya bir nceki blmde grdmz DS18B20yi de ekleyerek scaklk/tarih uygulamas yapabilirsiniz.

FxDev.org

Sayfa 108

10.2) DS1868 ile Dijital Pot lemi Dijital potansiyometreler ayn anolog potansiyometlerin yapt ii yani belirli aralklar arasnda diren deiiklii ilemini yapmaktadrlar. Bu i iin zelletirilmi bir ok entegre mevcuttur. Biz Dallas Maxim firmasnn rettii DS1868 dijital potansiyometresi ile ilemimizi gerekletireceiz. ekil-96da DIP yaps grlebilecek DS1868in iinde 256 deiik pozisyonda ayarlanabilen iki adet potansiyometre mevcuttur.DS1868in potlar sahip olduu modellere gre 10k, 50k veya 150klk deerlere sahiptirler. DS1868 de DS1302 gibi 3-Wire iletiim protokol ile kontrol edilmektedir.

ekil 96 DS18B20 Uygulamas

ekil-96da grlen pinlerin grevleri ise yledir; Vb H1 L1 W1 RST CLK GND DQ Cout LO H0 W0 Sout Vcc : Alt tabaka n gerilimi : 1. Potansiyometrenin st ucu : 1. Potansiyometrenin alt ucu : 1. Potansiyometrenin orta ucu : Seri port reset girii : Saat girii : Toprak ucu : Seri port data girii : Kaskat port k : 0. Potansiyometrenin alt ucu : 0. Potansiyometrenin st ucu : 0. Potansiyometrenin orta ucu : 0. ve 1. potansiyometreler seri balanrsa ortak u k : +5V besleme ucu

DS1868i srmek olduka basittir. ekil-97de iletiim zaman diyagramndan da grlecei gibi DS1868i kullanmak olduka basittir.

FxDev.org

Sayfa 109

ekil 97 DS1868 Zaman Diyagram

ekil-97de de grlecei zere ncelikle RST=1 yaplp, cihaz reset durumundan karlmaldr. Daha sonra srasyla stack biti, 1. potansiyometrenin 8 bitlik kodu daha sonrasnda ise 0. Potansiyometrenin 8 bitlik kodu saat darbelerinin ykselen kenarlarnda gnderilmelidir. Buradaki stack select bir ekil-98de ki gibi potansiyometreler seri balandnda ortak ucu belirlemek iin kullanlmaktadr. Normal ilemlerde stack bitinin 1 ya da sfr olmas bir eyi deitirmemektedir.

ekil 98 Potansiyometrelerin Seri Balanmas

8 bitlik potansiyometre ayar bize 1/256 orannda kontrol imkan salar. rnein 150klk DS1868 kullandmzda tek bir art; 150000/256=585,938 ohmluk arta denk gelmektedir. Dolays ile hesaplarmz bu deere gre ayarlamalyz. DS1868 dijital potansiyometresi kullanm bir ktphane haline getirirsek ds1868.h dosyas aadaki gibi olacaktr.
/* www.FxDev.org * DS1868 Kullanm Klavuzu * ds1868_pot(POT, DEGER, STACK); eklinde kullan * POT 1'den byk olamaz * www.FxDev.org */ #define DQ RB5 #define CLK RB6 #define RST RB7

FxDev.org

Sayfa 110

extern void one(void); extern void zero(void); extern ds1868_pot(unsigned char pot, unsigned char deger,unsigned char stack);

Yukarda da grld zere ktphane balmz olduka sadedir. Bu fonksiyonlar altran ds1868.c ise aadaki gibi olacaktr.
#include <pic.h> #include "ds1868.h" #include "delay.h" void one(void) { DQ=1; DelayUs(2); CLK=1; DelayUs(2); CLK=0; DelayUs(2); } void zero(void) { DQ=0; DelayUs(2); CLK=1; DelayUs(2); CLK=0; DelayUs(2); } ds1868_pot(unsigned char pot, unsigned char deger,unsigned char stack) { unsigned char i, veri1, veri2, kay=0x80; if(pot>1) return; if(pot) veri1=deger; else veri2=deger; RST=1; DelayUs(2); if(stack) one(); else zero(); for(i=0;i<8;i++) { if(veri1&kay) one(); else zero(); kay=kay>>1; } kay=0x80;

FxDev.org

Sayfa 111

for(i=0;i<8;i++) { if(veri2&kay) one(); else zero(); kay=kay>>1; } DelayUs(2); RST=0; }

Grlecei zere ktphanemiz olduka sadedir. Bu da DS1868in kullanm kolaylndan kaynaklanmaktadr. 10.2) DS1868 ile Dijital Pot Uygulamas Bu uygulamamzda DS1868 kullanarak dijital potun L0-W0 ve L1-W1 arasnda deien ohm deerlerini grelim. ncelikle ekil-99daki devremizi izelim.

ekil 99 DS1868 Uygulamas

ekil-99da grlen devreyi altracak kodlarmz ise aadaki gibidir.


#include <htc.h> #include "delay.h" #include "ds1868.h" void main(void) { unsigned i=0,j=0; ADCON1=0x07; PORTA=0x00; PORTB=0x00; // Gecikme ktphanesi tanmlanyor // ds1868 ktphanesi tanmlanyor

// PORTB ve PORTA sfrlanyor

FxDev.org

Sayfa 112

TRISA=0x0F; TRISB=0x00;

// PORTB k

while(1) // Sonsuz dng { if (RA0) // Eer Pot reset butonuna basld ise { ds1868_pot(0,0,0); ds1868_pot(1,0,0); i=0; j=0; } if (!RA1) // 0. Potansiyometre seilmi ise { if (RA2) // Arttir butonuna baslm ise { i++; // i deerini bir arttr ds1868_pot(0,i,0); // 0. potansiyometreyi i deerine ayarla while(RA2); // Butondan el ekile kadar bekle } if (RA3 && (i!=0)) // Azalt butonuna baslm ise ve { // i deeri 0 deil ise i--; // i deerini bir azalt ds1868_pot(0,i,0); // 0. potansiyometreyi i deerine ayarla while(RA3); // Butondan el ekile kadar bekle } } else // 1. potansiyometre seilmi ise { if (RA2) // Arttir butonuna baslm ise { j++; // j deerini bir arttr // 1. potansiyometreyi j deerine ayarla ds1868_pot(1,j,0); while(RA2); // Butondan el ekile kadar bekle } if (RA3 && (j!=0)) // Azalt butonuna baslm ise ve { // j deeri 0 deil ise j--; // j deerini bir azalt ds1868_pot(1,j,0); // 1. potansiyometreyi j deerine ayarla while(RA3); // Butondan el ekile kadar bekle } } } }

Kodlarmz altrdmzda DS1868in kaydedicileri ise ekil-100deki gibi olacaktr.

ekil 100 DS1868 Kaydedici Deeleri

FxDev.org

Sayfa 113

BLM 11 2x20 LCD KULLANIMI, 74HC595 ENTEGRES ve 3-WIRE LCD LEMLER


11.1) 2x20 LCD Kullanm 2x20 LCD, daha nceki blmlerde bahsettiimiz 2x16 LCDden farkl olarak ekstra 8 satr birimine daha sahip yapsdr. Genel itibari ile 2x16 LCD kullanmndan tek fark yazlabilecek alann bykldr. Dier tm zellikleri 2x16 LCD ile ayndr. 2x16 LCD ktphanesinde deiecek tek fonksiyon lcd_gotoxy(y,x) fonksiyonudur. Bu fonksiyon aadaki kodlarla deitirilmelidir.
void lcd_gotoxy(unsigned char x,unsigned char y) { if(x==1) lcd_komut(0x80+((y-1)%20)); else lcd_komut(0xC0+((y-1)%20)); }

Eer 2x16daki ktphane dosyasndaki fonksiyona bakarsanz tek farkn %16 blm oran yerin %20 olmasdr. 11.1.1) 2x20 LCD Uygulamas Ktphanemizi yukardaki gibi dzenledikten sonra st ve alt satra istediimiz yazy yazdralm. ncelikle ekil-101deki devremizi izelim.

ekil 101 2x20 LCD Uygulamas

FxDev.org

Sayfa 114

ekil-101deki ilemi yapan kodumuz ise aadaki gibidir.


#include <htc.h> #include "delay.h" #include "lcd.h" void main(void) { PORTB=0x00; TRISB=0x00; TRISC=0x00; lcd_init(); lcd_yaz(" www.FxDev.org Sunar!"); lcd_gotoxy(2,1); lcd_yaz(" 2x20 LCD Denemesi"); for(;;); } // Gecikme ktphanesi tanmlanyor // ds1868 ktphanesi tanmlanyor

// PORTB ve PORTC k

Grld gibi kodlarmz olduka sadedir. Uygulamann gerekletirilmi hali ise ekil102de grlebilmektedir.

ekil 102 2x20 LCD Uygulamasnn Gereklenmesi

11.2) 74HC595 Entegresi ekil-103te grlebilecek 74HC595 entegresi 100Mhze kadar alabilen 8 bitlik bir shift registerdir. Bu zellii sayesinde 74HC595 entegresi ayrca DS ucundan girilen seri bilgileri istenildii an Q0..Q7 ularndan paralel bilgi olarak alnmasna olanak salar.

ekil 103 74HC595 DIP Yaps

FxDev.org

Sayfa 115

ekil-103te grlen pinlerin grevleri ise yledir; Q0..Q7- Paralel klar DS - Seri data girii OE - k ak SH_CP - Shift register saat kayna ST_CP - Kaydedici registerin saat kayna MR - Reset ucu Q7 - Seri data k GND - Toprak ucu Vcc - +5V 74HC595in alma mant ise yledir; - OE ucu toprak hattna, MR ucu ise +5Va balanr, - DS ucundan seri bilgi girii SH_CPnin her ykselen kenarnda shift edilerek kaydedici registere yazlr, - 8 kmz olduu iin bu ilem 8 kez gerekletirilir, - Tm bu ilemler gerekleirken Q0..Q7 klarnda bir deiiklik olmaz, - Son olarak kaydrma ilemi bittiinde kaydedici registerdeki deerin Q0..Q7 ularna yansmas iin ST_CP ucuna ykselen kenarda sinyal verilir, - Son olarak Q0..Q7 ularnda, ilk giren bilgi Q7 de son giren bilgi ise Q0da olmak koulu ile sralama tamamlanr. rnek olarak 0xA5nn ulara iletimini rnek verelim; 0xA5=0b10101001 olur. lk giren Q7de olacana gre ncelikle A5in en yksek biti olan 7. Biti gndermeliyiz. Daha sonra ise 6,5,4.. eklinde bunu srdrmeliyiz. C ileminde bunu adaki fonksiyon ile salayabiliriz.
void three_wire_control(unsigned char temp) { char i; Enable=0; for(i=0;i<8;i++) { Clock=0; if((temp<<i)&0x80) DataIO=1; else DataIO=0; Clock=1; } Enable=1; }

lem takip edilirse ncelikle 7. bitin daha sonra ise dier dk bitlerin, en sonunda ise 0. bitin ka gnderildii grlebilir. Bu ekilde port geniletme ilemimizide (3ten 8e) gerekletirmi olduk.

FxDev.org

Sayfa 116

11.2.1) 74HC595 ile 7-Segment Srm Fonksiyonumuzu tamamladktan sonra artk balant ularna dikkat ederek istediimiz 8 bitlik her arac kontrol edebiliriz. Bu uygulamada bir adet 7-Segment ile 0-9 saym ilemi yapacaz. ncelikle ekil-104teki devremizi izelim.

ekil 104 74HC595 ile 7-Segment Uygulamas

Tanmladmz fonksiyonu kullanarak yazdmz kod ise aadaki gibi olacaktr.


#include <htc.h> #include "delay.h" #define Clock #define DataIO #define Enable RB0 RB1 RB2 // Gecikme ktphanesi tanmlanyor //74LS595 Clk girii, ykselen kenar //74LS595 Data girii //74LS595 Enable girii

// Seven segment sabitleri const unsigned char segment[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; void three_wire_control(unsigned char temp) { char i; Enable=0; for(i=0;i<8;i++) { Clock=0; if((temp<<i)&0x80) DataIO=1; else DataIO=0; Clock=1; } Enable=1; } void main(void) { char i; // 3-Wire ktphanesi

FxDev.org

Sayfa 117

PORTB=0x00; TRISB=0x00;

// PORTB k

for(;;) { three_wire_control(segment[i]); DelayMs(250);DelayMs(250); i++; if(i>9) i=0; } }

// Seven segment // bilgisi gnderiliyor

Burada dikkat edilmesi gereken konu 7-segmentin ortak katot kullanlm olmasdr. 11.2.2) 74HC595 ile LCD Srm Grld zere 74HC595 ile 3-Wire iletiimini kullanmak olduka kolaydr. Fakat bu ilemi LCDde gerekletirmek iin ncelikle LCD ktphanesinde baz deiiklikler yapmalyz. Yapacamz modifiyenin rneini tek fonksiyonda gsterirsek, kodlarmz aadaki gibi olacaktr.
void lcd_komut(unsigned char c) { unsigned char temp; temp = 0x00; temp |= 0x04; three_wire_control(temp); temp |= ( c & 0xF0 ); three_wire_control(temp); temp &= 0xF0; three_wire_control(temp); lcd_busy(); temp = 0x00; temp |= 0x04; three_wire_control(temp); temp |= ( (c & 0x0F)<<4 ); three_wire_control(temp); temp &= 0xF0; three_wire_control(temp); lcd_busy(); }

Kodlar dikkatle incelerseniz aslnda yaplan iin tm giri klar 8 bit haline getirmek olduu rahatlkla grlebilir. Tm kodlar bu ekilde modifiye edip, son olarak 3-Wire fonksiyonumuzu da ekleyip ktphane haline getirirsek three_wire_lcd.h dosyamz aadaki gibi olacaktr.
/* www.FxDev.org * 3 Kablolu 2x16 LCD Kullanm Klavuzu * 74LS595 ile birlikte kullanlmaldr. * RW/RS/EN pinleri ise srasyla 74LS595'in Q0.,Q1. ve Q2. pinlerine * D4,D5,D6,D7 pinleri srasyla 74LS595'in Q4.,Q5.,Q6. ve Q7. pinlerine balanmaldr. * Cursor kapaldr. * * lcd_init(); ile LCD'nin ilk ayarlarn yap

FxDev.org

Sayfa 118

* * * * * */

lcd_clear(); ile LCD'yi sil lcd_yaz("deneme"); eklinde yaz yazdr. veri_yolla('F'); eklinde tek ascii kodu yazdr. lcd_gotoxy(1,13); eklinde LCD'nin istenilen yerine git. www.FxDev.org RB0 RB1 RB2 //74LS595 Clk girii, ykselen kenar //74LS595 Data girii //74LS595 Enable girii

#define Clock #define DataIO #define Enable

/* LCD'de kullanilan komutlarin tanimlamasi*/ #define Sil 1 // Ekrani temizler #define BasaDon 2 // Imleci sol st kseye getirir #define SolaYaz 4 // Imlecin belirttigi adres azalarak gider #define SagaYaz 6 // Imlecin belirttigi adres artarak gider #define ImlecGizle 12 // Gstergeyi ac, kursor grnmesin #define ImlecAltta 14 // Yanip snen blok kursor #define ImlecYanSon 15 // Yanip snen blok kursor #define ImlecGeri 16 // Kursor bir karakter geri kaydir #define KaydirSaga 24 // Gstergeyi bir karakter saga kaydir #define KaydirSola 28 // Gstergeyi bir karakter sola kaydir #define EkraniKapat 8 // Gstergeyi 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 Seimi */ #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 extern extern extern extern extern extern void void void void void void void three_wire_control(unsigned char temp); veri_yolla(unsigned char); lcd_clear(void); lcd_yaz(const char * s); lcd_gotoxy(unsigned char x, unsigned char y); lcd_init(void); lcd_komut(unsigned char c);

Tm bu fonksiyonlar yerine getiren three_wire_lcd.c dosyamz ise aadaki gibi olacaktr.


#include #include #include <pic.h> "three_wire_lcd.h" "delay.h"

void three_wire_control(unsigned char temp) { char i; Enable=0; for(i=0;i<8;i++) { Clock=0; if((temp<<i)&0x80) DataIO=1; else DataIO=0; Clock=1;

FxDev.org

Sayfa 119

} Enable=1; } void lcd_busy(void) { DelayUs(100); } void lcd_komut(unsigned char c) { unsigned char temp; temp = 0x00; temp |= 0x04; three_wire_control(temp); temp |= ( c & 0xF0 ); three_wire_control(temp); temp &= 0xF0; three_wire_control(temp); lcd_busy(); temp = 0x00; temp |= 0x04; three_wire_control(temp); temp |= ( (c & 0x0F)<<4 ); three_wire_control(temp); temp &= 0xF0; three_wire_control(temp); lcd_busy(); } void veri_yolla(unsigned char c) { unsigned char temp; temp = 0x00; temp |= 0x05; three_wire_control(temp); temp |= ( c & 0xF0 ); three_wire_control(temp); temp &= 0xF1; three_wire_control(temp); lcd_busy(); temp = 0x00; temp |= 0x05; three_wire_control(temp); temp |= ( (c & 0x0F)<<4 ); three_wire_control(temp); temp &= 0xF1; three_wire_control(temp); lcd_busy(); } void lcd_clear(void) { lcd_komut(0x1); DelayMs(2); } void lcd_yaz(const char * s) { lcd_busy(); while(*s)

FxDev.org

Sayfa 120

veri_yolla(*s++); } void lcd_gotoxy(unsigned char x,unsigned char y) { if(x==1) lcd_komut(0x80+((y-1)%20)); else lcd_komut(0xC0+((y-1)%20)); } void lcd_init() { unsigned char temp=0; three_wire_control(temp); DelayMs(15); lcd_komut(0x02); DelayMs(2); lcd_komut(CiftSatir4Bit); lcd_komut(SagaYaz); lcd_komut(ImlecGizle); lcd_clear(); lcd_komut(BirinciSatir); }

Grlecei gibi kodlar kark gelebilir. Fakat biraz incelediinizde iin o kadar da karmak olmadn greceksiniz. Ktphanemizi tanmladktan sonra, istediimiz herhangi bir yazy LCDmize yazdralm. ncelikle ekil-105teki devreyi iziyoruz.

ekil 105 74HC595 ile 2x16 LCD Uygulamas

FxDev.org

Sayfa 121

ekil-105teki devreyi altran kodumuz ise aadadr.


#include <htc.h> #include "delay.h" #include "three_wire_lcd.h" void main(void) { PORTB=0x00; TRISB=0x00; lcd_init(); // Gecikme ktphanesi tanmlanyor // 3-Wire LCD ktphanesi tanmlanyor

// PORTB k // LCD ilk ayarlar yaplyor

lcd_yaz(" FxDev.org Sunar"); lcd_gotoxy(2,1); lcd_yaz(" 3-Wired LCD"); for(;;); }

Grdld gibi kodlarmzn dier LCD srmeden hibir fark yoktur. Devrenin gereklenmi halini (LCD ve 74HC595i) ise ekil-106da grebilirsiniz.

ekil 105 74HC595 ile 2x16 LCD Uygulamasnn Gereklenmesi

FxDev.org

Sayfa 122

BLM 12 PS/2 KLAVYE KULLANIMI


12.1) Klavye alma Mant ve Ktphanesi
lk kez yaz makinesinin mucidi olan Christopher Latham Sholes tarafndan 1867de ortaya

kan klavye birimi o gnden gnmze kadar teknolojiye ayak uydurmas dnda pek bir deiiklie uramad. Bugn birok bilgisayarda kullanlan Q klavyenin de mucidi olan Sholes, bu kadar karmak harf dizilimini mhendislie aykr olarak yazlarn daha yava yazlmas dolays ile makinelerinin daha az bozulmas iin oluturdu. Klavye alma mant olduka basittir. Her tu basmnda klavye kendine has 8 bitlik zel tu bilgilerini gnderir, bu kodlar zlerek hangi tuun basld karar alnr ve kullanlr. Baslan tu dahilinde hangi bilgilerin bizlere gnderildii ekil-106daki tablolardan grlebilir.

ekil 1706 - Klavye zel Kodlar

Klavyeler eitli balant ekillerine sahip olsalar da dnya apnda en ok kullanlan balant ekillerinden biri DIN ya da PS/2dir. ekil-107de PS/2 yapsnn giri birimi grlmektedir.

ekil 107 - PS/2 Balant ekli

ekil-107de de grlecei zere PS/2 yapsnda 6 farkl balant noktas bulunmaktadr. Srasyla ka numaral pinin ne ie yaradn syleyecek olursak;
FxDev.org Sayfa 123

1- Data hattdr 2- Bo hat, balant yaplmayacak 3- GND, toprak hat ucudur 4- VDD, g ucudur, +5V verilecek hattr 5- Clk ucudur, iletiim saati buradan verilir 6- Bo hat, balant yaplmayacak nemli not: Bu yap giri birimi olduu iin klavyeden direk hat ekilecekse, tam simetriine gre ilem yaplmaldr. Aksi takdirde klavyeniz zarar grebilir. Biz iletiimimizi klavyeden kaynamza doru yapacamz iin ekil-108deki zaman diyagramn kullanacaz. Grld zere klavye her bir tu bilgisi iin ekil-108de grlen 20 ile 30 Khz arasnda saat darbesi ve data sinyali retmektedir.

ekil 108 - Kklavyeden Kaynaa

ekil-108deki zaman diyagramn yorumlayacak olursak; - Klavyeden hibir tua baslmaz iken saat ve data yolu yksek seviyede duracaktr. - Klavyeden herhangi bir tua basldnda ilk saat darbesinde data hatt sfra ekilir. - Daha sonraki 8 saat darbesinde tua ait, ekil-106daki zel kodlardan biri gnderilir. - Daha sonra parity biti gnderilir, klavye tek parity sistemini kullanr - En sonda da iletiimin bittii ynnde 11. Saat darbesinde biti bilgisi gnderilerek iletiim sonlandrlr. Burada belirttiimiz bu yapy anlamak iin aadaki C fonksiyonu kullanlabilir. Parity bizim iin nemli olmadndan kontrol ihtiyac duyulmamtr. Fonksiyon geri dn olarak klavyeden alglad zel kodu gnderecektir.
unsigned char get_byte(void) { char i; unsigned char veri=0; for(i=0;i<11;i++) { while(Clock); if( (i<9) && (i>0)) { veri=veri>>1; if(Data==1) veri=veri | 0x80; } while(!Clock); } return veri; //Alglanan } //11 bitlik veri gelecek //lk nce Clock=1 olmal //2->9 bitler

//Son olarak Clock=0 olmal deer gnderiliyor

FxDev.org

Sayfa 124

Klavye iin yukardaki kodu yazmak bal bana yeterli deildir. Klavyede her tua basldnda o tuun zel kodu, tu brakldnda o tua ait baka bir kod ve tekrar o tuun kendi kodu gnderilir. rnein baz tulara baslp brakldnda aadaki kodlar srasyla klavyeden gnderilecektir; A: 0x1C -> 0xF0 -> 0x1C H: 0x33 -> 0xF0 -> 0x33 1: 0x16 -> 0xF0 -> 0x16 Grld zere 0xF0 burada kilit rol oynamaktadr. Eer sadece yukardaki C kodunu kullanacak olursak, tek tua bastmzda sanki 3 ayr tua basm gibi olacaz. Bunu engellemek iin aadaki kod sistemini kullanabiliriz.
data=get_byte(); while(get_byte()==0xF0);

Burada alglama ilemini ister 0xF0dan nce, isterseniz de sonda yapabiliriz. Daha sonras ise algladmz kodun ASCI karln bulmaktan ibarettir. Tm bunlar dnerek oluturacamz ktphane dosyasnn keyboard.h dosyas aadaki gibi olacaktr.
/* www.FxDev.org * Keyboard Kullanm Klavuzu * Shift ve Capslock tuu ile byk, kk ve tularn ikinci grevleri kullanlabilir. * i=get_byte(); eklinde klavyeden gelen byte'lk veriler okunur. * i=keyboard(); eklinde klavyeden okunan kod direk ascii olarak gnderilir. * www.FxDev.org */ #define Clock RA0 //Pin tanmlamalar #define Data RA1 extern unsigned char get_byte(void); extern unsigned char keyboard(void);

Bu fonksiyonlar altran keyboard.c dosyamz ise yle olacaktr.


#include #include <pic.h> "keyboard.h"

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},

FxDev.org

Sayfa 125

{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} }; const unsigned char buyuk[67][2]={ {0x0d,0x7e},{0x0e,''},{0x15,'Q'},{0x16,'!'}, {0x1a,'Z'},{0x1b,'S'},{0x1c,'A'},{0x1d,'W'}, {0x1e,'"'},{0x21,'C'},{0x22,'X'},{0x23,'D'}, {0x24,'E'},{0x25,'+'},{0x26,'^'},{0x29,' '}, {0x2a,'V'},{0x2b,'F'},{0x2c,'T'},{0x2d,'R'}, {0x2e,'%'},{0x31,'N'},{0x32,'B'},{0x33,'H'}, {0x34,'G'},{0x35,'Y'},{0x36,'&'},{0x39,'L'}, {0x3a,'M'},{0x3b,'J'},{0x3c,'U'},{0x3d,'/'}, {0x3e,'('},{0x41,0},{0x42,'K'},{0x43,'I'}, {0x44,'O'},{0x45,'='},{0x46,')'},{0x49,7}, {0x4a,':'},{0x4b,'L'},{0x4c,1},{0x4d,'P'}, {0x4e,'?'},{0x52,6},{0x54,5},{0x55,0x2d}, {0x5a,0xa3},{0x5b,4},{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} }; 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( (i<9) && (i>0)) //2->9 bitler { veri=veri>>1; if(Data==1) veri=veri | 0x80; } while(!Clock); //Son olarak Clock=0 olmal } return veri; //Alglanan deer gnderiliyor } 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 basld shift=!shift; //Capslock gibi alacak if(data==0x58) shift=!shift; //Capslock'a basldysa

for(i=0;kucuk[i][0]!=data && kucuk[i][0]; i++);

FxDev.org

Sayfa 126

//Tuun ascii karl bulunuyor if(kucuk[i][0]==data) //Data ascii tablolarmzda var m baklyor { if(shift==0) //Capslock ak deilse kk harf, aksa byk harfin ascii deeri geri gnderiliyor return kucuk[i][1]; else return buyuk[i][1]; } }

Kodlarmzda da greceimiz zere burada matris dizi mantn kullandk. Klavye kodu deerlerinin neler olduunu internetten bulup sizde istediiniz ekilde dizi oluturabilirsiniz. 12.2) Klavye Uygulamas Bu uygulamada klavyede baslan herhangi bir tuun LCDde grnmesini salayacaz. ncelikle ekil-109daki devremizi iziyoruz.

ekil 109 Klavye Uygulamas

Proteusta klavye almad iin onun yerine CLK ve Data ular giri olarak verilmitir. Simlasyon yapmak isterseniz ekil-108deki zaman diyagramndaki gibi sinyalleri elle vererek simlasyon yapabilirsiniz.

FxDev.org

Sayfa 127

ekil-109deki devreyi altran kodumuz ise aadaki gibidir.


#include #include #include #include <htc.h> "delay.h" "lcd.h" "keyboard.h"

// LCD ve Klavye ktphaneleri // Tanmlanyor

void main(void) { unsigned char i,j; PORTB=0x00; PORTC=0x00; TRISB=0x00; // LCD iin k, klavye iin giriler TRISC=0x30; // tanmlanyor lcd_init(); lcd_yaz("FxDev.org Sunar!"); lcd_gotoxy(2,1); lcd_yaz("Klavye Denemesi"); DelayMs(250);DelayMs(250);DelayMs(250);DelayMs(250); lcd_clear(); lcd_komut(ImlecAltta); // mlec alta geecek for(;;) { i=keyboard(); j++; // Klavyeden baslan karakterler // LCD'ye yazlyor

if(j==17) { lcd_gotoxy(2,1); } else if(j==33) { lcd_clear(); lcd_gotoxy(1,1); j=0; } veri_yolla(i); } }

Grld gibi kodlarmz olduka sadedir. Eer projeniz 40-50 buton gerektiren bir devre ise, bu ekilde klavye kullanmak kolay olabilir.

FxDev.org

Sayfa 128

BLM 13 GRAFK LCD


13) Hi-Tech GLCD lemleri Grafik LCDler yaplarnda karakter LCDler gibi hazr karakterler bulundurmayan, fakat karakter LCDlerin yapamad grafik izimleri rahatlkla yapabilen LCDlerdir. Grafik LCDlerin altrlmas dier LCDlere gre zordur. GLCDlerin alma mantklar ise yledir, belirli komutlarla istenilen blgesi yazlabilen bo bir 124x64 bitlik DDRAMin istenilen alan yazldnda GLCDde de istenilen blge yazlm olur. rnein DDRAM blgesinin 23x12. adresi 1 yapldnda GLCDde de 23x12. pixel koyular. Bu ekilde istenilen tm ilemler GLCDde yaptrlabilir. Piyasada olduka fazla eitte GLCD bulmak mmkndr. Gerek piyasada trevlerinin ok oluu, gerek dier GLCDlere nazaran kullanm kolay olmas nedeniyle gnmzde en ok tercih edilen ekil-110da da grlebilecek GLCD, 124x64 pixel boyutunda olan KS0108 GLCDsidir.

ekil 109 KS0108 GLCD

Piyasada farkl ulara sahip modeller olsa da GLCDlerin genel bacak balantlar aadaki gibidir; Vss Vdd D/I R/W EN DB0..DB7 CS1 CS2 RES Vee K A
FxDev.org

- Toprak ucu - +5V - Data veya komut verme ucu - Yazma veya okuma yapldn belirten u - Yetki verme ucu - Data giri ular - lk 64x64 bitlik chipi seme biti - kinci 64x64 bitlik chipi seme biti - Reset ucu - Kontrast iin gerekli -10V ucu - Backlight eksi ucu - Backlight art ucu
Sayfa 129

Yukardaki u balantlar GLCDden GLCDye farkllk gsterebileceinden doru balant bacaklar iin GLCDnin datasheetine bakmalsnz. KS0108de dikkat edilmesi gereken bir noktada hafza biriminin 64x64 eklinde iki paradan olumasdr. CS1 seili, CS2 seili deilken bilgiler ilk 64x64 birimlik alan iin geerliyken, tam tersi durumunda gnderilen ya da alnan bilgiler ikinci alan kapsamaktadr. Dolays ile kod yazlrken buna ok dikkat edilmelidir.

Yukardaki tabloda ise KS0108i kontrol edebilmemiz iin gerekli kodlar bulunmaktadr. GLCD de grnt elde etmek iin gerekli olan fonksiyonlar ise yledir; - KS0108 ilk ayarlar : GLCDyi temizlemek iin de kullanlabilir, GLCD il ayarlarn yapar. - KS0108e yazm : GLCDye herhangi bir bilgiyi yazmaya yarar - KS0108den okuma : GLCDden herhangi bir bilginin okunmasna yarar - KS0108 pixel : GLCDnin herhangi bir pixelini aktif veya pasif yapmaya yarar Yukardaki drt fonksiyonla istenilen her trl ekil, eitli matematiksel fonksiyonlar kullanlarak izilebilir. Tablodaki nergeleri dikkate alarak yazdmz ks0108.h dosyas aadaki gibi olacaktr.
/* www.FxDev.org * KS0108 GLCD Kullanm Klavuzu * ks0108_init(); ile ilk ayarlar yap * ks0108_write(0,0x55); eklinde veri yaz * veri=ks0108_read(0); eklinde veri oku * ks0108_pixel(1,1,1) eklinde herhangi bir pixeli a ya da kapa * ks0108_fill(1); eklinde tm ekran pixelleri alr ya da kapanr * ks0108_line(10,10,20,50,1); eklinde belirtilen koordinatlarda izgi iz * ks0108_rect(10,10,20,20,1,1); eklinde belirtilen koordinatlarda dikdrtgen iz * ks0108_circle(10,10,10,1,1); eklinde daire iz * www.FxDev.org */ #define TRIS_GLCD TRISC //Pin tanmlamalar

FxDev.org

Sayfa 130

#define #define #define #define #define #define #define

GLCD_PORT CS1 CS2 DI RW EN RST

PORTC RB0 RB1 RB2 RB3 RB4 RB5

// RS'de olabilir

extern void ks0108_init(void); extern void ks0108_write(unsigned char chip, unsigned char veri); extern unsigned char ks0108_read(unsigned char chip); extern void ks0108_pixel(unsigned char x, unsigned char y, unsigned char renk); extern void ks0108_fill(unsigned char renk); extern void ks0108_line(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2, unsigned char renk); extern void ks0108_rect(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned char dolu, unsigned char renk); extern void ks0108_circle(unsigned char x,unsigned char y, unsigned char r, unsigned char dolu, unsigned char renk);

Grld zere bu ktphanemizde olduka fazla ktphane bulunmaktadr. Oysa karakter LCDmizde olduka az fonksiyon vard. Grld zere fonksiyonlarmz iine dikdrtgen, yuvarlak, izgi izme gibi ekstra fonksiyonlar da eklediimizde ks0108.c dosyamz aadaki gibi olacaktr.
#include #include #include <pic.h> "ks0108.h" "delay.h" 0x3F

#define EKRANAC #define EKRANKAPA 0x3E #define sag 1 #define sol 0 void ks0108_init(void) { RST=1; EN=0; CS1=0; CS2=0; DI=0; ks0108_write(sag, ks0108_write(sol, ks0108_write(sag, ks0108_write(sol, ks0108_write(sag, ks0108_write(sol,

//Komut verilecek 0xC0); //En st RAM'in ilk RAM olduu belirleniyor 0xC0); 0x40); //Stunun en bana gidiliyor, Y=0 0x40); 0xB8); //Satrn en bana gidiliyor, X=0 0xB8); //Ekran a

ks0108_write(sag, EKRANAC); ks0108_write(sol, EKRANAC); ks0108_fill(0); }

void ks0108_write(unsigned char chip, unsigned char veri)

FxDev.org

Sayfa 131

{ if(chip) { CS1=0; CS2=1; } else { CS1=1; CS2=0; } RW=0; GLCD_PORT=veri; DelayUs(10); EN=1; DelayUs(10); EN=0; CS1=0; CS2=0; } unsigned char ks0108_read(unsigned char chip) { unsigned char veri; TRIS_GLCD=0xFF; RW=1; if(chip) { CS1=0; CS2=1; } else { CS1=1; CS2=0; } DelayUs(10); EN=1; DelayUs(10); veri=GLCD_PORT; EN=0; TRIS_GLCD=0x00; CS1=0; CS2=0; return veri; } void ks0108_pixel(unsigned char x, unsigned char y, unsigned char renk) { unsigned char veri, kay=1; unsigned char chip=sol; if(x>63) { x=x-64; chip=sag; } // 63'ten bykse ikinci chipe ge // Veri yazma moduna alnd // Den kenar tetiklemeli

// Chip seim alanlar temizleniyor

FxDev.org

Sayfa 132

DI=0; // x=x&0x7F; // x=x|0x40; ks0108_write(chip,x); // ks0108_write(chip,(y/8 & 0xBF) | DI=1; ks0108_read(chip); veri=ks0108_read(chip); if(renk) veri=veri | kay<<y%8; else veri=veri & (~(kay<<y%8)); DI=0; ks0108_write(chip,x); DI=1; ks0108_write(chip,veri); } void ks0108_fill(unsigned char renk) { unsigned char i,j;

Komut verilecek X iin komutlar hazrlanyor X iin komut veriliyor 0xB8); // Y iin komut veriliyor // Veri okunup, yazlacak // Yeni adres bilgisi iin // GLCD iki kez okunuyor // Pixel ak m kapal m

// Komut veriliyor // Yazm yaplyor

for(i=0;i<8;i++) // 8 sayfa var { DI=0; // Komut veriliyor ks0108_write(sol,0x40); ks0108_write(sag,0x40); // Her seferinde, her sayfann bana gidiliyor ks0108_write(sol,i | 0xB8); ks0108_write(sag,i | 0xB8); DI=1; // Veri gnderilecek for(j=0;j<64;j++) // 64 stun var { if(renk) { ks0108_write(sag, 0xFF); ks0108_write(sol, 0xFF); } else { ks0108_write(sag, 0x00); ks0108_write(sol, 0x00); } } } } void ks0108_line(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2, unsigned char renk) { int addx=1, addy=1, P; unsigned char i, dy, dx, diff; if(x2>x1) dx = x2 - x1; else { dx = x1 - x2; addx = -1;

FxDev.org

Sayfa 133

} if(y2>y1) dy = y2 - y1; else { dy = y1 - y2; addy = -1; } if(dx >= dy) { dy *= 2; P = dy - dx; diff = P - dx; for(i=0; i<=dx; ++i) { ks0108_pixel(x1, y1, renk); if(P < 0) { P += x1 += } else { P += x1 += y1 += } } } else { dx *= 2; P = dx - dy; diff = P - dy; for(i=0; i<=dy; ++i) { ks0108_pixel(x1, y1, renk); if(P < 0) { P += y1 += } else { P += x1 += y1 += } } } } void ks0108_rect(unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned char dolu, unsigned char renk) { if(dolu)

dy; addx;

diff; addx; addy;

dx; addy;

diff; addx; addy;

FxDev.org

Sayfa 134

{ unsigned char if(x1 < x2) { xmin = xmax = } else { xmin = xmax = } if(y1 < y2) { ymin = ymax = } else { ymin = ymax = } i, xmin, xmax, ymin, ymax;

x1; x2;

x2; x1;

y1; y2;

y2; y1;

for(; xmin <= xmax; ++xmin) { for(i=ymin; i<=ymax; ++i) { ks0108_pixel(xmin, i, renk); } } } else { ks0108_line(x1, ks0108_line(x1, ks0108_line(x1, ks0108_line(x2, } } void ks0108_circle(unsigned char x,unsigned char y, unsigned char r, unsigned char dolu, unsigned char renk) { unsigned char a,b; int P; a=0; b=r; P=1-r; do { if(dolu) { ks0108_line(x-a, ks0108_line(x-a, ks0108_line(x-b, ks0108_line(x-b, } else y+b, y-b, y+a, y-a, x+a, x+a, x+b, x+b, y+b, y-b, y+a, y-a, renk); renk); renk); renk); y1, y2, y1, y1, x2, x2, x1, x2, y1, y2, y2, y2, renk); renk); renk); renk);

FxDev.org

Sayfa 135

{ ks0108_pixel(a+x, ks0108_pixel(b+x, ks0108_pixel(x-a, ks0108_pixel(x-b, ks0108_pixel(b+x, ks0108_pixel(a+x, ks0108_pixel(x-a, ks0108_pixel(x-b, } if(P < 0) P+= 3 + 2 * a++; else P+= 5 + 2 * (a++ - b--); }while(a <= b); } b+y, a+y, b+y, a+y, y-a, y-b, y-b, y-a, renk); renk); renk); renk); renk); renk); renk); renk);

Grld zere neredeyse 7 sayfa tutan bir ktphane dosyasna sahibiz. Bu da ktphanemizin, pic ierisinde olduka fazla yer kaplayaca anlamna gelmektedir. Dikdrtgen, yuvarlak, izgi izme gibi fonksiyonlarn algoritmalarn internetten bulup sizde yukardaki gibi dilediiniz ekil iin yazabilirsiniz. 13.1) GLCD Uygulamas Bu uygulamada oluturduumuz GLCD dosyasn kullanarak GLCDnin istenilen blgesine dikdrtgen, daire, izgi izdirelim. Bunun iin ncelikle ekil-111deki devremizi izelim.

ekil 111 GLCD Uygulamas

FxDev.org

Sayfa 136

steimizi yerine getiren kodlar ise aadaki gibidir.


#include <htc.h> #include "delay.h" #include "ks0108.h" void main(void) { unsigned char x1,x2,y1,y2,i; PORTB=0x00; PORTC=0x00; TRISB=0x00; // GLCD iin klar TRISC=0x00; // tanmlanyor ks0108_init(); // lk ayarlar yaplyor

while(1) { x1=5; y1=5; x2=100; y2=5; for(i=0;i<6;i++) { // GLCD'de izgi izdiriliyor ks0108_line(x1, y1, x2, y2, 1); y2=y1+=10; x2-=10; DelayMs(250);DelayMs(250);DelayMs(250);DelayMs(250); } ks0108_fill(0); // Ekran temizleniyor x1=y1=0; for (i=0;i<120;i++) { // Ekranda istenen pikseller aktif yaplyor ks0108_pixel(x1,y1,1); y1=x1++; DelayMs(50); } ks0108_fill(0); // Ekran temizleniyor for(i=30;i>0;i=i-3) { // GLCD'de Daire izdiriliyor ks0108_circle(60, 30, i, i%2, i%2); DelayMs(250);DelayMs(250);DelayMs(250);DelayMs(250); } ks0108_fill(0); // Ekran temizleniyor x1=5; y1=5; x2=120; y2=63; for(i=0;i<6;i++) { // GLCD'de dikdtrgen izdiriliyor ks0108_rect(x1, y1, x2, y2, 0, 1); y1=x1+=5; x2-=5; y2-=5;

FxDev.org

Sayfa 137

DelayMs(250);DelayMs(250); } ks0108_fill(0); // Ekran temizleniyor } }

Grld zere GLCD srmek normal karakter LCD srmekten olduka zordur. Dolays ile birok ilemde karakter LCD kullanlmaktadr. Simlasyon yaparken dikkat edilecek durum picin 20MHze ayarlanm olmasdr. Gerek hayatta bu deer 4MHzdir. 20MHz yaplmasnn nedeni proteusta bulunan GLCDnin ekilleri 4MHzde bozuk gstermesindendir.

FxDev.org

Sayfa 138

BLM 14 GRAFK LCD


14) Nokia 3310 Ekran ekil-112de grlebilecek Nokia 3310 ekran aslnda Philips firmasnn PCD8544 tabanl 48x84 pixellik bir grafik LCDdir.

ekil 112 Nokia 3310 Ekran

Dier GLCD srmlerinden tek fark bilgilerin paralel deil seri ekilde ilenmesidir. Seri iletiim protokol kullanmas yaanabilecek zaman problemlerinin giderilmesini salamtr.

ekil 113 Nokia 3310 Ekrannn Pinleri

ekil-113te Nokia3310 ekrannn pinleri grlmektedir, bu pinlerin grevleri yledir. - VDD : +2,7Vtan +3.3V deerleri arasnda voltaj uygulanmaldr. Yksek voltaj deerleri LCDnin kolaylkla yanmasna neden olabilir.

FxDev.org

Sayfa 139

Voltaj devresi iin aadaki devre kullanlabilir;

- SCLK : SCE pini sfrken, seri iletiimin saat darbeleri buradan alnr. - SDIN : Seri data giri ucudur, datalar SCLKnin ykselen kenarlarnda ilenir. - D/C : Kontrol pinidir, bilgi data m yoksa komut mu onu anlamaya yarar. Alnan bilgi bu pin 0 iken komut, 1 iken veridir. - SCE : Seri iletiimi aktif etme ucudur, herhangi bir bilgi gnderilmek istendiinde 0 yaplmaldr. - GND : Toprak ucudur. - Vout : Kontrast ucudur, toprak ucuna 1-10 mikro farad arasnda kondansterle balanmal. - RES : Reset ucudur, balangta o yaplmaldr, yoksa LCD zarar grebilir. Nokia 3310 ekranna veri gnderip alma ilemlerinin yapl ise ekil-114teki zaman diyagramndan grlebilir.

ekil 114 Nokia 3310 Ekrannn Zaman Diyagram

Nokia 3310 ekran ile iletiim kurulmas iin u sra izlenmelidir; -ncelikle SCE pini 0 yaplmal. -D/C pininden gnderilecek bilginin komut ya da data m olduu seilmeli (data iin 1, komut iin 0 olmal) -Daha sonra SCLKnn her ykselen kenarnda 1 bit bilgi gnderilmelidir. Nokia ekrann altrmak iin baz zel komutlar vardr. Bu komutlar ekil-115te grlebilir. GLCD ve komut grevleri ise yledir; -LCDnin hafza yaps 6x8x84 bit eklindedir. (48x84) -X ekseninde 0dan 83e kadar adresleme yaplabilirken, Y ekseninde 0dan 5e kadar adresleme yaplabilir. (Kaynak: Datasheet)

FxDev.org

Sayfa 140

Komutlar:

ekil 115 Nokia 3310 Ekrannn Komutlar

lk ykleme deerleri iin ise aadaki ilemler yaplmaldr; 1) lk nce LCD pasif yaplmal. Bunun iin SCE=1 olmal. 2) Daha sonra LCDye zarar vermemek iin 10ms kadar RES=0 olmal ve daha sonra RES=1 yaplmal. 3) Sonra srayla aadaki ilemler uygulanr - 0x21: Tanmlanm komutlara eriim alyor - 0xC8: Kontrast voltaj ayarlanyor.(Direk VSSe bal) - 0x13: LCD bias ayarlanyor (1:48 modunda) - 0x20: Yatay mod, X otomatik artacak, komutlara eriilmiyor. - 0x09: LCD alyor - DDRAM temizleniyor, bylece nceden kaydedilmi kaytlar siliniyor. - 0x08: Tm LCD segmentleri alyor. - 0x0C: LCD normal moda altrlyor.

FxDev.org

Sayfa 141

Tm bunlar hesaba katp ktphane haline getirirsek 3310.h dosyas aadaki gibi olacaktr.
/* www.FxDev.org * 3310 LCD Kullanm Klavuzu * nokia_init(); ile LCD'nin ilk ayarlarn yap. * nokia_clean_ddram(); ile LCD nin DDRAM'i silinir. * nokia_write_command(0x20); eklinde komut gnderilir. * nokia_write_data(0x01); eklinde data gnderilir. * nokia_write_byte(0xFE); ile bir byte'lk bilgi gnderilir. * nokia_gotoxy(2,3); ile lcd'de belirli blgelere gidilebilir. Snr: (0,0) dan (83,5) tir. * nokia_contrast(0x0F); ile kontrast ayar yaplr. * nokia_printchar("Deneme"); eklinde yaz yazdrlr. * nokia_print(i+48); eklinde say yazdrlr. * lcdpixel (3,4); eklinde pixel belirtilir. * www.FxDev.org */ #define #define #define #define #define extern extern extern extern extern extern extern extern extern extern nok_res RB0 nok_sce RB1 nok_dc RB2 nok_sdin RB3 nok_sclk RB4 nokia_init(void); nokia_clean_ddram(void); nokia_write_command(char nokia_command); nokia_write_data(char nokia_data); nokia_write_byte(char bytefornokia); nokia_gotoxy(char ynokia, char xnokia); nokia_contrast(char contrast); nokia_printchar(const char *s); nokia_print(char charsel); lcdpixel (char x, char y);

void void void void void void void void void void

Yukardaki ilemleri yapan 3310.c dosyas ise aadaki gibi olacaktr.


#include <pic.h> #include "delay.h" #include "3310.h" const unsigned char tablo1 [240] = { 0x00,0x00,0x00,0x00,0x00, bosluk 0x00,0x00,0x5f,0x00,0x00, 0x00,0x07,0x00,0x07,0x00, 0x14,0x7f,0x14,0x7f,0x14, 0x24,0x2a,0x7f,0x2a,0x12, 0x23,0x13,0x08,0x64,0x62, 0x36,0x49,0x55,0x22,0x50, 0x00,0x05,0x03,0x00,0x00, 0x00,0x1c,0x22,0x41,0x00, 0x00,0x41,0x22,0x1c,0x00, 0x14,0x08,0x3e,0x08,0x14, 0x08,0x08,0x3e,0x08,0x08, 0x00,0x50,0x30,0x00,0x00, 0x08,0x08,0x08,0x08,0x08, 0x00,0x60,0x60,0x00,0x00, 0x20,0x10,0x08,0x04,0x02, 0x3e,0x51,0x49,0x45,0x3e, // 20 // // // // // // // // // // // // // // // // 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 ! " # $ % & ' ( ) * + , . / 0

FxDev.org

Sayfa 142

0x00,0x42,0x7f,0x40,0x00, 0x42,0x61,0x51,0x49,0x46, 0x21,0x41,0x45,0x4b,0x31, 0x18,0x14,0x12,0x7f,0x10, 0x27,0x45,0x45,0x45,0x39, 0x3c,0x4a,0x49,0x49,0x30, 0x01,0x71,0x09,0x05,0x03, 0x36,0x49,0x49,0x49,0x36, 0x06,0x49,0x49,0x29,0x1e, 0x00,0x36,0x36,0x00,0x00, 0x00,0x56,0x36,0x00,0x00, 0x08,0x14,0x22,0x41,0x00, 0x14,0x14,0x14,0x14,0x14, 0x00,0x41,0x22,0x14,0x08, 0x02,0x01,0x51,0x09,0x06, 0x32,0x49,0x79,0x41,0x3e, 0x7e,0x11,0x11,0x11,0x7e, 0x7f,0x49,0x49,0x49,0x36, 0x3e,0x41,0x41,0x41,0x22, 0x7f,0x41,0x41,0x22,0x1c, 0x7f,0x49,0x49,0x49,0x41, 0x7f,0x09,0x09,0x09,0x01, 0x3e,0x41,0x49,0x49,0x7a, 0x7f,0x08,0x08,0x08,0x7f, 0x00,0x41,0x7f,0x41,0x00, 0x20,0x40,0x41,0x3f,0x01, 0x7f,0x08,0x14,0x22,0x41, 0x7f,0x40,0x40,0x40,0x40, 0x7f,0x02,0x0c,0x02,0x7f, 0x7f,0x04,0x08,0x10,0x7f, 0x3e,0x41,0x41,0x41,0x3e};

// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // //

31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f

1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O

const unsigned char tablo2 [240] = { 0x7f,0x09,0x09,0x09,0x06, // 50 P 0x3e,0x41,0x51,0x21,0x5e, // 51 Q 0x7f,0x09,0x19,0x29,0x46, // 52 R 0x46,0x49,0x49,0x49,0x31, // 53 S 0x01,0x01,0x7f,0x01,0x01, // 54 T 0x3f,0x40,0x40,0x40,0x3f, // 55 U 0x1f,0x20,0x40,0x20,0x1f, // 56 V 0x3f,0x40,0x38,0x40,0x3f, // 57 W 0x63,0x14,0x08,0x14,0x63, // 58 X 0x07,0x08,0x70,0x08,0x07, // 59 Y 0x61,0x51,0x49,0x45,0x43, // 5a Z 0x00,0x7f,0x41,0x41,0x00, // 5b [ 0x02,0x04,0x08,0x10,0x20, // 5c \\ 0x00,0x41,0x41,0x7f,0x00, // 5d 0x04,0x02,0x01,0x02,0x04, // 5e ^ 0x40,0x40,0x40,0x40,0x40, // 5f _ 0x00,0x01,0x02,0x04,0x00, // 60 ` 0x20,0x54,0x54,0x54,0x78, // 61 a 0x7f,0x48,0x44,0x44,0x38, // 62 b 0x38,0x44,0x44,0x44,0x20, // 63 c 0x38,0x44,0x44,0x48,0x7f, // 64 d 0x38,0x54,0x54,0x54,0x18, // 65 e 0x08,0x7e,0x09,0x01,0x02, // 66 f 0x0c,0x52,0x52,0x52,0x3e, // 67 g 0x7f,0x08,0x04,0x04,0x78, // 68 h 0x00,0x44,0x7d,0x40,0x00, // 69 i 0x20,0x40,0x44,0x3d,0x00, // 6a j 0x7f,0x10,0x28,0x44,0x00, // 6b k

FxDev.org

Sayfa 143

0x00,0x41,0x7f,0x40,0x00, 0x7c,0x04,0x18,0x04,0x78, 0x7c,0x08,0x04,0x04,0x78, 0x38,0x44,0x44,0x44,0x38, 0x7c,0x14,0x14,0x14,0x08, 0x08,0x14,0x14,0x18,0x7c, 0x7c,0x08,0x04,0x04,0x08, 0x48,0x54,0x54,0x54,0x20, 0x04,0x3f,0x44,0x40,0x20, 0x3c,0x40,0x40,0x20,0x7c, 0x1c,0x20,0x40,0x20,0x1c, 0x3c,0x40,0x30,0x40,0x3c, 0x44,0x28,0x10,0x28,0x44, 0x0c,0x50,0x50,0x50,0x3c, 0x44,0x64,0x54,0x4c,0x44, 0x00,0x08,0x36,0x41,0x00, 0x00,0x00,0x7f,0x00,0x00, 0x00,0x41,0x36,0x08,0x00, 0x10,0x08,0x08,0x10,0x08, 0x78,0x46,0x41,0x46,0x78};

// // // // // // // // // // // // // // // // // // // //

6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f

l m n o p q r s t u v w x y z { | } ~

void nokia_init(void) { nok_dc=1; // Bilgiler DDRAM'de tutuluyor, Address counter ise otomatik artacak nok_sce=1; // Chip pasif DelayUs(200); nok_res=0; //Balangta res=0 olmak zoruna, aksi halde LCD'ye zarar gelebilir DelayMs(10); nok_res=1; nokia_write_command(0x21); // LCD'ye komut yazlyor. nokia_write_command(0x06); // Vop V: 0xC8 (for 3V) nokia_write_command(0x13); // LCD (1:48) modunda (bias) nokia_contrast(0x40); // Kontrast ayar yaplyor nokia_write_command(0x20); // Soldan saa x birer artrlarak yazlyor // 0x22 kullanlsayd, yukardan aa yazcakt. nokia_clean_ddram(); // DDRAM temizleniyor, aksi halde eski yazlm karekterlerle kartrlabilinir DelayMs(10); nokia_write_command(0x0C); } void nokia_clean_ddram(void) { int ddram; nokia_gotoxy(0,0); // 84*6=504bit Dram alan temizleniyor for(ddram=0; 504>ddram; ddram++) nokia_write_data(0x00); } void nokia_write_command(char nokia_command) { nok_dc = 0; // Komut gnderimi iin D/C=0; nok_sce = 0; // Chip aktif // Display normal moda dnyor

FxDev.org

Sayfa 144

nokia_write_byte(nokia_command); nok_sce = 1; // Chip pasif } void nokia_write_data(char nokia_data) { nok_dc = 1; // Data gnderimi iin D/C=1 nok_sce = 0; // Chip aktif nokia_write_byte(nokia_data); nok_sce = 1; // Chip pasif } void nokia_write_byte(char bytefornokia) // Seri veri gnderme rutini, datasheet'ten bire bir alnt. { char i; for(i=8;i>0;i--) { nok_sclk=0; DelayUs(2); if((bytefornokia & 0x80)==0) nok_sdin=0; else nok_sdin=1; DelayUs(2); nok_sclk=1; DelayUs(2); bytefornokia = bytefornokia << 1; } } void nokia_gotoxy(char xnokia,char ynokia) // stenilen blgeye ulama fonksiyonu { nokia_write_command(0x40|(ynokia & 0x07)); // Y bu ekilde hareket ediyor: 0100 0yyy nokia_write_command(0x80|(xnokia & 0x7F)); // X bu ekilde hareket ediyor: 1xxx xxxx } void nokia_contrast(char contrast) { nokia_write_command(0x21); // LCD'ye komut veriliyor nokia_write_command(0x80 | contrast); // Kontrast ayar // Yatay adresleme modu, X birer otomatik artar. nokia_write_command(0x20); } void nokia_printchar(const char *s) { while(*s) nokia_print(*s++); } // ASCII tablosunu kullanarak yaz yazdrmaya yarayan fonksiyon void nokia_print(char charsel) { char char_row,charpos,chardata; if (charsel<0x20) return; if (charsel>0x7f) return;

FxDev.org

Sayfa 145

for(char_row=0;char_row<5;char_row++) { // Seilen karekterin ASCII kodu 50h'tan ufaksa if(charsel<0x50) { charpos=(((charsel&0xff)-0x20)*5); chardata=tablo1[(charpos+char_row)]; } // Seilen karekterin ASCII kodu 50h'tan bykse if(charsel>0x4f) { charpos=(((charsel&0xff)-0x50)*5); chardata=tablo2[(charpos+char_row)]; } nokia_write_data(chardata); // Datay gnder } nokia_write_data(0x00); // Her zaman 1 bytelk son alan bo olacak } void lcdpixel (char x, char y) { char offset, data; if (x > 84) return; if (y > 48) return; offset = y - ((y / 8) * 8); data = (0x01 << offset); nokia_gotoxy(x, (y/6)); nokia_write_data(data); }

Ktphaneden grlecei zere Nokia 3310 ekrann da dier GLCDler gibi kullanmak zordur. 14.1) Nokia 3310 Ekran Uygulamas Proteusun kendisinde Nokia 3310 ekran yoktur. Yalnz internette bu ktphane bulunup proteusa kolaylkla eklenebilir. Bu uygulamada Nokia 3310 ekranna istediimiz bir ekili aktaralm. Nokia 3310 ekrannn 6x8x84bit byklnde DDRAMi istediimiz verilerle doldurursak, doluluk oranna gre ekranda ekiller oluur. rnein ilk ayarlar yaptktan sonra 0xFF deerini LCDye veri olarak gnderdiimizde ekrann 0x8 lik alannda dz bir izgi grrz. Ayn ekilde 0x9F gnderdiimizde de bir pixel geniliinde harfi grrz. LCDde yaz yazdrmak iin nceden ASCII dizisi tanmlayp, istediimiz ekilde harfleri arp kolaylkla yazdrabiliriz. GLCDde herhangi bir ekilde resim karmak iin yine ayn ekilde diziler oluturulmal ve bu dizinin boyutu 84x6=504 bit boyutunu gememelidir. Bu tanmlamay yapmak teker teker elle ok zor olaca iin FastLCD gibi programlar kullanmak iinizi daha da kolaylatracaktr.

FxDev.org

Sayfa 146

14.1.1) FastLCD Kullanm Programn ara yz ekil-116daki gibidir. ncelikle boyut ayarndan genilik 84, ykseklik ise 48 yaplmaldr.

ekil 116 Fast LCD Program Grnts

Memory yaps 6x8x84 olduu iin karakterlerimizin boyutunu ekil-117deki gibi 6x8lik semek uygun olacaktr.

ekil 117 Fast LCDde Boyut Ayar

Ayarlar yapldktan sonra istenilen resmi ekil-118deki gibi izebiliriz.

FxDev.org

Sayfa 147

ekil 118 Fast LCD Programnda Resim izimi

Daha sonra bunu ekil-118deki mende yazan BAS seeneine basp, Nokia 3310u seip, zellikle save as ksmndan ekil-119da grlen image array seilerek kaydedelim.

ekil 119 Kaydetme Seenekleri

FxDev.org

Sayfa 148

Daha sonra kaydettiimiz dosya notepad++ gibi bir programla alr ve ekil-120deki gibi &h olan ksmlar 0x ile deitirilir.

ekil 120 Deiecek Deerler

Bu deiiklikler olduktan sonra tanmlanan dizi rnei ise aadaki gibi olacaktr.
const int fxdev[]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xF0,0xF0,0xF8,0x78, 0x38,0x78,0xF8,0xF0,0xF0,0xE0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF, 0xFF,0x07,0x01,0x00,0x00,0x00,0xC0,0xFB,0xFF,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xF8,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0, 0xE0,0xE0,0xFF,0xFF,0xFF,0x78,0x78,0x3C,0x3E,0x1F,0x1F,0x0F,0x07,0x00,0x00,0x00, 0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0xC0,0x00,0x00,0x00, 0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xF0,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0xC0, 0xF0,0xF0,0xF0,0x70,0x70,0xF0,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0xF0,0xC0,0x00,0x00, 0x00,0x00,0x00,0xE0,0xFC,0xFE,0x7E,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x81,0xC1,0xC1,0xE1,0xFF,0xFF,0xFF,0x70,0x78,0x78,0x78,0x38,0x3C,0x3C, 0x3C,0x00,0x00,0x00,0x07,0x0F,0x3F,0xFF,0xFC,0xF0,0xF8,0xFC,0x7F,0x1F,0x0F,0x07, 0x01,0x00,0xFE,0xFF,0xFF,0x07,0x03,0x83,0xF3,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00, 0x00,0x00,0xFF,0xFF,0xFF,0xFB,0x79,0x3E,0x3F,0x1F,0x0F,0x07,0x00,0x00,0x01,0x0F, 0x3F,0xFF,0xFE,0xF0,0x80,0xF0,0xFE,0xFF,0x3F,0x07,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xE0,0xF8,0xFC,0x7E,0x3F,0x0F,0x87,0xC3,0xF1,0xFF,0xFF,0x7F,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF8,0xFC,0x7F,0x3F,0x1F,0x07,0x0F,0x1F, 0x7F,0x7E,0x78,0x70,0x00,0x00,0x7F,0x7F,0x7F,0x3E,0x1F,0x1F,0x0F,0x07,0x1F,0x7F, 0x7F,0x7C,0xF0,0xF0,0xF0,0xE0,0x01,0x03,0x07,0x0F,0x1F,0x1E,0x1E,0x3C,0x3C,0x3C, 0x78,0x78,0x78,0x70,0x00,0x01,0x0F,0x3F,0x7F,0x7F,0x7F,0x1F,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x03,0x0F,0x1F,0x1F,0x1E,0x1F,0x1F,0x0F,0x07,0x03,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };

FxDev.org

Sayfa 149

14.1.2) Tanmlanan Dizinin Kullanlmas Dizimizi tanmladktan sonra yapmamz gereken tek ey bu deerleri srasyla Nokia 3310 ekranna yazdrmaktr. ncelikle ekil-121deki devreyi iziyoruz.

ekil 121 Nokia 3310 Uygulamas

steimizi yerine getiren kodumuz ise aadadr.


#include <htc.h> #include "delay.h" #include "3310.h" const int fxdev[]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xF0,0xF0,0xF8 ,0x78,0x38,0x78,0xF8,0xF0,0xF0,0xE0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0xFF,0x07,0x01,0x00,0x00,0x00,0xC0,0xF B,0xFF,0xFF,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0 xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xE0,0xE 0,0xFF,0xFF,0xFF,0x78,0x78,0x3C,0x3E,0x1F,0x1F,0x0F,0x07,0x00,0x00,0x00,0x 80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0xC0,0x00,0x00,0 x00,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xF0,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,

FxDev.org

Sayfa 150

0x00,0xC0,0xF0,0xF0,0xF0,0x70,0x70,0xF0,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0xF0 ,0xC0,0x00,0x00,0x00,0x00,0x00,0xE0,0xFC,0xFE,0x7E,0x1E,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0xC1,0xC1,0xE1,0xFF,0xFF,0xFF,0x70,0x 78,0x78,0x78,0x38,0x3C,0x3C,0x3C,0x00,0x00,0x00,0x07,0x0F,0x3F,0xFF,0xFC,0 xF0,0xF8,0xFC,0x7F,0x1F,0x0F,0x07,0x01,0x00,0xFE,0xFF,0xFF,0x07,0x03,0x83, 0xF3,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFB,0x79 ,0x3E,0x3F,0x1F,0x0F,0x07,0x00,0x00,0x01,0x0F,0x3F,0xFF,0xFE,0xF0,0x80,0xF 0,0xFE,0xFF,0x3F,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xF8,0xFC,0x 7E,0x3F,0x0F,0x87,0xC3,0xF1,0xFF,0xFF,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0 x00,0x00,0x00,0x00,0xF0,0xF8,0xFC,0x7F,0x3F,0x1F,0x07,0x0F,0x1F,0x7F,0x7E, 0x78,0x70,0x00,0x00,0x7F,0x7F,0x7F,0x3E,0x1F,0x1F,0x0F,0x07,0x1F,0x7F,0x7F ,0x7C,0xF0,0xF0,0xF0,0xE0,0x01,0x03,0x07,0x0F,0x1F,0x1E,0x1E,0x3C,0x3C,0x3 C,0x78,0x78,0x78,0x70,0x00,0x01,0x0F,0x3F,0x7F,0x7F,0x7F,0x1F,0x00,0x00,0x 00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0F,0x1F,0x1F,0x1E,0x1F,0x1F,0x0F,0 x07,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0 0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x 00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0 x00 }; void main(void) { int i; PORTB=0x00; TRISB=0x00; // GLCD iin k nokia_init(); for(i=0;504>i;i++) nokia_write_data(fxdev[i]); for(;;); }

Grld zere kodlarmz olduka sadedir. Tm GLCDlerde olduu gibi Nokia 3310 ekran da pic hafzasnn nemli bir blmn kullanmaktadr.

FxDev.org

Sayfa 151

BLM 15 KAYAN YAZI UYGULAMASI


15) Kayan Yaz Uygulamas lk blmde dot matrislerin nasl altn grdk. Gnmzde zellikle reklam panolarnda 5x7 ya da 8x8 matrisler yan yana koyularak kullanlmaktadrlar. Biz bu uygulamada iki adet 8x8 dot matris ile ismimizi bu sistemde kaydrma ilemi yapacaz. ncelikle ekil-122deki devremizi izelim ve iin mantna gz atalm.

ekil 122 Kayan Yaz Uygulamas

Blm 1de yaz yazdrmann ne ekilde olacan grmtk. Yaz kaydrmak ise, yaz yazdrmann biraz deitirilmi bir halidir. ncelikle tek bir dizi tanmlanr ve buraya yazdrmak istediimiz yaznn dizi deerleri yerletirilir. Ben bu uygulamada admn harflerini dizi ierisine yerletirdim. Bata matrislerin bo gzkmesi iin 3x6 satr da 0x00 ifadesini dizime yerletirerek aadaki ifadeyi elde ettim.
const unsigned char kayan_yazi[]= { 0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00, 0x7f,0x09,0x09,0x09,0x01,0x00, 0x00,0x41,0x7f,0x41,0x00,0x00, 0x7f,0x09,0x19,0x29,0x46,0x00, 0x7e,0x11,0x11,0x11,0x7e,0x00, 0x01,0x01,0x7f,0x01,0x01,0x00, 0x00,0x00,0x00, 0x7f,0x41,0x41,0x22,0x1c,0x00, 0x7f,0x49,0x49,0x49,0x41,0x00, 0x1f,0x20,0x40,0x20,0x1f,0x00, 0x7f,0x49,0x49,0x49,0x41,0x00, 0x3e,0x41,0x41,0x41,0x22,0x00, 0x00,0x44,0x7d,0x44,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00 };

// // // // // // // // // // // // // // // // // //

20 20 20 46 49 52 41 54 20 44 45 56 45 43 69 20 20 20

bosluk bosluk bosluk F I R A T bosluk D E V E C i bosluk bosluk bosluk

FxDev.org

Sayfa 152

Sizde adnzn ifadelerini Nokia 3310 ekran uygulamasndaki karakter dizilerinden alp, yeni oluturacanz dizinizin iine koyabilirsiniz. Diziyi oluturduktan sonra yaplmas gereken ise bu ifadelerin dor matrislere baslmasdr. Burada yine birinci blmde anlattmz tarama yntemini kullanacaz. lemimizde tarama srasyla PORTCnin 0. bitinden 7. bitine, oradan PORTDnin 0. bitinden 7. bitine doru olacak. Her stunun bilgi deerini ise PORTBden gndereceiz. Bu ilemi 5 kere tekrarladktan sonra ise karekterlerimizi bir birim sola kaydrarak ilemimizi devam ettireceiz. Tm bu anlatlanlarn yapld Hi-Tech kodunu ise aada grebilirsiniz.
#include <htc.h> #include "delay.h" //smimiz tanmlanyor const unsigned char kayan_yazi[]= { 0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00, 0x7f,0x09,0x09,0x09,0x01,0x00, 0x00,0x41,0x7f,0x41,0x00,0x00, 0x7f,0x09,0x19,0x29,0x46,0x00, 0x7e,0x11,0x11,0x11,0x7e,0x00, 0x01,0x01,0x7f,0x01,0x01,0x00, 0x00,0x00,0x00, 0x7f,0x41,0x41,0x22,0x1c,0x00, 0x7f,0x49,0x49,0x49,0x41,0x00, 0x1f,0x20,0x40,0x20,0x1f,0x00, 0x7f,0x49,0x49,0x49,0x41,0x00, 0x3e,0x41,0x41,0x41,0x22,0x00, 0x00,0x44,0x7d,0x44,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00 }; void main(void) { int i,kay=1,j,k; PORTB=0x00; PORTC=0x00; TRISB=0x00; TRISC=0x00; TRISD=0x00;

// // // // // // // // // // // // // // // // //

20 20 20 46 49 52 41 54 44 45 56 45 43 69 20 20 20

bosluk bosluk bosluk F I R A T // 20 bosluk D E V E C i bosluk bosluk bosluk

// Deikenler tanmlanyor // Dot matris iin klar

for(;;) { for(i=0;i<8;i++) // lk matrise deerler gnderiliyor { PORTC=kay<<i; PORTB=~kayan_yazi[i+j]; DelayMs(1); } kay=1; PORTC=0x00; for(i=0;i<8;i++) // kinci matrise deerler gnderiliyor { PORTD=kay<<i; PORTB=~kayan_yazi[i+8+j]; DelayMs(1); }

FxDev.org

Sayfa 153

kay=1; PORTD=0x00; k++; if(k>5) { k=0; j++; if(j==90) j=0; } } }

// Yazy kaydracak deiken

lemler takip edilirse aslnda ilemlerin o kadar da zor olmad gzkmektedir. Dilerseniz daha fazla dot matris ve decoderler kullanarak yaz alann bytebilirsiniz.

BLM 16 EK BLGLER
16.1) Picin Dahili Eepromuna Balangta Bilgi Yazlmas
Pic ilk baladnda dahili eepromuna bilgi yazmak iin aadaki kod programa eklenebilir.
#include <htc.h> __CONFIG( PROTECT & DPROT & WDTDIS & XT & PWRTDIS & BORDIS & WP1 & LVPDIS & DEBUGDIS ); __EEPROM_DATA('F' ,'I' ,'R' ,'A' ,'T' ,0x00,0x00,0x00); __EEPROM_DATA('D' ,'E' ,'V' ,'E' ,'C' ,'i' ,0x00,0x00); //Bu ekilde ilk kodlar yazlabilir. void main(void) { ... }

BTRRKEN
Sizlere 16 blm boyunca Hi-Tech derleyicisini, C programlama ve en nemlisi Picin nemli zelliklerini anlatmaya, hibir eyin ezbere dayal olmamas gerektiine, her eyin bir mantk zerine oturduunu gstermeye altm. Sadece derleyici anlatmakla kalmayp, birok ekstra donanmn almasn da sizlere gsterdim Kitab takip eden ve katks olan herkese teekkrler

Frat Deveci Austos 2009 fxdev@fxdev.org www.fxdev.org


FxDev.org Sayfa 154

FxDev.org

Sayfa 155

You might also like