Sonsivri
 
*
Welcome, Guest. Please login or register.
Did you miss your activation email?
April 23, 2024, 07:37:38 07:37


Login with username, password and session length


Pages: [1]
Print
Author Topic: LCD 40x4 characters  (Read 9848 times)
0 Members and 1 Guest are viewing this topic.
fernandodiaz
Junior Member
**
Offline Offline

Posts: 73

Thank You
-Given: 1
-Receive: 18


« on: July 29, 2006, 03:17:48 03:17 »

Hi i have a problem a LCD 40x4 characters the problem is:
 
the LCD  have 2 pin ENABLE (enable and enable1)  for make control line 1,2 and 3,4
but the compiler proton plus and picbasic only support  control in only one pin Enable and no multiplexing
 
were i download sample program for control 40x4 lines  with basic compilers or
 
wath buy  LCD  support 4 lines  x 4 character  fotr this version compilers
 
 
I need multiplexing control in
Logged
MiCrO-BiT
Guest
« Reply #1 on: April 10, 2008, 05:02:36 17:02 »

Code:
This driver is for use with 40x4 LCDs. It's based in flex_lcd420 by CCS C compiler

//lcd_40x4_h.c
// These pins are for my Microchip PicDem2-Plus board,
// which I used to test this driver.
// An external 20x4 LCD is connected to these pins.
// Change these pins to match your own board's connections.

#define LCD_DB4   PIN_B4
#define LCD_DB5   PIN_B5
#define LCD_DB6   PIN_B6
#define LCD_DB7   PIN_B7

#define LCD_RS    PIN_B0
#define LCD_RW    PIN_B1
#define LCD_E1    PIN_B2
#define LCD_E2    PIN_B3
/*
// To prove that the driver can be used with random
// pins, I also tested it with these pins:
#define LCD_DB4   PIN_D4
#define LCD_DB5   PIN_B1
#define LCD_DB6   PIN_C5
#define LCD_DB7   PIN_B5

#define LCD_RS    PIN_E2
#define LCD_RW    PIN_B2
#define LCD_E1     PIN_D6
*/

// If you want only a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.  Doing so will save one PIC
// pin, but at the cost of losing the ability to read from
// the LCD.  It also makes the write time a little longer
// because a static delay must be used, instead of polling
// the LCD's busy bit.  Normally a 6-pin interface is only
// used if you are running out of PIC pins, and you need
// to use as few as possible for the LCD.
#define USE_RW_PIN   1     


// These are the line addresses for most 4x20 LCDs.
#define LCD_LINE_1_ADDRESS 0x00
#define LCD_LINE_2_ADDRESS 0x40
#define LCD_LINE_3_ADDRESS 0x00
#define LCD_LINE_4_ADDRESS 0x40

// These are the line addresses for LCD's which use
// the Hitachi HD66712U controller chip.
/*
#define LCD_LINE_1_ADDRESS 0x00
#define LCD_LINE_2_ADDRESS 0x20
#define LCD_LINE_3_ADDRESS 0x40
#define LCD_LINE_4_ADDRESS 0x60
*/


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

#define lcd_type 2   // 0=5x7, 1=5x10, 2=2 lines(or more)

int8 lcd_line;

int8 const LCD_INIT_STRING[4] =
{
 0x20 | (lcd_type << 2),  // Set mode: 4-bit, 2+ lines, 5x8 dots
 0xc,                     // Display on
 1,                       // Clear display
 6                        // Increment cursor
 };
                             
//DISPLAY 1
//-------------------------------------
void lcd_send_nibble1(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_E1);
 delay_us(2);
 output_low(LCD_E1);
}

//DISPLAY 2
//-------------------------------------
void lcd_send_nibble2(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_E2);
 delay_us(2);
 output_low(LCD_E2);
}


//-----------------------------------
// 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_RW_PIN
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_E1);

delay_us(1);

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


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

#ifdef USE_RW_PIN
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

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

