Picproje Elektronik Sitesi

DERLEYİCİLER => CCS C => Konuyu başlatan: zafzaf82 - 01 Eylül 2006, 10:41:38

Başlık: CCS de 2 pinle LCD yi çalıştırmak
Gönderen: zafzaf82 - 01 Eylül 2006, 10:41:38
Selam Arkadaşlar bi sitede buldugum LCD driver'i sizinle paylaşmak istedim.

#if defined(__PCM__)
#include <16F628A.h>


#FUSES NOWDT                 //No Watch Dog Timer
#FUSES INTRC                 //Internal RC Osc
#FUSES NOPUT                 //No Power Up Timer
#FUSES NOPROTECT             //Code not protected from reading
#FUSES NOBROWNOUT             //No brownout reset
#FUSES NOMCLR                 //Master Clear pin used for I/O
#FUSES NOLVP                 //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD               //No EE protection


#use delay(clock=4000000,RESTART_WDT)
#include <LCDHG.C>

void main()
{
  setup_oscillator(4000000);

  lcd_init(); // LCd ile haberleş

  for(;;)
  {
  lcd_gotoxy(1,1);
  lcd_putc("DENEME\n");
  lcd_putc("LCD CALISIYOOOOO");
  DELAY_MS(100);

  }
}


Yukarıda yazdığım programla aşagıdaki driveri denedim ve çalıştı.

//// LCDHG.C
//// Driver for common LCD modules
////
//// lcd_init() Must be called before any other function. ////
//// lcd_putc(c) Will display c on the next position of the LCD.
//// The following have special meaning:
//// \f Clear display
//// \n Go to start of second line
//// \b Move back one position
////
//// lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1)
////
/*
I adapt CCS driver for use the 2wire serial lcd interface.

I found this interface very useful for lcd when a 1 wire serial lcd is not practical due use of INTRC osc configuration. This interface has no timings problem when used with internal osc!.

Just define in the main c module the 2 pins LCDCLK, LCDDAT..

I test this code in 16f84, 16f877, 16f628 with rc / intrc at 4mhz.
For 18fx52 20-40mhz operation, delays in lcd_es() is needed.

Original idea from Myke Predko.
For the schematics please see http://www.rentron.com/Myke1.htm .

*/

#ifndef LCDCLK
#define LCDCLK PIN_A2
#endif

#ifndef LCDDAT
#define LCDDAT PIN_A3
#endif

#define DATA1 output_high(LCDDAT)
#define DATA0 output_low(LCDDAT)

void lcd_Es()
{
output_high(LCDDAT);
//delay_us(200); //only in high mhz
output_low(LCDDAT);
}

void lcd_Clk()
{
output_high(LCDCLK);
output_low(LCDCLK);

}


void lcd_Send_Nibble( char nibble, int1 rs)
{
int8 i;

DATA0; // clear output
for (i=0; i<6; i++) lcd_Clk();

DATA1; // Output the "AND" Value
lcd_Clk();

IF (rs==1) DATA1; // Output the RS Bit Value
ELSE DATA0;
lcd_Clk();

for (i = 0; i<4; i++) // Output the Nybble
{
if (nibble & 0x08) DATA1; // Output the High Order Bit
else DATA0;
lcd_Clk(); // Strobe the Clock
nibble<<=1; // Shift up Nybble for Next Byte
}
lcd_Es(); // Toggle the "E" Clock Bit
}


void lcd_send_byte( int n , int1 rs)
{
lcd_send_nibble(n >> 4 , rs);
lcd_send_nibble(n & 0xf, rs);
}


void lcd_init( void)
{
lcd_send_nibble(0x03,0);
delay_ms(5);
lcd_es();
delay_us(160);
lcd_es();
delay_us(160);
lcd_send_nibble(0x02,0);
delay_us(160);
lcd_send_byte(0x28,0);
lcd_send_byte(0x08,0);
lcd_send_byte(0x01,0);
delay_ms(5);
lcd_send_byte(0x06,0);
lcd_send_byte(0x0C,0);
}


void lcd_gotoxy( int x, int y)
{
BYTE address;
if (y!=1) address=0x40;
else address=0;
address+=x-1;
lcd_send_byte(0x80|address,0);
}


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


