fernandodiaz
Junior Member
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 » |
|
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
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
|
|
|
|
|
bbarney
Moderator
Hero Member
Offline
Posts: 2429
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 ' 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
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
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
|
|
|
|
|
fernandodiaz
Junior Member
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
|
|
|
|
|