|
|
View previous topic :: View next topic |
Author |
Message |
Ed_Banses
Joined: 15 Sep 2005 Posts: 15
|
Batron LCD Driver Issue |
Posted: Mon Aug 14, 2006 8:52 am |
|
|
Hi all,
I have place a post in the Code Library Forum asking for support of one of the drivers placed there. As I don't know if that is the bast place to ask for help, I have decided to place it here as well.
If the administrators think that it should be in the other forum, please delete this post
My question is about the flexible LCD driver from PCM Programmer.
I am trying to work with his driver with a LCD Batron BTHQ42003AV-FSTF-06. This is a 20x4 LCD and the controller is a HITACHI HCD66712UA02.
I am getting communication and some text is being displayed on it but I am getting some weird responses when I try to change the line or the number of character I send is big. Example:
code:
Code: |
lcd_init();
lcd_putc("\fHey you mate! Are you talking to me?");
|
LCD display:
Hey you mate! Are yo
! Are you talking to
Another example:
Code:
Code: |
lcd_init();
lcd_putc("\fHey");
//lcd_gotoxy(1,2);
//lcd_putc("you");
|
LCD display:
Hey
you
Next is the code of the modified driver:
Code: |
// 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_E PIN_E2
#define LCD_RS PIN_E0
#define LCD_RW PIN_E1
#define LCD_DB4 PIN_D4
#define LCD_DB5 PIN_D5
#define LCD_DB6 PIN_D6
#define LCD_DB7 PIN_D7
// 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 lcdline;
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>> 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);
lcdline = 1;
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;
switch(y) {
case 1 : address=0x80;break;
case 2 : address=0xc0;break;
case 3 : address=0x94;break;
case 4 : address=0xd4;break;
}
address+=x-1;
lcd_send_byte(0,address);
}
//-----------------------------
void lcd_putc(char c)
{
switch (c) {
case '\f' : lcd_send_byte(0,1);
lcdline=1;
delay_ms(2);
break;
case '\n' : lcd_gotoxy(1,++lcdline); 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
|
And the main routine:
Code: |
#include <16F877A.h>
//#device ICD=TRUE
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#include <flex_lcd.c>
void main()
{
lcd_init();
lcd_putc("\fHey you!");
while(TRUE)
{
printf("hey");
delay_ms(2000);
}
}
|
I will appreciate any suggestion.
Thanks in advance.
Eduardo |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Aug 14, 2006 12:36 pm |
|
|
Since this topic comes up so often, I will order a 4x20 LCD today,
so it will arrive later this week. I will modify and test the driver
and try to post it by the end of the week. |
|
|
Ed_Banses
Joined: 15 Sep 2005 Posts: 15
|
|
Posted: Tue Aug 15, 2006 1:51 am |
|
|
I am really looking forward to see your results.
Thanks a lot for your help.
Eduardo |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Aug 18, 2006 11:12 pm |
|
|
Please check your PM box. |
|
|
|
|
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
|