Lcd data pinleri tanımlarında sorun yaşıyorum?

Başlatan transistor, 08 Ocak 2024, 11:59:40

transistor

Merhaba, lcd data pinleri bit bit tanımlanabilir mi, neden istediğim bitleri kullanamıyorum? Bağlantı ve kodlarım aşağıdaki gibi,



DEFINE LCD_RSREG PORTB	            'LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT 0		    'LCD RS bacağı Hangi Bite bağlı  ?
DEFINE LCD_EREG PORTB	            'LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT	 1		    'LCD Enable Bacağı Hangi bite bağlı ?
DEFINE LCD_DREG PORTB	            'LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT  2		    'LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_BITS	 4		    'LCD 4 bit mi yoksa 8 bit olarak bağlı?
dEFINE LCD_LINES 4		    'LCD 4 satir
DEFINE LDC_COMMANDUS 2000
DEFINE LCD_DATAUS    50

Lcd data pinlerinin başlayacağı bit değerini 2 olarak yazdığımda rb2'den başlaması gerekirken rb4, rb5, rb6, rb7 sırasıyla oluyor. Sadece ilk 4 bit ile son 4 bit mi olabiliyor sadece?

transistor

Böyle bir tanımlama şekli olur mu?
DEFINE LCD_DBIT.4  2
DEFINE LCD_DBIT.5  3
DEFINE LCD_DBIT.6  4
DEFINE LCD_DBIT.7  5

ete

Normalde LCD data bitleri 8 bit üzerinden haberleşecek şekilde tasarlanmıştır.
Ancak daha sonra çok fazla işlemci pini işgal ettiği düşünülerek 8 bitlik bilgiyi ortadan ikiye bölerek yarısını bir diğer yarısınıda ayrıca yollayarak 4 bitlik yani 4 pin kullanılarak haberleşmesi sağlanmıştır.
Haberleşmede gecikme olmaması için bu işte de data pinlerinin bir birini takip eden bitler şekilde olması kararlaştırılmıştır. Böylece 8 bitlik bir bilginin ilk 4 biti YARIM=%00001111 & BILGI şeklinde alınır ve tek komutla LCD ye verilir. Sonraki 4 bit için ise benzer şekilde
IKINCIYARIM=%11110000 & BILGI şeklinde alınıp LCD ye verilir.
Şimdi diyelimki isteğinin pinleri gelişigüzel pinler olacak şekilde tanımladığında ne olacak bir düşün. Bu bitleri teker teker toplayıp onları 8 bit haline getirilmesi gerekecektirki bu iş hem bir sürü kod gerektirir hemde vakit alan bir işlemdir. Bu nedenle birbirini takip eden bitler diye şart koşulmuş üstelik 8 bitlik portun ortasından bir yerden olmaması da istenmiştir. Bu nedenle Data pinleri mutlaka PORT.0 dan veya PORT.4 den başlayacak şekilde tanımlanır. 
İkinci mesajındaki tanımlama şekli uygun değil. LCD tanımlamasında sadece başlangıç pini verilir. şekil şöyle olmalı
D
EFINE LCD_DREG PORTB    'LCD data bacaklari hangi porta bagli ? 
DEFINE LCD_DBIT  4       'LCD data bacaklari hangi bitten basliyor Yani PORTB.4 denbaşlıyor

veya

DEFINE LCD_DREG PORTB    'LCD data bacaklari hangi porta bagli ? 
DEFINE LCD_DBIT  0      'LCD data bacaklari hangi bitten basliyor ?

Ete

transistor

Anladım teşekkür ederim. I2c lcd veya modül kullanmak daha mantıklı bir yaklaşım mı olur. Ya da gecikme yönünden bir dez avantajı var mıdır 8 bit lcd'lere göre.

ete

Mantıklı düşünürsen bir bilgiyi bit bit yollamak yerine 4bit+4Bit yollamanın daha hızlı olacağını anlayabilirsin sanırım.

Ete

istinaf duvarı

#5
HD44780 uyumlu LCD'ler saniyede 60+ kez yapılması gereken tarama işini kendi içinde yapar. LCD'ye datayı gönderdikten sonra yeni data göndermez veya silme kodu göndermezseniz karakterleri sonsuza kadar ekranda tutacaktır.  Normal LCD ekranda bizim bu iş için görüntüyü 60+ kez arka arkaya yollamamız gerekirken hd44780 LCD'de görüntüde bir değişiklik yoksa veri göndermemize gerek yoktur. Sadece görüntüde değişiklik olduğu zamanlar data iletimi yaparız.

