Ayhan 2 Şubat 2014 ARM

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.

, , , , , , ,
1 Yıldız2 Yıldız3 Yıldız4 Yıldız5 Yıldız (1 votes, average: 5,00 out of 5)
Loading...
Yazar :

Elektrik-Elektronik mühendisiyim. 2 yıldır bu blogda yazıyorum. Ve 6 aydır aktif olarak internet siteleri yönetiyorum. Kişisel olarak da teknoloji ve fotoğrafçılıkla ile ilgileniyorum.



Beni sosyal medya hesaplarım üzerinden takip edin:

YORUMLAR

  1. 3 sene ago  

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

  2. Serkan

    3 sene ago  

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

  3. Yasin SOYASLAN

    3 sene ago  

    Eline emeğine sağlık

  4. Muhammet

    3 sene ago  

    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

    • Ayhan

      3 sene ago  

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

      Ayhan KORKMAZ

  5. Muhammet

    3 sene ago  

    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

    • Ayhan

      3 sene ago  

      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?

  6. Muhammet

    3 sene ago  

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

    • Ayhan

      3 sene ago  

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

  7. Muhammet

    3 sene ago  

    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ü :)

    • Ayhan

      3 sene ago  

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

  8. selime

    2 sene ago  

    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?

    • Ayhan

      2 sene ago  

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

  9. faruk

    11 ay ago  

    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

Daha fazla ARM
STM32I2C2
STM32F1xx EEPROM Fonksiyonlarını Geliştirelim

Merhaba Arkadaşlar, Bugünkü yazımda sizlere daha öceden paylaşmış olduğum STM32F1XX I2C ile Harici EEPROM Kullanımı yazısındaki kütüpanemizin geliştirilmiş halini paylaşacağım....

STM32I2C2
STM32F1xx I2C ile Harici EEPROM Kullanımı

Merhaba arkadaşlar bugünkü yazımda internette çok fazla örneği olmayan bir konuya değinmek istiyorum. Aslında bir çok onuda eeprom ele alınmış...

Kapat