5 Ağustos 2015 Çarşamba

SDCC ile Dahili Eeprom'a okuma ve yazma (16F877A) -Ders14



eepromokuyaz.c” ana dosyamız
============================================================

// Durali Kiraz 2015
// PIC16F877A için hazırlanmıştır.
#include "ayarlar.h"
#include "bizim_lcd.h" // LCD kütüphanesi tanımlanıyor
#include "delay.h"
#include "eeprom.h"


void main(void) // Ana fonksiyon alanı
{
  TRISB = 0x00; // LCD'ye bağlı portlar çıkış yapılıyor
  TRISC = 0x00; // C portları çıkış yapılıyor

  PORTB = 0x00;
  PORTC = 0x00;

  lcd_baslat();

  eeprom_yaz(0x00, 'D');
  eeprom_yaz(0x01, 'U');
  eeprom_yaz(0x02, 'R');
  eeprom_yaz(0x03, 'A');
  eeprom_yaz(0x04, 'L');
  eeprom_yaz(0x05, 'i');
  eeprom_yaz(0x06, ' ');
  eeprom_yaz(0x07, 'K');
  eeprom_yaz(0x08, 'i');
  eeprom_yaz(0x09, 'R');
  eeprom_yaz(0x0A, 'A');
  eeprom_yaz(0x0B, 'Z');

  lcd_yaz("EEPROM verisi:");
  lcd_konumlanxy(2,1);

  veri_yolla( eeprom_oku(0x00) );
  veri_yolla( eeprom_oku(0x01) );
  veri_yolla( eeprom_oku(0x02) );
  veri_yolla( eeprom_oku(0x03) );
  veri_yolla( eeprom_oku(0x04) );
  veri_yolla( eeprom_oku(0x05) );
  veri_yolla( eeprom_oku(0x06) );
  veri_yolla( eeprom_oku(0x07) );
  veri_yolla( eeprom_oku(0x08) );
  veri_yolla( eeprom_oku(0x09) );
  veri_yolla( eeprom_oku(0x0A) );
  veri_yolla( eeprom_oku(0x0B) );

  for(;;); //Sonsuz döngüye giriliyor
}

============================================================

eeprom.c” dosyamız
============================================================

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

void eeprom_yaz(unsigned char adres, unsigned char data)
{
  EEADR = adres;
  EEDATA = data;
  WREN = 1;
  EECON2 = 0x55;
  EECON2 = 0xAA;
  WR = 1;
  while(WR);
  WREN = 0;
}

unsigned char eeprom_oku(unsigned char adres)
{
  EEADR = adres;
  RD = 1;
  return(EEDATA);
}

============================================================

eeprom.h” dosyamız
============================================================
*
Dahili EEPROM Kullanım Klavuzu
* eeprom_yaz(address, data); ile eepromun istenilen adresine istenilen bilgi yazılır.
* eeprom_oku(address); ile eepromun istenilen adresi okunur.
*/
extern void eeprom_yaz(unsigned char adres, unsigned char data);
extern unsigned char eeprom_oku(unsigned char adres);
============================================================


Bu dersimizde mikrodenetleyici programlamanın vazgeçilmezlerinden dahili eeproma yazma ve okuma işleminin nasıl yapıldığını göreceğiz.

EEPROM, Electronically Erasable Programmable Read-Only Memory yani elektriksel olarak
silinip yazılabilen hafıza bölümüdür. Pic16f877a’nın içinde 256 byte yani 256x8 bit’lik EEPROM
bulunmaktadır. Kullanacağımız işlemlerdeki bilgilerin, enerji kesildiğinde de korunmasını
istiyorsak pic’in EEPROM birimini kullanabiliriz. Eğer kaydedeceğimiz değerler 256byte’tan
büyük ise harici EEPROM’lar kullanarak istediğimizi yine gerçekleştirebiliriz. Harici eepromlar şu an bizim konumuz değil. O yüzden dahili eeprom üzerinde basit bir iki işlem yapacağız.