http://rapidshare.de/files/31523197/2_wire_lcd_deneme.rar.html
Başlık: Eğer çalışıyorsa harika.
Gönderen: fuko88 - 04 Eylül 2006, 10:32:42
2 bacak gerçekten de harika. Bende deneyeceğim bunu. Eğer çalışıyorsa/çalıştırabilirsem çok güzel olur gerçekten.
Bi yan etkisi oluyor mu peki? Gecikme vb. ?
Başlık: CCS de 2 pinle LCD yi çalıştırmak
Gönderen: zafzaf82 - 04 Eylül 2006, 17:10:54
tabiki biraz gecikme oluyor. Altprograma bakarsan görebilirsin.
Başlık: CCS de 2 pinle LCD yi çalıştırmak
Gönderen: tufantuncer - 15 Eylül 2006, 18:11:27
dosyayı indirdim fakat bendeki proteusla açamadım
acaba resmi upload edebilirmisiniz devreyi gorup denemek istiyorum da
Başlık: CCS de 2 pinle LCD yi çalıştırmak
Gönderen: tufantuncer - 15 Eylül 2006, 18:41:46
birde bende pic dem2 deneme boardı var bu boardta 16x2 lcd var, pic16f648a pic te var, yanlız henuz uygulama geliştiremedim. ccs c compiler kullanmak istiyorum,c de yazdığım kodda lcd yi surerken yukarıdaki gibi    
  lcd_gotoxy(1,1);
  lcd_putc("DENEME\n");
  lcd_putc("LCD CALISIYOOOOO");
  DELAY_MS(100);
gibi komutlar kullanıp, denemeler yapmak istiyorum, bunun için gerekli header dosyaları nasıl bulabilirim, birde pinlerin nereye bağlandığı kendim belirlemek istiyorum. pic16f648A kullanıyorum bide o var. 4 pini kullanabildiğim veya 8pinde olabilir denemek için lcd driver kodu nereden bulabilirmiyim , yardımcı olursanız sevinirim
Başlık: CCS de 2 pinle LCD yi çalıştırmak
Gönderen: zafzaf82 - 17 Eylül 2006, 16:32:59
bağlantıyı bu şekilde yapabilirsin.
(http://www.rentron.com/2wirelcd.jpg)
Başlık: CCS de 2 pinle LCD yi çalıştırmak
Gönderen: zafzaf82 - 17 Eylül 2006, 16:37:12
@tufantuncer aşagıdaki header dosyasını kullanarak LCD yi pic'in istediğin pinine bağlayabilirsin.
// flex_lcd.c

// These pins are for the Microchip PicDem2-Plus board,
// which is what I used to test the driver.  Change these
// pins to fit your own board.

#define LCD_DB4   PIN_D0
#define LCD_DB5   PIN_D1
#define LCD_DB6   PIN_D2
#define LCD_DB7   PIN_D3

#define LCD_E     PIN_A1
#define LCD_RS    PIN_A3
#define LCD_RW    PIN_A2

// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.

#define USE_LCD_RW   1    

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

#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


istediğin pine LCD yi bağlamak için
#define LCD_DB4   PIN_D0
#define LCD_DB5   PIN_D1
#define LCD_DB6   PIN_D2
#define LCD_DB7   PIN_D3

#define LCD_E     PIN_A1
#define LCD_RS    PIN_A3
#define LCD_RW    PIN_A2

kodlarını değiştrimen yeterlidir.
Başlık: CCS de 2 pinle LCD yi çalıştırmak
Gönderen: tufantuncer - 19 Eylül 2006, 10:30:13
dostum yardımların için teşekkür ederim, ama ben gene çalıştıramadım pic c de compile ederken
int8 const LCD_INIT_STRING[4] =    bu komutta hata veriyor, onune #device yazmalısın diyor, yazıyorum bu seferde farklı hatalar ortaya cıkıyor. acaba başka bir header dosyası felan mı gereki? int8 tipinin içinde tanımlandığı?
Başlık: CCS de 2 pinle LCD yi çalıştırmak
Gönderen: zafzaf82 - 23 Eylül 2006, 23:53:45
yukarıda verdiğim heddar dosyasını kopyala flex_lcd.c diye programın main dosyasının bulundugu klasöre kaydet.
Sonra şu programı yaz çalışacaktır.


#if defined(__PCM__)
#include <16F84A.h>


#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOCPD                  //No EE protection


#use delay(clock=4000000,RESTART_WDT)
#include <flex_lcd.c>

void main()
{

  lcd_init(); // LCd ile haberleş

  while(TRUE)
  {
  lcd_gotoxy(1,1);
  printf(lcd_putc,"INSALLAH");
  lcd_gotoxy(1,2);
  printf(lcd_putc,"LCD CALISICAK :)");
  delay_ms(100);
  }
}


tabi lcd nin pinlerini 16f84 e görede ayarlamayı unutma.
#define LCD_DB4   PIN_D0
#define LCD_DB5   PIN_B1
#define LCD_DB6   PIN_B2
#define LCD_DB7   PIN_B3

#define LCD_E     PIN_A1
#define LCD_RS    PIN_A3
#define LCD_RW    PIN_A2


Kolay gelsin....