#ifdef USE_RW_PIN
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_RW_PIN
output_low(LCD_RW);
delay_cycles(1);
#endif

output_low(LCD_E1);


lcd_send_nibble1(n >> 4);
lcd_send_nibble1(n & 0xf);
}
//----------------------------

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

#ifdef USE_RW_PIN
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_RW_PIN
output_low(LCD_RW);
delay_cycles(1);
#endif

output_low(LCD_E2);


lcd_send_nibble2(n >> 4);
lcd_send_nibble2(n & 0xf);
}
//----------------------------

//DISPLAY 1
//----------------------------
void lcd_init1(void)
{
int8 i;

lcd_line = 1;

output_low(LCD_RS);

#ifdef USE_RW_PIN
output_low(LCD_RW);
#endif

output_low(LCD_E1);



// Some LCDs require 15 ms minimum delay after
// power-up.  Others require 30 ms.  I'm going
// to set it to 35 ms, so it should work with
// all of them.
delay_ms(35);         

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

lcd_send_nibble1(0x02);

for(i=0; i < sizeof(LCD_INIT_STRING); i++)
   {
    lcd_send_byte1(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 50 us, so in
    // that case, lets just do a 5 ms delay
    // after all four of them.
    #ifndef USE_RW_PIN
    delay_ms(5);
    #endif
   }

}

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

//DISPLAY 2
//----------------------------
void lcd_init2(void)
{
int8 i;

lcd_line = 1;

output_low(LCD_RS);

#ifdef USE_RW_PIN
output_low(LCD_RW);
#endif

output_low(LCD_E2);


// Some LCDs require 15 ms minimum delay after
// power-up.  Others require 30 ms.  I'm going
// to set it to 35 ms, so it should work with
// all of them.
delay_ms(35);         

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

lcd_send_nibble2(0x02);

for(i=0; i < sizeof(LCD_INIT_STRING); i++)
   {
    lcd_send_byte2(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 50 us, so in
    // that case, lets just do a 5 ms delay
    // after all four of them.
    #ifndef USE_RW_PIN
    delay_ms(5);
    #endif
   }

}

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



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


switch(y)
  {
   case 1:
     address = LCD_LINE_1_ADDRESS;
     break;

   case 2:
     address = LCD_LINE_2_ADDRESS;
     break;

   case 3:
     address = LCD_LINE_3_ADDRESS;
     break;

   case 4:
     address = LCD_LINE_4_ADDRESS;
     break;

   default:
     address = LCD_LINE_1_ADDRESS;
     break;
     
  }

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

// DISPLAY 1
//-----------------------------
void lcd_putc1(char c)
{
 switch(c)
   {
    case '\f':
      lcd_send_byte1(0,1);
      lcd_line = 1;
      delay_ms(2);
      break;
   
    case '\n':
       lcd_gotoxy(1, ++lcd_line);
       break;
   
    case '\b':
       lcd_send_byte1(0,0x10);
       break;
   
    default:
       lcd_send_byte1(1,c);
       break;
   }
}

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


//DISPLAY 2
//-----------------------------
void lcd_putc2(char c)
{
 switch(c)
   {
    case '\f':
      lcd_send_byte2(0,1);
      lcd_line = 1;
      delay_ms(2);
      break;
   
    case '\n':
       lcd_gotoxy(1, ++lcd_line);
       break;
   
    case '\b':
       lcd_send_byte2(0,0x10);
       break;
   
    default:
       lcd_send_byte2(1,c);
       break;
   }
}

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



#ifdef USE_RW_PIN
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
« Last Edit: May 23, 2008, 07:17:49 19:17 by metal » Logged
boss.lrc
Guest
« Reply #2 on: May 05, 2008, 07:14:21 19:14 »

Hi fernandodiaz

What type of PIC have who used for the LCD 40x4 characters, or the LCD had a microntrolor included?

Thanks

Regards

Logged
sputnik
Junior Member
**
Offline Offline

Posts: 40

Thank You
-Given: 9
-Receive: 39


« Reply #3 on: May 06, 2008, 12:46:26 00:46 »

I was going to say that it would be fairly simple to modify the the include for the LCD routines in Proton but I cannot find one in the Proton include folder, or the whole install for that matter.

If someone can find where the routines are located I will be happy to modify it. It may be in the executable however.

A 40x4 LCD is just 2 20x4 LCDs in one package, the enable lines select which "lcd" (chip) to write to.

You could do it using 3 extra pic pins. Bring the enable IN to one, then the 2 enables on the LCD to the 2 others and control the flow to the LCDs chips in your program. Create a "qualifier" that if its in your print line it will route the enable to LCD1 or LCD2.
Logged
fernandodiaz
Junior Member
**
Offline Offline

Posts: 73

Thank You
-Given: 1
-Receive: 18


« Reply #4 on: May 07, 2008, 07:28:38 19:28 »

HI FRIENDS
READ THIS:
http://www.picbasic.org/forum/showthread.php?t=4590

I TEST THIS CIRCUIT AND RUN GOOD
Logged
bbarney
Moderator
Hero Member
*****
Offline Offline

Posts: 2430

Thank You
-Given: 405
-Receive: 545


Uhm? where did pickit put my mute button


« Reply #5 on: May 20, 2008, 04:10:07 04:10 »

there in C:\Program Files\Crownhill\PDS\INC\Sources
there are all the inc files in that directory
heres the PROTON_4.INC

Code:
' Header file for the Proton Development Board
' Using a 16F877 Device with a 4MHz Oscillator
'
DEVICE = 16F877
XTAL = 4


LCD_DTPIN = PORTD.4
LCD_RSPIN = PORTE.0
LCD_ENPIN = PORTE.1
LCD_INTERFACE = 4
LCD_LINES = 2
LCD_TYPE = 0
LCD_COMMANDUS = 2000
LCD_DATAUS = 50

SCL_PIN = PORTC.3
SDA_PIN = PORTC.4

SERIAL_BAUD = 9600
RSOUT_PIN = PORTC.6
RSOUT_MODE = TRUE
RSOUT_PACE = 1
RSIN_PIN = PORTC.7
RSIN_MODE = TRUE


HSERIAL_BAUD = 9600 ' Set baud rate to 9600
HSERIAL_RCSTA = %10010000       ' Enable serial port and continuous receive
HSERIAL_TXSTA = %00100100       ' Enable transmit and asynchronous mode
HSERIAL_CLEAR = ON ' Enable Error clearing on received characters


KEYPAD_PORT = PORTB

CCP1_PIN = PORTC.2
CCP2_PIN = PORTC.1

Symbol T300 = 3313
Symbol N300 = 3313 + $4000
Symbol T600 = 1646
Symbol N600 = 1646 + $4000
Symbol T1200 = 813
Symbol N1200 = 813 + $4000
Symbol T2400 = 396
Symbol N2400 = 396 + $4000
Symbol T4800 = 188
Symbol N4800 = 188 + $4000
Symbol T9600 = 84
Symbol N9600 = 84 + $4000

Symbol OT2400 = 396 + $8000         ' Open True
Symbol OT1200 = 813 + $8000         ' Open True
Symbol OT9600 = 84 + $8000       ' Open True
Symbol OT300  = 3313 + $8000       ' Open True

Symbol ON2400 = 396 + $4000 + $8000       ' Open Inverted
Symbol ON1200 = 813 + $4000 + $8000       ' Open Inverted
Symbol ON9600 = 84 + $4000 + $8000       ' Open Inverted
Symbol ON300  = 3313 + $4000 + $8000     ' Open Inverted

' Rsout / Serial Constants
Symbol HOME = 1
Symbol BELL = 7
Symbol BKSP = 8
Symbol TAB = 9
Symbol CR = 13

ALL_DIGITAL = TRUE ' Set PORTA and PORTE to all digital



I was going to say that it would be fairly simple to modify the the include for the LCD routines in Proton but I cannot find one in the Proton include folder, or the whole install for that matter.

If someone can find where the routines are located I will be happy to modify it. It may be in the executable however.

A 40x4 LCD is just 2 20x4 LCDs in one package, the enable lines select which "lcd" (chip) to write to.

You could do it using 3 extra pic pins. Bring the enable IN to one, then the 2 enables on the LCD to the 2 others and control the flow to the LCDs chips in your program. Create a "qualifier" that if its in your print line it will route the enable to LCD1 or LCD2.
« Last Edit: May 23, 2008, 07:18:25 19:18 by metal » Logged

Ever wonder why Kamikaze pilot's wore helmet's ?
sputnik
Junior Member
**
Offline Offline

Posts: 40

Thank You
-Given: 9
-Receive: 39


« Reply #6 on: May 23, 2008, 05:41:49 05:41 »

I was talking about the actual macro that the compiler uses with the LCD commands, not just the normal include. I dont think one exists in the install anywhere. I think it is actually part of the compiler rather than a macro/include.



there in C:\Program Files\Crownhill\PDS\INC\Sources
there are all the inc files in that directory
heres the PROTON_4.INC

' Header file for the Proton Development Board
' Using a 16F877 Device with a 4MHz Oscillator
'
   DEVICE = 16F877
   XTAL = 4


   LCD_DTPIN = PORTD.4
   LCD_RSPIN = PORTE.0
   LCD_ENPIN = PORTE.1
   LCD_INTERFACE = 4
   LCD_LINES = 2
   LCD_TYPE = 0
   LCD_COMMANDUS = 2000
   LCD_DATAUS = 50

   SCL_PIN   = PORTC.3
   SDA_PIN   = PORTC.4

   SERIAL_BAUD = 9600
   RSOUT_PIN = PORTC.6
   RSOUT_MODE = TRUE
   RSOUT_PACE = 1
   RSIN_PIN = PORTC.7
   RSIN_MODE = TRUE


   HSERIAL_BAUD = 9600            ' Set baud rate to 9600
   HSERIAL_RCSTA = %10010000       ' Enable serial port and continuous receive
   HSERIAL_TXSTA = %00100100       ' Enable transmit and asynchronous mode
   HSERIAL_CLEAR = ON            ' Enable Error clearing on received characters


   KEYPAD_PORT = PORTB

   CCP1_PIN = PORTC.2
   CCP2_PIN = PORTC.1

   Symbol T300 = 3313
   Symbol N300 = 3313 + $4000
   Symbol T600 = 1646
   Symbol N600 = 1646 + $4000
   Symbol T1200 = 813
   Symbol N1200 = 813 + $4000
   Symbol T2400 = 396
   Symbol N2400 = 396 + $4000
   Symbol T4800 = 188
   Symbol N4800 = 188 + $4000
   Symbol T9600 = 84
   Symbol N9600 = 84 + $4000

   Symbol OT2400 = 396 + $8000                   ' Open True
   Symbol OT1200 = 813 + $8000                   ' Open True
   Symbol OT9600 = 84 + $8000                  ' Open True
   Symbol OT300  = 3313 + $8000               ' Open True

   Symbol ON2400 = 396 + $4000 + $8000            ' Open Inverted
   Symbol ON1200 = 813 + $4000 + $8000            ' Open Inverted
   Symbol ON9600 = 84 + $4000 + $8000            ' Open Inverted
   Symbol ON300  = 3313 + $4000 + $8000        ' Open Inverted

' Rsout / Serial Constants
   Symbol HOME = 1
   Symbol BELL = 7
   Symbol BKSP = 8
   Symbol TAB = 9
   Symbol CR = 13

   ALL_DIGITAL = TRUE   ' Set PORTA and PORTE to all digital




Logged
oscar.inc
Newbie
*
Offline Offline

Posts: 11

Thank You
-Given: 2
-Receive: 1


« Reply #7 on: May 24, 2008, 02:48:53 14:48 »

THE CODE SINGLE

DEVICE = 16F877 ' CHOOSE PIC

XTAL = 4            ' SPEED CRYSTAL

TRISB %00000000 ' INPUT PRTB

DIM DATO AS BIT 'DECLARE VARIABLE

' DECLARE ALIAS FOR ANI MORE EASY

ALIAS INPUT AS SERIAL IN

'LCD' DECLARE, FOR CONTROL WHIT PORT E

LCD_DTPIN = PORTE.2
LCD_RSPIN = PORTE.0
LCD_ENPIN = PORTE.1
LCD_INTERFACE = 4
LCD_LINES = 2

SERIAL_BAUD = 9600 'SPEED TRANSMIT

INPUT = DATO
WHEN INPUT AS > 1 THEN
PRINT AT 1,1 "SONSIVRI" ' WRITE LCD LINE 1 CHARACTER 1

DELAYMS 2000 ' TIME DELAY

CLR_LCD ' CLEAR DYSPLAY

' MONITORING DATA SERIAL

IF PORTB.1 = 1 THEN

PRINT AT 1,1 @ DATO

END IF




' SEND DATA FROM THE YPERTERMINAL
'CONFIGURE PORT 9600,N,1

'REGARDS


   
   
   
Logged
drnewton
Guest
« Reply #8 on: June 15, 2008, 10:05:21 22:05 »

Look at this nice trick for driving an LCD with only 3 lines:
http://www.arduino.cc/playground/Code/LCD3wires
Logged
fernandodiaz
Junior Member
**
Offline Offline

Posts: 73

Thank You
-Given: 1
-Receive: 18


« Reply #9 on: August 13, 2008, 12:44:11 00:44 »

This reality  work good

device 16f877


Declare   LCD_INTERFACE   4        '  4-bit Interface NUERO DE CABLES
Declare   LCD_LINES       2         '  NUMERO DE LINEAS DEL LCD
Declare     LCD_TYPE        0         '  TIPO DEL LCD ALFA NUMERICO O GRAFICO
Declare   LCD_DTPIN       PORTC.4    '  LADO IZQ O DERECHO DEL PUERTO
Declare   LCD_RSPIN       PORTC.2   '  PIN DE RS   LCD
Declare   LCD_ENPIN       PORTC.3   '  PIN DE EN   LCD
Declare   LCD_COMMANDUS   2000
Declare     LCD_DATAUS      50



GoSub LIMPIAR
GoSub LINEA12
Print At 1,9,"hola usando linea 1 2"

DelayMS 1500
GoSub LINEA34
Print At 2,3,"ahora estamos usando linea 3 4"
DelayMS 2000


end



'_____________________________________LCD________________CLR_______________________
LINEA12:
   Low PORTE.1 ' pic EN1 pin   
       High PORTE.2 ' pic EN2 pin   
Return

LINEA34:
   High PORTE.1  ' pic EN1 pin
        Low PORTE.2   ' pic EN2 pin
   
Return

LIMPIAR:
   Input PORTE.1 ' pic EN1 pin
        Input PORTE.2 ' pic EN2 pin
Cls
DelayMS 10
Output PORTE.1  ' pic EN1 pin
Output PORTE.2  ' pic EN2 pin
Return
'_____________________________________LCD________________CLR_______________
Logged
Pages: [1]
Print
Jump to:  


DISCLAIMER
WE DONT HOST ANY ILLEGAL FILES ON THE SERVER
USE CONTACT US TO REPORT ILLEGAL FILES
ADMINISTRATORS CANNOT BE HELD RESPONSIBLE FOR USERS POSTS AND LINKS

... Copyright © 2003-2999 Sonsivri.to ...
Powered by SMF 1.1.18 | SMF © 2006-2009, Simple Machines LLC | HarzeM Dilber MC