EEPROM üzerinde okuma ve yazma yapabilmemiz için datasheetinde yazdığı gibi bir takım sıralı işlemlerini kuralına göre yapmamız gerekmekte. Bu işlemlerin işlem adımlarını oluşturan fonksiyonlar topluluğuna esasında eeprom sürme kodları desek daha isabetli bir anlatım yapmış oluruz. Bizim sürücü eeprom.c dosyamızda iki fonksiyon tanımı var. Biri okuma diğeri yazma işlemini yapmakta. PIC16F877A üzerinde EECON1 ve EECON2(sanal olarak var) isimli iki adet kontrol registerları bulunur. Eğer eeprom üzerinde okuma ve yazma yapacaksak bunları doğru şekilde sürmeniz/kontrol etmemiz gerekir. Bu registerlarla ilgili daha detaylı bilgiyi datasheet dosyasından edinebilirsiniz. Biz yazma ve okuma işlem adımlarındaki işlemleri açıklayalım.

OKUMA İŞLEMİ:
-----------------------------------------------------------------------------------
1- EEADR = adres;
Bu adımda okunması gereken adres değerini EEADR isimli registera yazarız

2- RD = 1;
Bu adımda RD Bitini (EECON1 0.bit) 1 yaparız. Bu da okuma yapmak istediğimizi gösterir.

3-return(EEDATA);
Yukardaki iki işlemden sonra hafızadaki değer EEDATA registerına yazılmıştır. Bizde bu registerın değerini okursak sonuca ulaşmış oluruz


YAZMA İŞLEMİ:
-----------------------------------------------------------------------------------
1- EEADR = adres;
Hangi adrese yazma işi yapılacaksa o adresin değeri EEADR registerına yazılır.

2- EEDATA = data;
Yazılacak hafıza değeri EEDATA registerına yazılır.

3- WREN = 1;
EECON1 bit 2 yani WREN 1 yapılırsa yazma izni verilmiş olur.0 da yazılma olmaz.

4- EECON2 = 0x55;
yazma işlemi için kurallardan birisi

5- EECON2 = 0xAA;
yazma işlemi için kurallardan birisi

6- WR = 1;
(EECON1 bit 1)WR nin 1 olması ile yazma işlemi başlatılır.
7- while(WR);
WR sıfır olana kadar program bekletilir.

8- WREN = 0;
WR sıfır olduktan sonra WREN sıfır yapılır ki artık yazma izni kaldırılmış olsun.

Görüldüğü üzere kurallarını yukarıda açıklamaya çalıştık. Aslında olay gayet basit. Bu eeprom üzerine yazdığımız veriler mikrodenetleyici eeprom hafızasında kalıcıdır.

Ana programımızdan bahsedecek olursak doğrudan eeprom kütüphanemizdeki eeprom_yaz fonksiyonumuz ile yazdırmak istediğimiz 8 bitlik değeri yazdırıyoruz. Burada char tipi karakterler yazdırdık. İsterseni 0 dan 255 e kadar sayılardan birini de yazdırabilirsiniz. Sonrasında ise eeprom_oku fonksiyonu ile okuyup veri_yolla lcd fonksiyonumuz ile eeprom hafızasındaki karakterleri sırasıyla lcd ye gönderiyoruz. Sonrasında program for(;;) sonsuz döngüsüne girerek bizim değerleri lcd üzerinde sürekli göstermemizi sağlıyor. Bu derste verilemeyen diğer dosyalar bir önceki derslerde bulunmaktadır. Bu dersimizde bu kadar. Başka bir derste görüşmek üzere hoşçakalın.


duralikiraz.blogspot.com
04 Ağustos 2015

Muvaffakiyet Allahtandır”


Kaynak:
* Hi-Tech ile Pic Programlama – Fırat Deveci

3 Ağustos 2015 Pazartesi

SDCC ile Ultrasonick Sensör Mesafe Ölçümü, Timer1, LCD kullanımı (16F877A) -Ders13




bizim_lcd.h” dosyası
=======================================================================

/* Durali Kiraz 2015
* www.duralikiraz.blogspot.com
*
* D4,D5,D6,D7 pinlerini kullanarak 4 bit iletişim kullanır.
* Cursor kapalıdır.
* RW kullanılmadığı için direk toprağa bağlanabilir.
* 2x16 LCD Kullanım Klavuzu
*
* lcd_baslat(); ile LCD'nin ilk ayarlarını yap
* lcd_ekranisil(); ile LCD'yi sil
* lcd_yaz("deneme"); Şeklinde yazı yazdır.
* veri_yolla('F'); Şeklinde tek ascii kodu yazdır.
* lcd_konumlanxy(1,13); Şeklinde LCD'nin istenilen yerine git.
*
*
*/


