Anasayfa Gömülü Sistemler ARM STM32F1xx ile 2×16 LCD Kütüphanesi Oluşturalım
ARM

STM32F1xx ile 2×16 LCD Kütüphanesi Oluşturalım

20 Dakikada Okunur
14
0
381
LCD Bağlantı Şeması

Merhaba Arkadaşlar,

Bugün sizlere STM32F1xx ile 2×16 LCD kullanımını göstermek istiyorum. Bildiğiniz gibi 2×16 LCD’ler çoğu işlerde işimizi görebilecek yapıda olup projelerimize de beklediğimizden daha çok görsellik katmaktadır. Bu nedenle bir kütüphane oluşturarak gerekli işlemlerin yapılmasını sağlamak istedim. Hem kendi işlerimde kullanmak için hem de kullanmak isteyenlerin işine yarayacağı bir kaynak oluşturmak için işe koyuldum.

Öncelikle LCD bağlantı şemamızdan başlamak gerekli. LCD Balantıları aşağıdaki gibi olacaktır. 4 Data pini ile süreceğiz LCD’mizi. Dikkat edilmesi gerekn nokta LCD’nin 5V ile çalışttığıdır. Bunun için VDD kısmına 5V bağlamalısınız. Ben elimdeki STM32VLDiscovery kart üstünden 5V çıkışı aldım. Yazıyı yazarken anımda pot olmadığından da pot kullanmadım ve VEE bacağını toprağa çektim.

LCD Bağlantı Şeması
LCD Bağlantı Şeması

Diğer bağlantı özellikleri ise;

*PC.0 –> RS
*PC.1 –> E
*PC.4 –> DB4
*PC.5 –> DB5
*PC.6 –> DB6
*PC.7 –> DB7
*RW ->Toprak

Bağlantılarımızı da yaptıktan sonra artık Kütüphanemizi oluşturabiliriz. Öncelikle lcd.h dosyamızı oluşturacağım. Bunu oluştururken  de uzmanlarca yazılmış kodları inceleyerek yazdım. İlk başta kodun daha önceden çağırılıp çağırılmadığı sorguladım.Eğer daha önceden çağırılmadıysa tanımla.Çağırıldıysa ise tanımlama yapılmayacak. Bu da  büyük projelerde aynı kodun defalarca açılıp vaktimizden çalınmasını engellemiş olacak. Kodu yazarken her zamanki gibi üst kısmında açıklamalar yaptım.

LCD.H :

/******************************************************************
*Dosya			:lcd.h
*Amaç			:2*16 LCD için gerekli tanımlamaları yapar
*Kullanım   	:Proje dosyasında ilgili yere eklenir.
*                lcd.c içinden çağırılır
*Yazar			:Ayhan KORKMAZ - AyhanKorkmaz.Net
*İletişim  	    :info@ayhankorkmaz.net
*Versiyon		:V1.0
*Pin bağlantısı :
*                  ----------------
*                  ||||||||||||||||
*
*PC.0  –> RS
*PC.1  –> E
*PC.4  –> DB4
*PC.5  –> DB5
*PC.6  –> DB6
*PC.7  –> DB7
*RW    ->Toprak
*******************************************************************/
#ifndef __LCD_H//Daha önceden çağırılmadı mı?
#define __LCD_H //LCD.h kullan
#define temizle 		0x01
#define zorunlu 		0x02
//------İMLEÇ AYARLARI------//
#define dkyansonyok		0x08   	//dk = disp kapalı
#define	dkyanson		0x09
#define dkyansonyokig	0x0A	//ig = imleç göster
#define dkyansonig		0x0B
#define dayansonyok		0x0C	//da = display açık
#define dayanson		0x0D
#define dayansonyokig 	0x0E
#define dayansonig		0x0F
#define solakay			0x10	//imleç sola kayar
#define sagakay			0x14	//imleç sağa kayar
#define dispsolakay		0x18	//display sola kayar
#define dispsagakay		0x1C	//display sağa kayar
//-------İletişim Ayarları------//
#define birsatir4bit5x8		0x3C	//LCD 1 satır,5x8 matris 4bit iletişim
#define birsatir4bit5x10	0x24
#define ikisatir4bit5x8		0x28
#define ikisatir4bit5x10	0x2C
#define birsatir8bit5x8		0x30
#define birsatir8bit5x10	0x34
#define ikisatir8bit5x8		0x38
#define ikisatir8bit5x10	0x20
//-------GİRİŞ AYARLARI--------//
#define imlecsolakay		0x04	//Her yazılan karakterden sonra imleç sola kayar
#define imlecdispsolakay	0x05	//Her yazılan karakterden sonra imleç ve display sola kayar
#define imlecsagakay		0x06	//Her yazılan karakterden sonra imleç saga kayar
#define imlecdispsagakay	0x07	//Her yazılan karakterden sonra imleç ve display sola kayar
extern void delay(unsigned long delay);
extern void lcd_komut(char komut);
extern void lcd_karakter_yaz(char veri);
extern void lcd_yazi_yaz(char *veri);
extern void lcd_git_xy(unsigned char satir,unsigned char sutun);
extern void lcd_hazirla(void);
extern void lcd_temizle(void);
extern void lcd_gecikme(void);
#endif