16x2'ye komple veri yollamak kontrol karakterleri ile beraber yaklaşık 40 byte (320bit) veri iletimi demektir. Bunu saniyede 10 defa yapsak 3200bit yapar. Saniyede 60 defa bunu yapsak 19200 bit yapar. I2C modüller dört bit çalıştığı için bu değerlerin iki katını göz önüne alabiliriz. Her defasında ekranı kopmple yenilemek yerine sadece değişen karakterlerin olduğu kısımları yenilersek veri aktarımı daha da düşer.

Amme hizmeti olsun. CCS için I2C LCD sürücüsü. CCS forumundan younder paylaşmıştı. Kullanıp test etmiş olduğum bir sürücü.
Kullanmadan önce I2C modülünün adres ve LCD'nin satır ve sütun değerlerini girmeniz gerekiyor. Varsayılan değerler, Adres 0x4E, ve 20x4 LCD'dir. Bu bilgiler LCD sürücüsü çağrılmadan önce girilmelidir. Aksi takdirde sürücü içindeki varsayılan değerler aktif olacaktır. Orjinal kodda bu değerler sabit olarak belirlenmiş, burasını elle yapılandırılabilir hale getirdim.  Örnek:

#define LCD_ADDR              0x4E        //I2C slave address for LCD module
#define lcd_total_rows        4           //Number of rows: 1,2,3 or 4
#define lcd_total_columns     20          //Number of columns: 1...20
#include <i2c_lcd.c>

//-----------------------------------------------------------------------------
// Title:         i2c_Flex_LCD
// Description:   Driver for common LCD with 1/2/3 or 4 rows by 1...20 columns
//                using PCF8574T interface board with I2C protocol.
// Date:          Nov-2013
// Ver.Rev.:      1.1
// Author:        Hugo Silva (sergio-hugo@bol.com.br) #Based on the routines of
//                "20X4_LCD_I2C_DRIVER.h" from Pumrin S. and "lcd4_i2c.c" from XP8100
//-----------------------------------------------------------------------------
//
// lcd_init() Must be called before any other function.
//
// lcd_putc(c) Will display c on the next position of the LCD.
// 
//     \f Clear LCD display
//     \n Set write position on next lcd line
//     \b LCD backspace
//     lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1)
//
// lcd_backlight_led(ON)/lcd_backlight_led(OFF) = Turn ON/OFF LCD Backlight LED
//
//-----------------------------------------------------------------------------
// LCD pins D0-D3 are not used.
//-----------------------------------------------------------------------------
//
// Comment   : Control of a compatible LCD (1...4 rows by 1...4 columns) from
//              a bus I2C with an EXPANDER of I/O with connection I2C.
//              The tests of these routines have been programmed using the IC
//              Phillips PCF8574T. I've used 4 bits mode programming.
//              The 8 bits mode programming is possible if you use 2 x PCF8574T.
//              RW Pin is not being used.
//
// As defined in the following structure the pin connection is as follows:
//
//  PCF8574P     LCD
//  ========     ======
//     P0        RS
//     P1        RW    (Not used!)
//     P2        Enable 
//     P3        Led Backlight
//     P4        D4
//     P5        D5
//     P6        D6
//     P7        D7
//
//  The SCL and SDA pins should be pull-up resistor as shown below:
//
//             +5v
//               |
//               <
//               > 4.7K       
//               <         
//To PIC         |          To i2c slave
//pin xx ------------------ SDA pin 
//(SDA)                     
//              +5v
//               |
//               <
//               > 4.7K       
//               <         
//To PIC         |          To i2c slave
//pin xx ------------------ SCL pin 
//(SCL)
//
//To PIC                    To i2c slave
//Vss pin ----------------- Vss or ground pin 
//                |
//              -----
//               ---  Ground
//                - 
// 
// THIS DOCUMENT IS PROVIDED TO THE USER "AS IS"
//-----------------------------------------------------------------------------
#ifndef LCD_ADDR
#define LCD_ADDR              0x4E        //Default I2C slave address for LCD module
#endif
#ifndef lcd_total_rows
#define lcd_total_rows        4           //Default number of rows: 1,2,3 or 4
#endif
#ifndef lcd_total_columns
#define lcd_total_columns     20          //Default number of columns: 1...20
#endif    