#define rs RC0 //Pin tanımlamaları
#define rw RC1
#define e RC2
#define lcd_port PORTB


/* LCD'de kullanilan komutlarin tanimlamasi*/
#define Sil 1 // Ekrani temizler
#define BasaDon 2 // Imleci sol üst köseye getirir
#define SolaYaz 4 // Imlecin belirttigi adres azalarak gider
#define SagaYaz 6 // Imlecin belirttigi adres artarak gider
#define ImlecGizle 12 // Göstergeyi ac, kursor görünmesin
#define ImlecAltta 14 // Yanip sönen blok kursor
#define ImlecYanSon 15 // Yanip sönen blok kursor
#define ImleciGeri 16 // Kursoru bir karakter geri kaydır
#define KaydirSaga 24 // Göstergeyi bir karakter sağa kaydır
#define KaydirSola 28 // Göstergeyi bir karakter sola kaydır
#define EkraniKapat 8 // Göstergeyi kapat (veriler silinmez)
#define BirinciSatir 128 // LCD'nin ilk satir başlangıç adresi
// (DDRAM adres)
#define IkinciSatir 192 // İkinci satirin başlangıç adresi
#define KarakUretAdres 64 // Karakter üreteci adresini belirle
// (CGRAM adres)

/* LCD'de Kullanilan Fonksiyon Seçimi */
#define CiftSatir8Bit 56 // 8 bit ara birim, 2 satir, 5*7 piksel
#define TekSatir8Bit 48 // 8 bit ara birim, 1 satir, 5*7 piksel
#define CiftSatir4Bit 40 // 4 bit ara birim, 2 satir, 5*7 piksel
#define TekSatir4Bit 32 // 4 bit ara birim, 1 satir, 5*7 piksel


extern void veri_yolla(unsigned char);
extern void lcd_ekranisil(void);
extern void lcd_yaz(const char *s);
extern void lcd_konumlanxy(unsigned char x, unsigned char y);
extern void lcd_baslat(void);
extern void lcd_komut(unsigned char c);
extern void lcd_int_yaz(int x,unsigned int y);
//
=======================================================================


bizim_lcd.c” dosyası
=======================================================================

/* Durali Kiraz 2015
* www.duralikiraz.blogspot.com
*/

#include <pic14regs.h> //mikrodenetleyici hazır tanımları alınıyor
#include "bizim_lcd.h" // bizim_lcd.h dosyası tanımlanıp, değerler alınıyor
#include "delay.h" // Gecikme fonksiyonu tanımlanıyor

void lcd_busy(void)
{
   us_delay_20(12); //DelayUs(250);
}

void lcd_komut(unsigned char c) // Komut gönderme fonksiyonu
{
   rw=0; // LCD'ye yazma yapılacak
   rs=0; // LCD'ye komut gönderilecek
   e=1; // Düşen kenar tetikleme olduğu için E önce 1
   lcd_port = ( c & 0xF0 ); // Yüksek değerlikli bitler gönderiliyor
   e=0; // E, 0 yapılıyor
   lcd_busy(); //Belirli süre bekleniyor
   e=1; // E, 1 yapılıyor
   lcd_port = ( (c & 0x0F)<<4 ); // Düşük değerlikli bitler gönderiliyor
   e=0; // E, 0 yapılıyor
   lcd_busy(); // Belirli bir süre bekleniyor
}

void veri_yolla(unsigned char c)
{
  rw=0;
  rs=1; // Komut yolladan tek farkı, RS'nin 1 olması
  e=1;
  lcd_port = ( c & 0xF0 );
  e=0;
  lcd_busy();
  e=1;
  lcd_port = ( (c & 0x0F)<<4 );
  e=0;
  lcd_busy();
}

void lcd_ekranisil(void) // LCD siliniyor
{
   lcd_komut(0x1);
   ms_delay(2);
}

void lcd_yaz(const char * s) // LCD'ye string ifade gönderiliyor
{
  lcd_busy();
  while(*s)
  veri_yolla(*s++);
}