Daha sonra LCD.H dosyasından tanımlaması yapılan fonksiyonlar LCD.C dosyasının içinde yazılmış olacak.

LCD.C :

/******************************************************************
*Dosya			:lcd.c
*Yazar			:Ayhan KORKMAZ - AyhanKorkmaz.Net
*İletişim  	        :info@ayhankorkmaz.net
*Versiyon		:V1.0
*******************************************************************/
#include <stm32f10x.h>
#include "lcd.h"
unsigned char sayac,s,adres=64;
/*****************************************************************************
Kullanim  : Eklemek istediğiniz özel karakterleri ekleyebiliriniz
Bunun için LCD karakter oluşturma programlarını kulanabilirsiniz
******************************************************************************/
unsigned char karakter_[8][8]=
{
/* TR Karakterler */
{ 0,14,16,16,17,14, 4, 0},//ç
{ 0, 0,12, 4, 4, 4,14, 0},//I
{10, 0,14,17,17,17,14, 0},//ö
{ 0,15,16,14, 1,30, 4, 0},//$
{10, 0,17,17,17,17,14, 0},//ü
/* özel isaretler */
{2, 6,14,30,14, 6,  2, 0},//<
{ 0, 4, 4, 4, 4, 4, 4, 0},//|
{ 0, 16, 8, 4, 2, 1, 0,0} //\//
};
/********************************************************
Fonksiyon : delay
Amac	  : Gecikme Fonksiyonudur.
Kullanim  : delay(0x0000FFFF);
*********************************************************/
void delay(unsigned long delay)
{
while(delay--);
}
/********************************************************
Fonksiyon : lcd_komut
Amac	  : LCD Çalışması için gerekli komutları verir
Kullanim  : lcd_komut(temizle);
*********************************************************/
void lcd_komut(char komut)
{
GPIOC->BRR =  0x00000001; 			//RS=0
GPIOC->ODR |= 0x00000002;			//E=1
GPIOC->ODR |= (komut & 0x000000F0);	        //Yüksek değerlikli 4 bit gönderiliyor
lcd_gecikme();
GPIOC->BRR = 0x00000002;			//E=0
GPIOC->BRR = 0x000000F0;			//gönderilen yüksek değerlikli 4 bit porttan temizleniyor.
lcd_gecikme();
GPIOC->ODR |= 0x00000002;			//E=1
GPIOC->ODR |= ((komut & 0x0000000F)<<4);	//İlk 4 bit lcd ye gönderiliyor.
lcd_gecikme();
GPIOC->BRR = 0x00000002;			//E=0
GPIOC->BRR = 0x000000FF; 			//Gönderilen düşük değerlikli 4 bit porttan temizleniyor.
}
/********************************************************
Fonksiyon : lcd_karakter_yaz
Amac	  : LCD Ekrana bir karakter basar
Kullanim  : lcd_karakter_yaz('A');
*********************************************************/
void lcd_karakter_yaz(char veri)
{
switch (veri) {
case 'Ç' : veri=0x00; break;
case 'İ' : veri=0x01; break;
case 'Ö' : veri=0x02; break;
case 'Ş' : veri=0x03; break;
case 'Ü' : veri=0x04; break;
case 'ç' : veri=0x00; break;
case 'ı' : veri=0x01; break;
case 'ö' : veri=0x02; break;
case 'ş' : veri=0x03; break;
case 'ü' : veri=0x04; break;
default : break;
}
GPIOC->ODR |= 0x00000001;			//RS=1
GPIOC->ODR |= 0x00000002;			//E=1
GPIOC->ODR |= (veri & 0x000000F0);	        //verinin yüksek değerlikli 4 biti gönderiliyor.
lcd_gecikme();
GPIOC->BRR = 0x00000002;			//E=0
GPIOC->BRR = 0x000000F0;			//Gönderilen 4 bit porttan temizleniyor.
lcd_gecikme();
GPIOC->ODR |= 0x00000002;			//E=1
GPIOC->ODR |= ((veri & 0x0000000F)<<4);		//İlk 4 bit gönderiliyor.
lcd_gecikme();
GPIOC->BRR = 0x00000002;			//E=0;
GPIOC->BRR = 0x000000FF;			//Gönderilen ilk 4bit porttan temizleniyor.
lcd_gecikme();
}
/********************************************************
Fonksiyon : lcd_yazi_yaz
Amac	  : LCD Ekrana yazi yazar
Kullanim  : lcd_yazi_yaz("AyhanKorkmaz.Net");
*********************************************************/
void lcd_yazi_yaz(char *veri)
{
while(*veri)
{
lcd_gecikme();
lcd_karakter_yaz(*veri++);
}
delay(0x0000FFFF);
}
/**************************************************************
Fonksiyon : lcd_git_xy
Amac	  : LCD ekranın hangi bölmesine yazılacağını ayarlarız
Kullanim  : lcd_git_xy(2,1); 2. satır 1. Sütun
***************************************************************/
void lcd_git_xy(unsigned char satir,unsigned char sutun)
{
if(satir==1)
{
lcd_komut(0x00000080 + (sutun-1)); 					//1.satır 1.sütun için cgram adresi 0x80 dir
}
else if(satir==2)
{
lcd_komut(0x000000C0 +(sutun-1));					//2.satır 1.sütun için chram adresi 0x80+0x40=0xC0 dır
}
}
/********************************************************
Fonksiyon : lcd_hazirla
Amac	  : LCD Çalışması için gerekli ilk ayarlar
Kullanim  : lcd_hazirla();
*********************************************************/
void lcd_hazirla(void)
{
delay(0x0000FFFF);
delay(0x0000FFFF);
GPIO_InitTypeDef GPIO_InitStructure;
delay(0x0000FFFF);
RCC_DeInit();
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);
lcd_komut(zorunlu);
delay(0x0000FFFF);
lcd_komut(ikisatir4bit5x8);
delay(0x0000FFFF);
lcd_komut(imlecsagakay);
delay(0x0000FFFF);
lcd_komut(dayansonig);
delay(0x0000FFFF);
lcd_komut(dayansonyok);
delay(0x0000FFFF);
lcd_komut(temizle);
delay(0x0000FFFF);
lcd_gecikme();
lcd_temizle();
for(sayac=0;sayac<=7;sayac++){  // Türkçe karakterler tanitiliyor
lcd_komut(adres);
for(s=0;s<=7;s++){
lcd_karakter_yaz(karakter_[sayac][s]);
}
adres=adres+8;
}
lcd_temizle();
delay(0x0000FFFF);
}
/********************************************************
Fonksiyon : lcd_temizle
Amac	  : LCD ekran tamamen silinir
Kullanim  : lcd_temizle();
*********************************************************/
void lcd_temizle(void)
{
lcd_komut(temizle);
lcd_gecikme();
}
/********************************************************
Fonksiyon : lcd_gecikme
Amac	  : LCD Çalışması için gerekli gecikmedir
Kullanim  : lcd_gecikme();
*********************************************************/
void lcd_gecikme(void)
{
unsigned long delay=0x00000872;
while(delay--);
}

