2x16 LCD karakter sorunu

Başlatan Gökhan BEKEN, 14 Ekim 2014, 01:26:09

Gökhan BEKEN

Malzemenin kod adı: tc1602a-90t
datasheet: https://www.adafruit.com/datasheets/TC1602A-01T.pdf
sayfa 15'teki tabloya göre sorun olmaması lazım.
Küçük harflerin hiç birinde sorun yok.
Büyük karakterler ve sayılarda sorun var. Bir de 2. satıra geçmiyor.
8 bit modda çalışıyorum.
ABCD
yazdığımda
!"#$

gidiyor. Burdan anlaşılıyor ki taboda 2 soldaki eleman gidiyor.
Ancak '0' gönderdiğimde 'P' gidiyor, yani 2 sağındaki eleman gidiyor ama 'P' gönderdiğimde '0' gidiyor.
Bu sorun neyden kaynaklanabilir?
Daha önce aynı kütüphaneyi PIC ile 4 bit modda sorunsuzca kullanmıştım, şu an aynı malzemeler elimde yok. STM32 ile deniyorum, 4 bit modda saçma sapan veriler gittiği için, 8 bit moda geçtim, çalışıyor ama dediğim gibi sorunlar var.
Not: C portunun 0 ila 7 arasındaki pinleri, LCD'nin D0 ila D7 arasındaki pinlere bağladım.

Kullandığım lcd bu(mavi olanı ve resimdekine göre biraz farklı): http://www.direnc.net/2X16-Lcd-Display-TC1602A-SOL-UST-YESIL,PR-18309.html

Özel mesaj okumuyorum, lütfen göndermeyin.

RaMu

Kod ve kütüphane,
elindeki lcdnin arkalı önlü fotosu, (savcılıktan temiz belgesi :) )
birde bağlantı şekilini payşabilir misin?

4 bit moddayken lcd nin boşta kalan data pinlerini GND ye bağlamak faydalı olur.
RW pinini kullanmıyorsan en fazla 220 ohm bir dirençle GND ye bağlamalısın.
LCD ye herhangibir işlem yapmadan önce en az 40-50 ms kadar enerji verilmesi lazım.

Ama bence sorun lcd_init işlemlerinde,
belliki 4 bit moda ve 2 satır moda geçmiyor,
bunlarda zaten init işlemlerinde yapılıyor.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Gökhan BEKEN

4 bit modunu es geçtim, 8 bitte de sorun var.
RW dışında kullanılmayan pin yok, sadece veri gönderme yaptığım için RW pini GND'ye bağlı.
Init işlemlerinde 50ms bekliyorum, fazla beklesem de faydası olmadı.
Sorun varsa küçük harfler neden düzgün çalıştı, işte bu kısım kafamı karıştırıyor.
Bu arada LCD'yi 5v ile besliyorum ama pinleri 3v ile sürüyorum.
Pinleri defalarca kontrol ettim, tek tek değerlerine baktım olması gerektiği gibi.
Bekleme fonksiyonum sys_tick ile yaptığım için 1ms hassasiyetinde düzgün çalışıyor.

lcd.h
#include "stm32f4xx.h"
 
/*PIN TANIMLAMALARI*/
#define RS_HIGH                     GPIOB->ODR|= (1<<11)
#define RS_LOW                      GPIOB->ODR&=~ (1<<11)
#define RW_HIGH                     GPIOB->ODR|= (1<<13)
#define RW_LOW                      GPIOB->ODR&=~ (1<<13)
#define E_HIGH                      GPIOB->ODR|= (1<<15)
#define E_LOW                       GPIOB->ODR&=~ (1<<15)
 
#define RS_SET_OUTPUT               {GPIOB->MODER|= (1<< ((11*2)));  GPIOB->MODER&=~ (1<< ((11*2)+1));}
#define RW_SET_OUTPUT               {GPIOB->MODER|= (1<< ((13*2)));  GPIOB->MODER&=~ (1<< ((13*2)+1));}
#define E_SET_OUTPUT                {GPIOB->MODER|= (1<< ((15*2)));  GPIOB->MODER&=~ (1<< ((15*2)+1));}
 
#define LCD_DATA_PINS               GPIOC->ODR

#define LCD_DATA_PINS_SET_OUTPUT    GPIOC->MODER=0b00000000000000000101010101010101
 
#define LCD_ALL_PINS_CLOCK_ENABLE   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC, ENABLE)
 
#define VERI_GONDER                 1
#define KOMUT_GONDER                0
 
 
//KULLANIM MODLARI:
#define SATIR_MODE                  2
//#define SATIR_MODE                1
#define BIT_MODE                    8
//#define BIT_MODE                  4
 
 
 
 
 
 
 
 
 
 
////////////////////////////////////////////
 