void lcd_konumlanxy(unsigned char x,unsigned char y) //LCD'nin belli lcd_gotoxy
//bölgesine gidiliyor
{
  if(x==1)
     lcd_komut(0x80+((y-1)%16));
  else
     lcd_komut(0xC0+((y-1)%16));
}

void lcd_baslat() // LCD ilk yükleme ayarları yapılıyor
{
   rs = 0;
   e = 0;
   rw = 0;
   ms_delay(15);
   e=1;
   lcd_komut(0x02);
   ms_delay(2);

   lcd_komut(CiftSatir4Bit);
   lcd_komut(SagaYaz);
   lcd_komut(ImlecGizle);
   lcd_ekranisil();
   lcd_komut(BirinciSatir);
}

void lcd_int_yaz(int val,unsigned int field_length)
{
/***************************************************************
This function writes a integer type value to LCD module

Arguments:
1)int val : Value to print

2)unsigned int field_length :total length of field in which the value is printed
must be between 1-5 if it is -1 the field length is no of digits in the val

****************************************************************/

char str[5]={0,0,0,0,0};
int i=4,j=0;
while(val)
{
   str[i]=val%10;
   val=val/10;
   i--;
}
if(field_length==-1)
  while(str[j]==0) j++;
else
  j=5-field_length;

if(val<0) veri_yolla('-');
   for(i=j;i<5;i++)
   {
      veri_yolla(48+str[i]);
   }
}

=======================================================================


mesafeolcumu.c” ana dosyası

=======================================================================

// Durali Kiraz 2015
// PIC16F877A için hazırlanmıştır.

#include "ayarlar.h"
#include "bizim_lcd.h" // LCD kütüphanesi tanımlanıyor
#include "delay.h"

#define trigger RD0 //pin tanımları
#define ECHO RD1



void main(void) // Ana fonksiyon alanı
{
   unsigned int sure, mesafe;

   TRISD = 0b0000010; // RD1 giriş diğer D portları çıkış yapılıyor
   TRISB = 0x00; // LCD'ye bağlı portlar çıkış yapılıyor
   TRISC = 0x00; // C portları çıkış yapılıyor

   PORTD = 0x00;
   PORTB = 0x00;
   PORTC = 0x00;
   T1CON = 0b00000101; //TIMER1 ayarları yapılıp çalıştırılıyor

   lcd_baslat(); // LCD ilk ayarları yapılıyor
   ms_delay(100);
   lcd_ekranisil();

   for(;;) //Sonsuz döngüye giriliyor
   {
      trigger = 1;
      us_delay_20(1); //20us bekletiyoruz. Bu 15 us yada 10 us de olabilir.
      trigger = 0;
      
      while(!(ECHO)); //echo pini bekle
      TMR1=0; //echo pini 1 se timeri 0 la ve saymaya başla

      while((ECHO)); //echo pini 0 olunca timer değerini süreye eşitle
      sure=TMR1;

      mesafe = (sure/58); //mesafeyi hesapla cm olarak

      lcd_konumlanxy(1,1); //uzaklık ve sure lcdye yazdırılıyor
      lcd_yaz("uzaklik:");
      lcd_int_yaz(mesafe,2);
      lcd_yaz("cm");
      lcd_konumlanxy(2,1);
      lcd_yaz("sure:");
      lcd_int_yaz(sure,2);
      lcd_yaz("us");
      ms_delay(100); //yeni ölçüm için bekle.
   }

}

=======================================================================






Bu dersimizde Timer1 sayıcısını kullanarak ultrasonik sensörümüzden gelen verileri sayarak mesafe ölçümünü yapacağız. İstersek timer1 kullanmadanda ultrasonik sensörün echo yapma süresini hesaplamamız mümkün. Ancak Timer kullanarak yapmak hem daha sağlıklı hemde mikrodenetleyicinin yükünü biraz daha hafifletir.