Kodları incelerseniz basit bir şekilde anlatmaya çalıştım. LCD kütüphanemizin en önemli noktalarından bir tanesi de Türkçe karakter desteğinin de olmasıdır. Eğer sizde istediğiniz bir karakteri kütüphaneye eklemek istereniz Türkçe karakterlerin tanımlandığı Karakter dizisine eklemelisiniz. Eklerken yapıyı bozmadan gerekli boytları da düzenlenmesi gerektiği ve lcd_hazırla() fonksiyonundaki türkçe karakterlerin tanımlandığı bölüme de eklenmesi gerektiği unutulmamalıdır.

Son olarak da kütüphane dosyamızın nasıl projemize ekleneceğinden bahsetmek gerekir. Eklemek için proje doyamızda .h ve .c neredeyse bizim dosyalarımızı da oraya ekliyoruz.Daha sonra kullandığınız derleyicinin(Ben IAR kullanıyorum.) solundaki dosyalar bölümünden  LCD.H  ekliyoruz. Ayrıca da Main.c dosyamıda #define komutu ile çağırıyoruz.

Artık kullanıma hazır hale geldik. Örnek kullanımı gösterek kodumuzu yazalım.

Main.c :

/*************************************************************
* Dosya   : LCD
* Amaç    : STM32F1xx kullanarak 2x16 LCD kullanımı
* Yazar   : Ayhan Korkmaz - AyhanKorkmaz.Net
* İletişim: info@ayhankorkmaz.net
* Test    : STM32VLDiscovery Kartı ve 2x16
*           LCD üstünde test edilmiştir.
**************************************************************/
#include "stm32f10x.h"
#include "lcd.h"
#include "stm32f10x_rcc.h"
unsigned char gozlem=0,Veri[30];
const char Yazi[]={"AyhanKorkmaz.Net"},Yazi1[]={"     2*16 LCD    "};
char k=12,i,j;
/********************************************************
Fonksiyon :Main
Amac	  :Ana Fonksiyondur
Kullanim  : -
*********************************************************/
int main(void)
{
uint8_t i,k,l=16;
lcd_hazirla();
lcd_temizle();
lcd_git_xy(1,1);
lcd_yazi_yaz("AyhanKorkmaz.Net");
lcd_git_xy(2,1);
lcd_yazi_yaz("Gururla Sunar!");
delay(0x000fffff);
delay(0x00ffffff);
lcd_temizle();
for(i=1;i<=16;i++)
{
lcd_git_xy(1,i);
lcd_karakter_yaz(Yazi[i-1]);
delay(0x0005ffff);
}
for(k=0;k<2;k++)
{
lcd_temizle();
delay(0x0005ffff);
delay(0x0005ffff);
lcd_git_xy(1,1);
lcd_yazi_yaz("AyhanKorkmaz.Net");
delay(0x000fffff);
delay(0x000fffff);
}
for(i=16;i>0;i--)
{
lcd_git_xy(2,i);
lcd_karakter_yaz(Yazi1[l]);
delay(0x000Affff);
l--;
}
lcd_temizle();
lcd_git_xy(1,1);
lcd_yazi_yaz("ÇÖİŞÜ");
delay(0x000fffff);
delay(0x000fffff);
delay(0x000fffff);
delay(0x000fffff);
lcd_temizle();
lcd_git_xy(1,1);
lcd_yazi_yaz("Türkçe yazı");
lcd_git_xy(2,1);
lcd_yazi_yaz("Yazabiliriniz!");
delay(0x000fffff);
delay(0x000fffff);
delay(0x000fffff);
delay(0x000fffff);
delay(0x000fffff);
delay(0x000fffff);
delay(0x000fffff);
delay(0x000fffff);
for(k=0;k<2;k++)
{
lcd_temizle();
delay(0x0005ffff);
delay(0x0005ffff);
lcd_git_xy(1,1);
lcd_yazi_yaz("AyhanKorkmaz.Net");
delay(0x000fffff);
delay(0x000fffff);
}
lcd_temizle();
delay(0x0005ffff);
delay(0x0005ffff);
lcd_git_xy(1,1);
lcd_yazi_yaz("AyhanKorkmaz.Net");
lcd_git_xy(2,1);
lcd_yazi_yaz("Takipte Kalın");
while (1)
{
}
}