/* LCD'de kullanilan komutlarin tanimlamasi*/
#define Sil 1 // Ekrani temizler
#define BasaDon 2 // Imleci sol üst köseye getirir
#define SolaYaz 4 // Imlecin belirttigi adres azalarak gider
#define SagaYaz 6 // Imlecin belirttigi adres artarak gider
#define ImlecGizle 12 // Göstergeyi ac, kursor görünmesin
#define ImlecAltta 14 // Yanip sönen blok kursor
#define ImlecYanSon 15 // Yanip sönen blok kursor
#define ImlecGeri 16 // Kursoru bir karakter geri kaydir
#define KaydirSaga 24 // Göstergeyi bir karakter saga kaydir
#define KaydirSola 28 // Göstergeyi bir karakter sola kaydir
#define EkraniKapat 8 // Göstergeyi kapat (veriler silinmez)
#define BirinciSatir 128 // LCD'nin ilk satir baslangiç adresi
// (DDRAM adres)
#define IkinciSatir 192 // ikinci satirin baslangiç 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
 
void lcd_clear(void);
void lcd_yaz(char *s);
void lcd_gotoxy(unsigned char x, unsigned char y);
void lcd_init(void);
void SendLCD(unsigned char c, char islem);
 
extern void DelayMs(int ms);



lcd.c
#include "lcd.h" // lcd.h dosyasi tanimlanip, degerler aliniyor
//#include "delays.h" // Gecikme fonksiyonu tanimlaniyor
void lcd_busy(void)
{
    //DelayMs(1);
    DelayMs(2); //3.3v icin
}
 
void SendLCD(unsigned char c, char islem) // Komut gönderme fonksiyonu
{
    RW_LOW; // LCD'ye yazma yapilacak
 
    if(islem==KOMUT_GONDER) RS_LOW;  // LCD'ye komut gönderilecek
    else if(islem==VERI_GONDER) RS_HIGH;
 
    E_HIGH; // Düsen kenar tetikleme oldugu için E önce 1

    LCD_DATA_PINS = c; // Yüksek degerlikli bitler gönderiliyor
 
    E_LOW; // E, 0 yapiliyor
    lcd_busy(); //Belirli süre bekleniyor
 
}
 
 
 
void lcd_clear(void) // LCD siliniyor
{
    SendLCD(Sil,KOMUT_GONDER);
    //DelayMs(2); //5v icin
    DelayMs(4); //3.3v icin
}
 
void lcd_yaz(char * s) // LCD'ye string ifade gönderiliyor
{
    lcd_busy();
    while(*s){
        SendLCD(*s,VERI_GONDER);
        s++;
    }
}
 
void lcd_gotoxy(unsigned char x,unsigned char y) //LCD'nin belli //bölgesine gidiliyor
{
    if(x==1)
        SendLCD(BirinciSatir+((y-1)%16),KOMUT_GONDER);
    else
        SendLCD(IkinciSatir+((y-1)%16),KOMUT_GONDER);
}
 
void lcd_init() // LCD ilk yükleme ayarlari yapiliyor
{
    LCD_ALL_PINS_CLOCK_ENABLE;
    LCD_DATA_PINS_SET_OUTPUT;
 
    RS_SET_OUTPUT
    RW_SET_OUTPUT
    E_SET_OUTPUT
 
    RS_LOW;
    RW_LOW;
    E_LOW;
 
    //DelayMs(20); //5 volt icin
    DelayMs(50); // 4.5'ten daha dusuk bir voltaj icin
 
 
    E_HIGH;
    SendLCD(BasaDon,KOMUT_GONDER);
 
    DelayMs(2);
 
 
 
#if BIT_MODE==8 && SATIR_MODE==1
    SendLCD(TekSatir8Bit,KOMUT_GONDER);
#elif BIT_MODE==8 && SATIR_MODE==2
    SendLCD(CiftSatir8Bit,KOMUT_GONDER);
#elif BIT_MODE==4 && SATIR_MODE==1
    SendLCD(TekSatir4Bit,KOMUT_GONDER);
#elif BIT_MODE==4 && SATIR_MODE==2
    SendLCD(CiftSatir4Bit,KOMUT_GONDER);
 
#elif BIT_MODE!=4 && BIT_MODE!=8
#error BIT MODUNU TANIMLAMAMISSINIZ
#elif SATIR_MODE!=1 && SATIR_MODE!=2
#error SATIR MODUNU TANIMLAMAMISSINIZ
#endif
 
 
    SendLCD(SagaYaz,KOMUT_GONDER);
    SendLCD(ImlecGizle,KOMUT_GONDER);
    lcd_clear();
    SendLCD(BirinciSatir,KOMUT_GONDER);
}
Özel mesaj okumuyorum, lütfen göndermeyin.

hasankara

init istediğin gibi olmuyor olabilir. bunun sebebi de io pinlerinin bazıları sorunlu olabilir. lcd e doğru datanın gidip gitmediğini debug yaparak tek tek kontrol edebilirsin. yada ilk olarak lcd rutinini iptal edip ilgili pinleri sırasıyla flash islemi yaptıracak kod yükleyip, ilgili pinlerin sadece yazılımla kontrol edildiğini gözlemleyebilirsin. pinlere en basitinden led bağlayıp sırasıyla ledlerin yanıp söndüğünü görmeyi bekleyebilirsin.