Ultrasonik sensörler; özel bir hoparlörden gönderilen ses dalgasının karşısındaki bir engele çarpıp geri gelmesi esnasında arada geçen sürenin yol=hız*zaman formülünden hesaplanmasıyla kullanılır. Ses saniyede 340m/sn lk hızla hareket eder. Hesaplamalarımızda kolaylık olması açısından bu mesafeyi cm olarak 34000cm (340m), zamanı da 1000000us (1sn) olarak düşünelim. Hâl böyle olunca (340000/1000000=1/29) olarak düzenlersek formül mesafe=zaman/29 olarak bulunur. Burada ses sinyali hem gitmekte hemde gelmekte. Dolayısıyla 29*2 = 58 yapar. Mesafe formümüz Mesafe=zaman/58 olur. (Sesin havadaki hızına hava sıcaklığı ve nemin de azda olsa etki ettiğini unutmayınız. Ama normal şartlarda saniyede 340m kabul edilir.)

Mikrodenetleyici timer larından bahsedilince akla hemen timer kesmeleri gelebilir. Ancak unutulmamalıdırki timerlar illa timer kesmesi ile beraber kullanılacak diye bir kaide yoktur. Bu örneğide özellikle seçme sebeplerinden biride budur. Timer1'in zamanlayıcı olarak kullanılmasına güzel bir örnek olacağı kanaatindeyim. 4 MHZ lik bir kristal osilatör kullanıldığında mikrodenetleyici bunu 4 e bölerek kullanılmasından dolayı timer1 in her komut çevriminde bir artması söz konusudur. Dolayısıyla mikrosaniye olarak süreyi elde etmemiz mümkün olmaktadır. Tabi bunu yapabilmek için T1CON register ının ayarlanması gerekmektedir. T1CON registeri 8 bitlik bir kontrol registeridir.

Bit 7-6
Kullanılmayan bitler. Okunurken bu bitler 0 okunur
Bit 5-4 T1CKPS1-T1CKPS0
Timer1 bölme (prescaler) oranı
11 = 1:8
10 = 1:4
01 = 1:2
00 = 1:1
Bit 3 T1OSCEN
Timer1 osilatör kontrol biti
1: osilatör açık
0: osilatör kapalı
Bit 2 T1SYNC
Timer1 dış clock sinyali senkronizasyon kontrol biti
1: Harici clock sinyali girişi ile senkronize yok
0: Harici clock sinyali girişi ile senkronize
Bit 1 TMR1CS
Timer1 clock kaynağı seçme biti
1: RC0/T1OSO/T1CK1 pininden dış clock sinyali
0: Dahili clock sinyali (FOSC /4)
Bit 0 TMR1ON
Timer1 açma-kapama biti
1: Timer1 açık
0: Timer1 kapalı

(Bu tablo CCS C ile PIC programlama (Serdar Çiçek) Kitabından alınmıştır)

Biz zamanlayıcı olarak Timer1 in kullanılabilmesi için ana program dosyamızda

T1CON = 0b00000101;

ayarını yaptık. Yani burada yapılan 0.bitin 1 yapılması. Yukarıdaki tabloda bakarsak 0.bit Timer1 1 yapıldığında “açık” olduğu anlamına geliyor. 2. bitin 1 yapılması Harici clock sinyali ile senkronizasyonun olmadığını gösterir. Dikkat çeken diğer bir değer ise 5. ve 4. bitin 00 olması. Buda Timer1 bölme(prescaler) oranının 1:1 olacağını gösterir. Bu şartları sağladığımızda timer1 zamanlayıcı olarak kullanılmaya hazır demektir. Daha fazla teknik bilgi için lütfen pic programlama kitaplarına yada PIC16F877A datasheet belgelerine bakabilirsiniz.