#define RS                    0b00000001  //P0 - PCF8574T Pin connected to RS
#define RW                    0b00000010  //P1 - PCF8574T Pin connected to RW
#define ENABLE                0b00000100  //P2 - PCF8574T Pin connected to EN
#define LCD_BACKLIGHT         0b00001000  //P3 - PCF8574T Pin connected to BACKLIGHT LED

#define addr_row_one          0x00        //LCD RAM address for row 1
#define addr_row_two          0x40        //LCD RAM address for row 2
#define addr_row_three        0x14        //LCD RAM address for row 3
#define addr_row_four         0x54        //LCD RAM address for row 4

#define ON                    1
#define OFF                   0
#define NOT                   ~
#define data_shifted          data<<4
int8 new_row_request=1, BACKLIGHT_LED=LCD_BACKLIGHT;

void lcd_backlight_led(byte bl)
{ 
      If (bl) BACKLIGHT_LED=LCD_BACKLIGHT; else BACKLIGHT_LED=OFF;
}

void i2c_send_nibble(byte data, byte type)
{   
   switch (type)
   {     
      case 0 :     
      i2c_write(data_shifted | BACKLIGHT_LED);
      delay_cycles(1);
      i2c_write(data_shifted | ENABLE | BACKLIGHT_LED );
      delay_us(2);
      i2c_write(data_shifted & NOT ENABLE | BACKLIGHT_LED);
      break;
     
      case 1 :
      i2c_write(data_shifted | RS | BACKLIGHT_LED);
      delay_cycles(1);
      i2c_write(data_shifted | RS | ENABLE | BACKLIGHT_LED );
      delay_us(2);
     i2c_write(data_shifted | RS | BACKLIGHT_LED); //fix
      break;
   }
} 
   
void lcd_send_byte(byte data, byte type)
   {
        i2c_start();
        i2c_write(LCD_ADDR);
        i2c_send_nibble(data >> 4 , type);
        i2c_send_nibble(data & 0xf , type);
        i2c_stop();       
   }

void lcd_clear()
{ 
        lcd_send_byte(0x01,0);
        delay_ms(2);
        new_row_request=1;
}

void lcd_init(void)
{
   byte i;
   byte CONST lcd_type=2;  // 0=5x7, 1=5x10, 2=2 lines
   byte CONST LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6}; // These bytes need to be sent to the LCD to start it up.

   disable_interrupts(GLOBAL);
   delay_ms(50); //LCD power up delay
   
   i2c_start();
   i2c_write(LCD_ADDR);
      i2c_send_nibble(0x00,0);
      delay_ms(15);
   
   for (i=1;i<=3;++i)   
   {
      i2c_send_nibble(0x03,0);
      delay_ms(5);
   }   
      i2c_send_nibble(0x02,0);
      delay_ms(5);
   i2c_stop();
   
   for (i=0;i<=3;++i) {
   lcd_send_byte(LCD_INIT_STRING[i],0);
   delay_ms(5);
   }
   lcd_clear();  //Clear Display
   enable_interrupts(GLOBAL);
}

void lcd_gotoxy( byte x, byte y)
{
byte row,column,row_addr,lcd_address;
static char data;

   if (y>lcd_total_rows) row=lcd_total_rows; else row=y;
 
   switch(row)
   {
      case 1:  row_addr=addr_row_one;     break;
      case 2:  row_addr=addr_row_two;     break;
      case 3:  row_addr=addr_row_three;   break;
      case 4:  row_addr=addr_row_four;    break;
      default: row_addr=addr_row_one;     break; 
   } 
   
   if (x>lcd_total_columns) column=lcd_total_columns; else column=x; 
   lcd_address=(row_addr+(column-1));
   lcd_send_byte(0x80|lcd_address,0);
}

//Display the character on LCD screen.
void LCD_PUTC(char in_data)
{   
  switch(in_data)
   { 
     case '\f': lcd_clear();                       break;               
     
     case '\n':
     new_row_request++;
     if (new_row_request>lcd_total_rows) new_row_request=1;
     lcd_gotoxy(1, new_row_request);
     break;
                 
     case '\b': lcd_send_byte(0x10,0);             break;
       
     default: lcd_send_byte(in_data,1);            break;     
     
   }
} 

I2C modüllerin veri hızı 16x2 LCD'leri sürmek için fazlasıyla yeterlidir. Burada tek problem gecikme olabilir.

Powered by EzPortal