Projemizin çıktısını da aşağıdaki videodan izleyebilirsiniz. Umarım herkesin işine yarar. Sorularını olursa öncelikle yorum atarsanız iyi olur.Hem herkes görmiş olur hem de benim görmem hızlanmış olur. Çünkü bazen aynı soruyu farklı kişiler iletişim bölümünden soruyorlar ve dolayısıyla birine verdiğim cevap diğerinin işine yaramamış oluyor.

Daha fazla ilgili makale
Yazardan daha fazla Ayhan KORKMAZ
Load More In ARM

14 Yorumlar

  1. Burak ŞAHAN

    3 Şubat 2014 at 8:25 am

    Eline emeğine sağlık güzel paylaşım olmuş. 2×16 Klasik LCD kullanmak isteyen arkadaşlar için yol gösterici.

    Cevapla

  2. Serkan

    3 Şubat 2014 at 9:08 am

    Eline sağlık güzel bir anltıcı yazı olmuş iyi çalışmalar..

    Cevapla

  3. Yasin SOYASLAN

    5 Şubat 2014 at 3:29 pm

    Eline emeğine sağlık

    Cevapla

  4. Muhammet

    15 Mart 2014 at 7:32 pm

    Merhabalar ,

    Ben stm32f051 kullanıyorum lcd.c programında

    Error[Pe020]: identifier “RCC_APB2Periph_GPIOC” is undefined C:\Users\Asus\Desktop\Yeni klasör (2)\ARM örnekler\Yeni klasör\LCD ye İsim Yazma\Project\src\EvalTest\lcd.c 143

    hatası veriyor bu konuda yardımcı olur musunuz

    İyi çalışmalar

    Cevapla

    • Ayhan

      16 Mart 2014 at 7:32 pm

      Kullandığın entegrenin datasheetine bir bak belki o seride GPIOC APB1 ile bağlıdır. Bir deneyip sonucunu yazarsın buraya.

      Ayhan KORKMAZ

      Cevapla

  5. Muhammet

    16 Mart 2014 at 10:45 pm

    merhabalar,

    Öncelikle cevabınız için çok teşekkür ederim

    GPIOC AHB2 ye bağlı fakat
    RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_GPIOC, ENABLE);

    yazdığımda da aynı hatayı veriyor RCC AHB 1 de gözüküyor APB1 ve APB2 de GPIOC veya RCC bağlantısı gösterilmiyor

    İyi çalışmalar

    Cevapla

    • Ayhan

      17 Mart 2014 at 9:27 pm

      Direkt olarak daha önceki yazılarımda paylaştığım std_periph… klasörü üzerinden mi derleme yapmaya çalışıyorsun.RCC kütüphaneleri eksik olabilir mi?

      Cevapla

  6. Muhammet

    19 Mart 2014 at 3:46 pm

    Sorunu hallettim çalışıyor çok teşekkür ederim yardımınız için İyi çalışmalar

    Cevapla

    • Ayhan

      19 Mart 2014 at 3:52 pm

      Merhaba,
      Hatanız neymiş söylerseniz karşılaşanlara da çözüm olmuş olur. Çözmenize sevindim.

      Cevapla

  7. Muhammet

    22 Mart 2014 at 3:26 pm

    STM32F0 – Discovery de AHB ‘ye bağlı PORTC. APB2’ yi AHB olarak değiştirdim ve stm32f0x.it.c dosyasının içindekiSystick_handler fonksiyonun içini sildim ve sorun çözüldü :)

    Cevapla

    • Ayhan

      23 Mart 2014 at 3:46 pm

      Neden Clock kaynağının yanlış seçilmesiymiş. Bu durumlarda Reference manuelden Saat kaynağına bakmak herzaman yararlıdır.

      Cevapla

  8. selime

    26 Haziran 2014 at 11:55 am

    64×128 lik ekran ile stm32f051 ile çalışıyorum bu kodları uyarlamaya çalıştım ve 8 tane hata aldım daha yeni başladım gömülü sistemlere acaba yardım edebilirmisiniz?

    Cevapla

    • Ayhan

      2 Temmuz 2014 at 8:48 am

      Merhaba,
      Henüz 64×128 GLCD çalışma fırsatım olamığı için yardımcı olamayacağım ama örneklere bakara rahatça yapabilirsiniz

      Cevapla

  9. faruk

    29 Ocak 2016 at 3:37 am

    ayhan hocam gecikmeleri mili saniye ve mikro saniye cinsinden yazsanız süper olurmuş. bu programı çalıştırmak için çalışma frekansımız ne olacak ben 72MHz de çalıştırıyorum işlemciyi. Bir de Ayhan hocam program çalışmayınca öküz altında buzağı aramamak için proje dosyasını hex dosyasını paylaşırsanız memnun olurum. bordun çalışıp çalışmadığından bile şühepheleniyorum bazen 😀 paylaşım için teşekkür eder. çalışmalarınızda başarılar dilerim

    Cevapla

Cevap Yaz