V

16*2 LCD BAĞLAMA

Başlatan vardar07, 05 Ocak 2013, 23:13:46

vardar07

Merhaba Arkadaşlar.
Bu güne kadar ekte bağlantı şekli1 olan devreyi kurup ona göre program yazıyoruz. Acaba bağlantı şekli 2 deki gibi devreye LCD tanımlamasını nasıl yapabiliriz.

Mucit23

Bahsettiğin 2. şekildeki gibi de tanımlamalar yapılabilir. Hangi dilde program yazıyorsun?
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

vardar07

Alıntı yapılan: Mucit23 - 06 Ocak 2013, 01:03:41
Bahsettiğin 2. şekildeki gibi de tanımlamalar yapılabilir. Hangi dilde program yazıyorsun?
PIC BASIC PRO.
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 2
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 3
DEFINE LCD_LINES 2

ete

Basic de LCD bağlantısı yalnızca 4 adet data bitinin bağlantısı açısından önem kazanır. Bu 4 bitlik pinler mutlaka bir portun ya sıfır nolu bitinden itibaren bağlanmalı yada portun 4 nolu bitinden itibaren bağlanmalıdır.
Kısaca muhtemel bağlantı alternatifleri şunlar olabilir.
Data bitleri,
- PortA.0 dan PortA.3'e kadar
- PortB.0 dan PortB.3 e kadar
- PortB.4 den PortB.7 ye kadar.
- Varsa PortC.0 dan PortC.3 e kadar
- Yine varsa PortC.4 den PortC.7 ye kadar
- Varsa PortD.0 dan PortD.3 e kadar
- PortD.4 den PortD.7 ye kadar.
Bu tanımlamayı LCD tanımlamalarında şöyle belirtiyoruz.
Define LCD_DREG PORTC  'bu satır Data bitlerinin PortC ye bağlandığını gösteriyor
Define LCD_DBIT 4            'başlangıç biti olarak da 4 biti kullandığımızı gösteriyor yani PortC.4-PortC.7 arası kullanılmış oldu
Şöyle yazarsak,
Define LCD_DREG PORTA
Define LCD_DBIT 9
Data bitlerinin PortA.0 dan PortA.3 e kadar bağlandığını belirlemiş oluyoruz.
Ne yazıkki data bitleriniistediğimiz pine rast gele biri orada diğeri şurada gibi bağlayamıyoruz. Mutlaka ve mutlaka bir biri ardından gelen sıralı pin olması gerekiyor. Bunun sebebi şudur.
LCD normalde 8 bit üzerinden haberleşir. Ama 8 adet biti 4 er bit kullanarak iki seferde vermeyi düşünüp 4 adet pinden tasarruf edelim demişler.
Örnek vermek gerekir ise Data bilgisi olarak diyelimki %10010110 verilecek bunu iki kısma ayırdığımız zaman %1001 0110 şeklinde görülecektir. Bu durumda önce %1001 bilgisini data bitlerine veririm. Sonra %0110 bilgisini veririm program bunları içeride birleştirerek yeniden %10010110 bilgisi olarak kullanır.  Data bitlerini rastgele bağlasanız bu sefer onları 8 bit olarak bir araya getirmek için epeyce bir program yazmak gerekibilirdi. Bu ise LCD nin geç çalışmasına sebep olurdu. Bu nedenle bir birini takip eden sıralı pinler kullanılmıştır. İki seferde dörder biti alıp işlemek için.

Data bitlerinin haricinde geriye Yalnzıca RS ve E pinleri kalıyorki bunlarıda nereye isterseniz bağlayabilirsiniz. Yapmanız gereken şey define tanımlamalarında nereye bağladığınızı belirtmek hepsi bu.
Bir kaç örnek verelim,
RS=PORTA.0 da ve E pinide PORTB.0 de bağlı olsun.

Define LCD_RSREG PORTA  'RS pini PortA da bağlı diyoruz.
Define LCD_RSBIT 0           'bağlandığı pin ise sıfır nolu pin diyoruz.

Define LCD_EREG PORTB    'E pini PORTB de bağlı diyoruz
Define LCD_EBIT 0             'Bağlandığı pin ise sıfır nolu pin diyoruz.

Bu şekilde işin temelini öğretmeye çalışıyorum. Böylece nasıl olacak sorusuna kendiniz cevap bulabilirsiniz sanırım.
Son bir şey ekleyeyim. LCD den geri okuma yapmayacaksanız RW pini direk GND ye bağlı olabilir. Bu LCD ye yazma işlemlerinde standart bağlantıdır. Bu nedenle bu pini Define tanımlamalarına almadan direk GND ye bağlayabilirsiniz.
Bazen PCB de oraya GND taşımak zor oluyor ise ve boşda pininiz var ise o zaman istediğiniz bir yere alıp aşağıdaki tanımlamaları  kullanabilirsiniz.