ek olarak benim kütüphanemin hazırlık dizisini de vereyim : {0x3,0x2,0x28,0x8,0xC,0x6,0x1}
kısa bir hatırlatma; her bir byte, 4 bit iletişim için 2 kez nibble ile gönderiliyor. diğer bir deyiş ile görüldüğü gibi 7 byte lık bu dizinin gitmiş olması için 14 nibble (14 kez e pininin anahtarlanması) ile gönderilmiş olması gerekiyor.

RaMu

    E_HIGH; // Düsen kenar tetikleme oldugu için E önce 1
dan sonra lcd busy denmesi lazım, e_low dan sonra değil,
e_low dan sonrada dersen daha iyi olur, ama e_highdan sonra kesinlikle bekle.

LCD_init için hiçbir komut göndermeden önce
3 defa 0x30 veya 0x20 komut olarak gönderilmesi lazım.

Şimdilik görebildiklerim bunlar.

3.3V her lcdde düzgün çalışmayabilir.

Aynı lcd yi 5V ile veya pic ile tam doğru çalışır şekilde kullanabiliyormusun,
yukarıda yazmışsın ama kodumu lcd yimi anlamadım,
birebir elindeki lcd çalışıyormu test imkanın varsa denermisin.
Birde şöyle bir döküman hazırlamıştım
kendi kütüphaneni yazacaksan işe yara aslında ama
kütüphane işi doğru yapıyormu kontrol etmek istersen bakabilirsin
https://www.dropbox.com/s/trq22u7q55j5z3v/2X16%20LCD%20giri%C5%9F.rar?dl=0

Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Gökhan BEKEN

d5 ve d6 pinleri ters takılmış, sorun buymuş. Kütüphaneyi isteyen kullanabilir, kodlarımda sorun yokmuş.
Tek bir ayarla hem 4 bit modda hem de 8 bit modda çalışabiliyor.
#define BIT_MODE                  4
veya
#define BIT_MODE                  8
Özel mesaj okumuyorum, lütfen göndermeyin.

RaMu

Hayırlı olsun hocam,
boşuna savcılıktan temiz belgesi istemiyoruz,
ben daha bir kere 2x16  lcd pinlerini doğru bağlayamadım.

Şimdi bunu flex lcd yede çevirirsin, port bol ihtiyaç yok gibi ama yinede kullanışlı olabilir.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Gökhan BEKEN

Teşekkürler
Hocam flex lcd'yi bilmiyorum, "port bol" dediğine göre shift register ile alakalı gibi geldi ama anlamadım. Biraz bahseder misin?
Özel mesaj okumuyorum, lütfen göndermeyin.

RaMu

Hocam lcdnin istediğin bacağını mcunun istediğin pinene
bağlayabileceğin şekilde yazılmış lcd kütüphanesi,
ccsc de flex_lcd.c olarak geçiyor,
4 bit mod için yazılmış, RW isteğe bağlı kullanılabiliyor,
toplam 7 lcd bacağını 7 farklı porta dahi bağlayabilirsin.
Az pinli ne azı hatta 40 pinli piclerde bile hayat kurtarıyor,
orada burada kalan pinlere lcd yi bağlıyorum,
hoş ben artık 2x16 lcdden soğudum neredeyse aynı fiyata kaç inch renkli lcd tft satılıyor, hatta dokunmatik.
(Türkiyedeki 2x16 lcd fiyatına ebayda renkli lcd tabi)
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Gökhan BEKEN

Evet pinlerin seçimi hakkında aklıma geldi o yöntem, şimdilik gerek yok diye ellemedim.

Bu arada
Alıntı yapılan: RaMu - 14 Ekim 2014, 21:39:14
hoş ben artık 2x16 lcdden soğudum neredeyse aynı fiyata kaç inch renkli lcd tft satılıyor, hatta dokunmatik.
(Türkiyedeki 2x16 lcd fiyatına ebayda renkli lcd tabi)
Kullanıp tavsiye ettiğin bir ürün varsa, linkini verir misin?
Özel mesaj okumuyorum, lütfen göndermeyin.

RaMu

Şimdilik yok, imkan olunca bolca alacam,
büyük ihtimal en ucuzlarından alıp kullanırım,
neredeyse 2x16 lcdden farkı yok diyebiliriz kullanımına.

Ben renkli macerasına nokia6100 lcdsi ile başladım,
telefondan söktüm,
Erhan YILMAZ ın atmega için düzenlidiği kütüphanesini buldum,
aslında sonra aslınıda buldum pic için yazılmış,
o atmegaya çevirmiş ben geri pice çevirdim,
çevirirken eklemeler düzeltmeler yaptım,
ister istemez çalışma prensibini biraz öğrenmiş oldum.

Bu konularda Burak Bayrak (bytemaster) daha iyi bilir,
ondan tavsiye alabiliriz.

Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html