Ana program dosyamızda PORTD nin 1. bacağını giriş olarak diğerlerini ise çıkış olarak seçtiğimizi gösteriyoruz. Giriş olan bacağı HC-SR04 ultrasonik sensörün Echo çıkışına bağladığımızda mikrodenetleyicimiz bu sönsörden sinyal okumayı yapabilecektir. Sensörün diğer trigger bacağı ise mikrodenetleyiciden gelen çıkışı giriş olarak alır. Bu sayade sensör çalışabilecek kararlılığa ulaşır. Bunun için en az 10us kadar trigger portunun lojik 1 olarak kalması gerekir. Aksi takdirde sensör çalışmaya hazır hale gelemez. Sonrasında echo pininden bir sinyal gelene kadar beklenir. Bu sinyalin gelmesi sensörden çıkan ses dalgasının herhangi bir engele çarpıp geri geldiği zamanı bize bildirir. İşte bu zamanı yakaladığımızda bu ses dalgasının aldığı yolu (mesafeyi) hesaplayabiliriz. Kodun diğer kısmı mesafenin hesaplama formulu ve lcd ye yazı gönderme işini kapsar. Burada da yeni olan bir lcd fonksiyonumuz lcd_int_yaz() fonksiyonumuzdan bahsedecek olursak, doğrudan tam sayı değerleri lcd ye gönderebilmemiz için oluşturulmuş bir fonksiyondur. İki parametre alır. Birincisi yazdırılacak integer değeri, diğeri ise bu değerin kaç basamaklı bir alana yazdırılacağı bilgisidir. Zaten sırf bu fonksiyonu eklemek için bizim_lcd.cd ve bizim_lcd.h dosyalarında değişiklik yapıldı. Değişikliğe uğramamış dosyalara ve derleme adımlarının nasıl yapılacağına önceki derslerden ulaşabilirsiniz. Başka bir derste görüşmek üzere hoşçakalın.


duralikiraz.blogspot.com
03 Ağustos 2015

Muvaffakiyet Allahtandır”



Kaynaklar :
* CCS C ile PIC programlama Serdar Çiçek.



2 Ağustos 2015 Pazar

SDCC ile LCD Uygulaması-3 Türkçe karakterler (16F877A) -Ders12



lcdturkce.c” dosyası (Ana dosyamız)
==================================================
// Durali Kiraz 2015
// PIC16F877A için hazırlanmıştır.

#include "ayarlar.h"
#include "bizim_lcd.h" // LCD kütüphanesi tanımlanıyor
#include "delay.h"

void TurkceKarakterleriHazirla(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);
  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) // Ana fonksiyon alanı
{
   TRISB=0x00; // LCD'ye bağlı portlar çıkış yapılıyor
   TRISC=0x00;
   PORTB=0x00;
   PORTC=0x00;

   lcd_baslat(); // LCD ilk ayarları yapılıyor
   TurkceKarakterleriHazirla();

   for(;;) //Sonsuz döngüye giriliyor
   {
      //veri_yolla(0); // 1. karekter yazdırılıyor
      lcd_yaz("ME");
      veri_yolla(4); //Ş harfi yazdır
      lcd_yaz("HUR ");
      veri_yolla(0); //Ç harfi yazdır
      lcd_yaz("UBUK");
      ms_delay(1000);

      lcd_konumlanxy(2,1); // İkinci satıra geçiliyor
      lcd_yaz("TUR");
      veri_yolla(4); //Ş harfi yazdır
      lcd_yaz("USU Y");
      veri_yolla(2); //İ harfi yazdır
      lcd_yaz("Y");
      veri_yolla(2); //İ harfi yazdır
      lcd_yaz("N");
      ms_delay(1000);

      lcd_ekranisil();
      ms_delay(500);
  }

}
==================================================

Bu dersimizde Ders11 den farklı olan tek dosyamız yukardaki ana dosymızdır. Diğer bizim_lcd.c, bizim_lcd.h, delay.c, delay.h, ayarlar.h dosyalarında herhangi bir değişiklik yoktur. Önceki dersten bu dosyaları isterseniz inceleyebilirsiniz.

Bilindiği üzere 16x2 karakter lcd lerin hafizasında bizim kullandığımız türkçe karakterler yoktur. Ancak 8 karakterin sığabileceği boş hafıza alanı mevcuttur. İşte biz kendi tanımladığımız Türkçe karakterleri yada özel karakterleri bu alanlara pic programımızı başlatırken tanımlıyor ve ardından kullanıyoruz. Burada önemli olan hususlardan biride bu tanımlanan özel karakterlerin pic mikrodenetleyicimizin elektriği kesildiği anda hafızadan kaybolmasıdır. Mikrodenetleyicimiz her elektriklenip çalışmaya başladığında bizim yazılımsal olarak bu özel karakterleri başlatmamızın gerekli olmasıdır. Peki özel karakter lcd ye nasıl tanımlanır isterseniz biraz bundan bahsedelim.