DEFINE LCD_RWREG PORTE 'LCD read/write port
DEFINE LCD_RWBIT 2 'LCD read/write bit

Bu durumda Porogramda değişken tanımlamadan hemen sonra RW pinini LOW yapmayı unutmayın. Yukarıdaki örnek te şunu yapanız gerekecek  PORTE.2=0 

Ete


vardar07

Ete hocam geniş anlatımınıza teşekkürler. Sorudaki amacım devre dizaynını kolaylaştırmak içindi. Kolay gelsin.

Mucit23

Aslında LCD kullanımı için PBP nin hazır kütüphanesini kullanacağına lcd kullanımı için gerekli fonksiyonları kendin yazarsan istediğin gibi pinlere bağlarsın.

C de böyle

ben ccs de lcd için hep bu kütüphaneyi kullanıyorum.

//Buradaki ayar bendeki Deneme Kartina göredir, istenilirse baska Pinlere cevrilebilinir.
#define LCD_DB4   PIN_C7
#define LCD_DB5   PIN_C6
#define LCD_DB6   PIN_C5
#define LCD_DB7   PIN_C4

#define LCD_E     PIN_B0
#define LCD_RS    PIN_B1

//#define LCD_RW    PIN_B6 //Bendeki Deneme Kartinda LC_RW PIC'in GND Pinine bagli.Bu nedenle bu satiri iptal ediyoruz...
//#define USE_LCD_RW   1   // Ayni sebepden bu satirida iptal ediyoruz !!   

//========================================

#define lcd_type 2        // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the 2nd line


int8 const LCD_INIT_STRING[4] =
{
0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots
0xc,                    // Display on
1,                      // Clear display
6                       // Increment cursor
};
                             

//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note:  !! converts an integer expression
// to a boolean (1 or 0).
output_bit(LCD_DB4, !!(nibble & 1));
output_bit(LCD_DB5, !!(nibble & 2)); 
output_bit(LCD_DB6, !!(nibble & 4));   
output_bit(LCD_DB7, !!(nibble & 8));   

delay_cycles(1);
output_high(LCD_E);
delay_us(2);
output_low(LCD_E);
}

//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine.  For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.     

#ifdef USE_LCD_RW
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3

retval = 0;
   
output_high(LCD_E);
delay_cycles(1);

retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);
 
output_low(LCD_E);
   
return(retval);   
}   
#endif

//---------------------------------------
// Read a byte from the LCD and return it.

#ifdef USE_LCD_RW
int8 lcd_read_byte(void)
{
int8 low;
int8 high;

output_high(LCD_RW);
delay_cycles(1);

high = lcd_read_nibble();

low = lcd_read_nibble();

return( (high<<4) | low);
}
#endif

//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);

#ifdef USE_LCD_RW
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60); 
#endif

if(address)
   output_high(LCD_RS);
else
   output_low(LCD_RS);
     
delay_cycles(1);

#ifdef USE_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif

output_low(LCD_E);

lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}

//----------------------------
void lcd_init(void)
{
int8 i;

output_low(LCD_RS);

#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif

output_low(LCD_E);

delay_ms(15);

for(i=0 ;i < 3; i++)
   {
    lcd_send_nibble(0x03);
    delay_ms(5);
   }

lcd_send_nibble(0x02);

for(i=0; i < sizeof(LCD_INIT_STRING); i++)
   {
    lcd_send_byte(0, LCD_INIT_STRING[i]);
   
    // If the R/W signal is not used, then
    // the busy bit can't be polled.  One of
    // the init commands takes longer than
    // the hard-coded delay of 60 us, so in
    // that case, lets just do a 5 ms delay
    // after all four of them.
    #ifndef USE_LCD_RW
    delay_ms(5);
    #endif
   }

}

//----------------------------

void lcd_gotoxy(int8 x, int8 y)
{
int8 address;

if(y != 1)
   address = lcd_line_two;
else
   address=0;

address += x-1;
lcd_send_byte(0, 0x80 | address);
}

//-----------------------------
void lcd_putc(char c)
{
switch(c)
   {
    case '\f':
      lcd_send_byte(0,1);
      delay_ms(2);
      break;
   
    case '\n':
       lcd_gotoxy(1,2);
       break;
   
    case '\b':
       lcd_send_byte(0,0x10);
       break;
   
    default:
       lcd_send_byte(1,c);
       break;
   }
}

//------------------------------
#ifdef USE_LCD_RW
char lcd_getc(int8 x, int8 y)
{
char value;

lcd_gotoxy(x,y);

// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7)); 

output_high(LCD_RS);
value = lcd_read_byte();
output_low(lcd_RS);

return(value);
}
#endif


Anlaşılması çok basit.

Hazır kütüphane varken bununla uğraşmak pek mantıklı değil elbet ama enazından LCD nin çalışmasını anlarsın.  8)
Bir ulusu yok etmenin En iyi yolu o ulusun dilini yok etmektir.

www.arectron.com/

Powered by EzPortal