|
|
View previous topic :: View next topic |
Author |
Message |
densimitre
Joined: 21 Dec 2004 Posts: 45
|
How make a LCD menu |
Posted: Sun Dec 26, 2004 8:01 pm |
|
|
Hi
Tha is, how make a LCD menu with 4 keys, up/down, menu and enter??
some experience??
Thank you |
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Sun Dec 26, 2004 8:32 pm |
|
|
Pick a serial LCD (Jameco, for example, has a good selection). Probably you'll be able to get away with just polling the buttons.
One of my favorite tricks is to put the buttons next to the display and then use it to show the captions for the buttons (instead of putting the captions into the artwork of the front panel).
Good luck,
Nick |
|
|
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
Re: How make a LCD menu |
Posted: Mon Dec 27, 2004 3:45 am |
|
|
densimitre wrote: | Hi
Tha is, how make a LCD menu with 4 keys, up/down, menu and enter??
some experience??
Thank you |
A good way to create menus is to implement a state machine. |
|
|
Guest
|
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Thu Jan 06, 2005 3:35 pm |
|
|
Guest, show us your code. The controler chip isn't show in the pdf, so all we can do is try to debug your code. |
|
|
Guest
|
4 line x 40 characters LCD module with HD44780 Controller |
Posted: Thu Jan 06, 2005 3:51 pm |
|
|
Here is the "main.c" code:
Code: | #fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#include <LCD_40_char.c>
void main()
{
lcd_init();
while(1)
{
delay_ms(400);
printf(lcd_putc,"\fThis is Line One of the LCD\n");
delay_ms(20);
printf(lcd_putc,"\This is Line Two\n");
delay_ms(20);
printf(lcd_putc,"\This is Line Three\n");
delay_ms(20);
printf(lcd_putc,"\This is Line Four");
delay_ms(1000);
}
} |
============================================
//
// Driver "LCD_40_char.c " as follow:
//
//
=============================================
Code: | ////////////////////////////////////////////////////////////////////////////
//// LCDD.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) ////
//// ////
//// lcd_getc(x,y) Returns character at position x,y on LCD ////
//// ////
////////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,1997 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, reproduction ////
//// or distribution is permitted without written permission. ////
//// Derivative programs created using this software in object code ////
//// form are not restricted in any way. ////
////////////////////////////////////////////////////////////////////////////
// This structure is overlayed onto the data ports so that you may use
// whatever ports you desire
struct lcd_pin_map
{
int unusedA; // portA is not used
int unusedB; // portB is not used
int unusedC; // portC is not used
int data : 4; // lower nibble of portD is used for data lines
BOOLEAN enable; // PinD4
BOOLEAN rw; // PinD5
BOOLEAN rs; // PinD6
BOOLEAN dummy; // PinD7 is not used
} lcd;
#if defined(__PCH__)
#locate lcd = 0xF80
#else
#locate lcd = 5
#endif
struct lcd_tris_map
{
int unusedA; // portA is not used
int unusedB; // portB is not used
int unusedC; // portC is not used
int data : 4; // lower nibble of portD is used for data lines
int control : 3;
BOOLEAN dummy; // PinD7 is not used
} lcdtris;
#if defined(__PCH__)
#locate lcdtris = 0xF92
#else
#locate lcdtris = 0x85
#endif
#define set_tris_lcd(x) lcdtris.data = (x); lcdtris.control = 0;
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the second line
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.
// The following are used for setting
// the I/O port direction register.
#define LCD_WRITE 0 // For write mode all pins are out
#define LCD_READ 15 // For read mode data pins are in
BYTE lcd_read_byte() {
BYTE low,high;
set_tris_lcd(LCD_READ);
lcd.rw = 1;
delay_cycles(1);
lcd.enable = 1;
delay_cycles(1);
high = lcd.data;
lcd.enable = 0;
delay_cycles(1);
lcd.enable = 1;
delay_us(1);
low = lcd.data;
lcd.enable = 0;
set_tris_lcd(LCD_WRITE);
return( (high<<4) | low);
}
void lcd_send_nibble( BYTE n ) {
lcd.data = n;
delay_cycles(1);
lcd.enable = 1;
delay_us(2);
lcd.enable = 0;
}
void lcd_send_byte( BYTE address, BYTE n ) {
lcd.rs = 0;
while ( bit_test(lcd_read_byte(),7) ) ;
lcd.rs = address;
delay_cycles(1);
lcd.rw = 0;
delay_cycles(1);
lcd.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_init() {
BYTE i;
set_tris_lcd(LCD_WRITE);
lcd.rs = 0;
lcd.rw = 0;
lcd.enable = 0;
delay_ms(15);
for(i=1;i<=3;++i) {
lcd_send_nibble(3);
delay_ms(5);
}
lcd_send_nibble(2);
for(i=0;i<=3;++i)
lcd_send_byte(0,LCD_INIT_STRING[i]);
}
void lcd_gotoxy( BYTE x, BYTE y) {
BYTE 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;
}
}
char lcd_getc( BYTE x, BYTE y) {
char value;
lcd_gotoxy(x,y);
lcd.rs=1;
value = lcd_read_byte();
lcd.rs=0;
return(value);
}
|
========================
I need to modify the above code / driver to use in a 4x40 LCD module
instead of 2x16. The above work fine with the first 2 lines.
Please help.....
Thanks.. |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Thu Jan 06, 2005 5:34 pm |
|
|
I don't see the include for the processor.
So I can't tell if your doing the #locate ontop of the i/o pins correctly.
I need to know the processor, and the physical way you wired it.
Is it to port A,B,C,D... |
|
|
densimitre
Joined: 21 Dec 2004 Posts: 45
|
LCD driven by 74ls164 |
Posted: Thu Jan 06, 2005 9:48 pm |
|
|
Hi, how can i introduce this code to make that LCD work with a 74ls164 shif register in 8 bit mode and not in 4 bit mode??
How can i modify de lcd.c to do this??
Or how make a C code than do the same funcion like this asm code???
I know a littel of C....thank you
Code: |
; Send the byte in W to the 74HCT164
__LCD_SEND:
MOVWF __LCD_TEMP ; Store byte
MOVLW .8 ; Eight data bits
MOVWF __LCD_CNTR ; Store in counter
__LCD_SENDLOOP:
MOVLW 0
RLF __LCD_TEMP,F ; Rotate left into carry
BCF LCD_DATA ; Assume carry low
BTFSC STATUS, C ; Carry high?
BSF LCD_DATA ; Yes. Set port bit
; GOTO $+1 ; Wait for the data line to settle
BSF LCD_CLOCK ; Clock high
; GOTO $+1 ; Make sure the HC164 sees the transition
BCF LCD_CLOCK ; Clock low
DECFSZ __LCD_CNTR, F ; Decrement counter
GOTO __LCD_SENDLOOP ; Not zero yet; keep going
RETURN ; Counter=0; return.
|
http://www.piclist.com/techref/io/lcd/unilcd.htm
Bye |
|
|
Guest
|
4x40 LCD Problem |
Posted: Fri Jan 07, 2005 7:17 am |
|
|
I use the PIC18F452
My hardware connection as follow:
I use 4 bit data bus
LCD --- PIC
---------------
DB4 --- RD0
DB5 --- RD1
DB6 --- RD2
DB7 --- RD3
Enable1 --- RD4
R/W ------- RD5
RS --------- RD6
Enable2 --- RD7
I hope that the above information will help you understand my hardware connection. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
Re: LCD driven by 74ls164 |
Posted: Fri Jan 07, 2005 7:54 am |
|
|
densimitre wrote: | Hi, how can i introduce this code to make that LCD work with a 74ls164 shif register in 8 bit mode and not in 4 bit mode??
How can i modify de lcd.c to do this??
Or how make a C code than do the same funcion like this asm code???
I know a littel of C....thank you
Code: |
; Send the byte in W to the 74HCT164
__LCD_SEND:
MOVWF __LCD_TEMP ; Store byte
MOVLW .8 ; Eight data bits
MOVWF __LCD_CNTR ; Store in counter
__LCD_SENDLOOP:
MOVLW 0
RLF __LCD_TEMP,F ; Rotate left into carry
BCF LCD_DATA ; Assume carry low
BTFSC STATUS, C ; Carry high?
BSF LCD_DATA ; Yes. Set port bit
; GOTO $+1 ; Wait for the data line to settle
BSF LCD_CLOCK ; Clock high
; GOTO $+1 ; Make sure the HC164 sees the transition
BCF LCD_CLOCK ; Clock low
DECFSZ __LCD_CNTR, F ; Decrement counter
GOTO __LCD_SENDLOOP ; Not zero yet; keep going
RETURN ; Counter=0; return.
|
http://www.piclist.com/techref/io/lcd/unilcd.htm
Bye |
Take a look at the 74595.C file in your drivers directory. It is very similar. |
|
|
densimitre
Joined: 21 Dec 2004 Posts: 45
|
|
Posted: Sun Jan 09, 2005 10:52 am |
|
|
HI
Can you explain me that code 74595.c ???
I dont understand it...
Thank you |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
How 74595.c works |
Posted: Sun Jan 09, 2005 5:49 pm |
|
|
The driver is sending out the bits serially, one at a time MSB first, to the 74595.
First a loop is set up with the loop terminator multiplied by the number of 74595s being serviced times 8 bits since they are daisy chained.
Then the code line below tests the high bit of EO (&0x80) to see if it is zero. If it is, the DO (data output) bit is set as a low bit output else it is set as a high bit output.
if((*(eo+(NUMBER_OF_74595-1))&0x80)==0)
output_low(EXP_OUT_DO);
In the lines following the one above EO is then rotated left one position and the clock line (EXP_OUT_CLOCK) is toggled to clock the DO bit just set to the 74595. Then it loops back and E0 is tested again for a zero in the MSB. |
|
|
densimitre
Joined: 21 Dec 2004 Posts: 45
|
|
Posted: Mon Jan 10, 2005 4:40 am |
|
|
OK
Thank you very much
Isīt like 74164, i will try to modify the lcd.c driver to use 74ls164 as driver of lcd 16x2
Bye |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Jan 10, 2005 7:11 am |
|
|
densimitre wrote: | OK
Thank you very much
Isīt like 74164, i will try to modify the lcd.c driver to use 74ls164 as driver of lcd 16x2
Bye |
Wrong, it is pretty close to it. Aside from the setting/clearing then EXP_OUT_ENABLE, it does the same thing as your asm code.
Code: |
void write_LCD_port(BYTE data) {
BYTE i;
output_low(LCD_CLOCK);
for(i=1;i<=8;++i) { // Clock out bits
if((data&0x80)==0)
output_low(LCD_DATA);
else
output_high(LCD_DATA);
data <<= 1;
output_high(LCD_CLOCK);
output_low(LCD_CLOCK);
}
}
|
|
|
|
Guest
|
|
Posted: Wed Jan 12, 2005 2:27 pm |
|
|
Mark wrote: | densimitre wrote: | OK
Thank you very much
Isīt like 74164, i will try to modify the lcd.c driver to use 74ls164 as driver of lcd 16x2
Bye |
Wrong, it is pretty close to it. Aside from the setting/clearing then EXP_OUT_ENABLE, it does the same thing as your asm code.
Code: |
void write_LCD_port(BYTE data) {
BYTE i;
output_low(LCD_CLOCK);
for(i=1;i<=8;++i) { // Clock out bits
if((data&0x80)==0)
output_low(LCD_DATA);
else
output_high(LCD_DATA);
data <<= 1;
output_high(LCD_CLOCK);
output_low(LCD_CLOCK);
}
}
|
|
WOW Mark, you are a Master....i am learning C but ist a little complicated...
Thank you so much....I hope this code will work for my project...
How can i use this code like a driver.c and set the control lines (DATA, CLOCK) from a main source code, and how i can share the RS and DATA lines without imcompatibility in PIC C, ex: portb.1 = RS and portb.1 DATA?...
after shifted the byte, i will not use CLOCK, then DATAīs status doesnt affect the 74164, then i can use it to control RS line of LCD...
Thank you |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|