Örnek olarak “Ç” harfinin tanımlanmasını ele alalım. CGRAM hafızasının boş karakter alanlarının ilkinin başlangıç adresi 0x40 adresidir. Bizim her karakterimiz için 8 satır tanımlama alanı vardır. En alttaki alan genelde boş bırakılır kullanılmaz. Bu yüzden en alt satırı sıfırla tamamlayacağız. Sırayla Ç harfine ait 8 satırı oluşturalim

Hafıza adresi
Gönderilen Değer - Ondalık
Gönderilen Değer – İkilik
0x40
14
00001110
0x41
17
00010001
0x42
16
00010000
0x43
16
00010000
0x44
16
00010000
0x45
21
00010101
0x46
14
00001110
0x47
0
00000000

Biz “Ç” harfini CGRAM hafıza da sırayla yukardaki satırları hafıza adresi ile belirtilen adrese göndererek oluştururuz. Şu durumda “Ç” harfinin nasıl oluştuğunu gözlerinden canlandıramayanlar için ikilik değerlerdeki “1” sayılarını koyulaştırıp aşağıda görmeniz sunuyoruz.




0 0 0 0 1 1 1 0
0 0 0 1 0 0 0 1
0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 1 0 1 0 1
0 0 0 0 1 1 1 0
0 0 0 0 0 0 0 0

Şu anda artık “Ç” harfini görüyor olmalısınız. Şayet halâ göremiyorsanız en yakın arkadaşınızdan yardım almanızı öneririm. :) Dilerseniz kendi hayâlinizdeki “Ç” yatık harfide bu mantığı kullanarak oluşturabilirsiniz. Hatta karakter lcd için özel karakterleri oluşturan programcıklarda internette mevcuttur. Bunlarla rahatlıkla kendi özel karakterlerinizi oluşturabilirsiniz.

Bu derste TurkceKarakterleriHazirla isimli fonksiyonu oluşturduk. İsminden anlaşılacağı gibi yukarda anlattığımız mantıkla 8 adet Türkçe karakteri CGRAM hafızasında geçici olarak oluşturduk. Main isimli ana fonksiyonumuzda lcd_baslat(); isimli fonksiyonun çağrılmasından sonra Türkçe karakterlerimizi oluşturan fonksiyonu çağırdık. Sonrasında Yazdırmak istediğimiz Türkçe karakterlerden oluşan iki satırlık mesajı parçalar halinde Lcd ye gönderdik. Bu kodda biz biraz kullanışlılığı az olan bir yöntemle Türkçe karakterleri parça parça gönderip diğer normal ingilizce karakterleri lcd_yaz fonksiyonu ile gönderdik. Bu şekilde programın çalışmasını engelleyecek bir sıkıntı yoktur. Eğer siz kodunuzda internette bulunan flex_lcd.c dosyasında olduğu gibi doğrudan lcd_yaz(“ÇUBUK TURŞUSU”) şeklinde tek bir fonksiyonda derli toplu bir şekilde bu işi yapmak isterseniz bizim_lcd.c dosyasındaki lcd_yaz() isimli fonksiyonda basit bir iki değişiklik yapabilirsiniz. Örnek verecek olursak

if (GelenKarakter == 'Ç')
     veri_yolla(0); //Ç harfi
:
:

şeklinde kod düzeltmesiyle fonksiyonunuzu daha işlevsel yapabilirsiniz.

Kodumuzun derle aşaları Ders11 de anlatıldığının aynı şekildedir. Biz yine burada nasıl derleme yapılacağını tekrar verelim :

sdcc --use-non-free -mpic14 -p16f877a -I path/to/pic14/includes -c bizim_lcd.c
sdcc --use-non-free -mpic14 -p16f877a -I path/to/pic14/includes -c delay.c
sdcc --use-non-free -mpic14 -p16f877a -I path/to/pic14/includes -L path/to/pic14/libraries -Wl, lcdturkce.c bizim_lcd.o delay.o

(En alt satır sığmadığı için aşağıya kaymıştır. Bir üstteki satırın devamıdır)

Bu derleme adımlarının açıklamalarını Ders 11 de ayrıntılı bir şekilde bulabilirsiniz. Bir sonraki derste görüşmek üzere hoşçakalın.


duralikiraz.blogspot.com
02 Ağustos 2015

Muvaffakiyet Allahtandır”