|
|
View previous topic :: View next topic |
Author |
Message |
Edward Guest
|
Powertip 20x4 LCD ST7066U |
Posted: Thu Jun 17, 2004 3:20 am |
|
|
I am using Powertip 20x4 LCD ST7066U and observed a percular problem.
I programmed the microchip usign ICD2 USB.
Upon ready, I pluck out the cable and the LCD works.
However, when I power off the device and power it on again, the LCD doesn't work.
The attached is my LCD code.
struct lcd_pin_map { // This structure is overlayed
BOOLEAN enable; // on to an I/O port to gain
BOOLEAN rs; // access to the LCD pins.
BOOLEAN rw; // The bits are allocated from
BOOLEAN unused; // low order up. ENABLE will
int data : 4; // be pin D0.
} lcd;
#byte lcd = 0xF83 // This puts the entire structure
// on to port D
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_1 0x00 // LCD RAM address for the 1st line
#define lcd_line_2 0x40 // LCD RAM address for the 2nd line
#define lcd_line_3 0x14 // LCD RAM address for the 3rd line
#define lcd_line_4 0x54 // LCD RAM address for the 4th line
BYTE const LCD_INIT_STRING[5] = {0x20 | (lcd_type << 2),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.
struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in
BYTE lcd_read_byte() {
BYTE low,high;
set_tris_d(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_d(LCD_WRITE);
return( (high<<4) | low);
}
void lcd_send_nibble( BYTE n ) {
lcd.data = n;
delay_cycles(1);
lcd.enable = 1;
delay_us(40);
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_send_byte_init( BYTE n ) {
lcd.rs = 0;
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_d(LCD_WRITE);
delay_ms(200);
lcd.rs = 0;
lcd.rw = 0;
lcd.enable = 0;
lcd_send_nibble(3);
for(i=0;i<=4;++i)
lcd_send_byte_init(LCD_INIT_STRING[i]);
}
void lcd_gotoxy( BYTE x, BYTE y) {
BYTE address;
switch (y)
{
case 1 : address=lcd_line_1; break;
case 2 : address=lcd_line_2; break;
case 3 : address=lcd_line_3; break;
case 4 : address=lcd_line_4; break;
default : address=lcd_line_1; break;
}
address += x;
lcd_send_byte(0,0x80|address);
}
void lcd_putc( char c) {
;
switch (c)
{
case '\q' : lcd_send_byte(0,1);delay_ms(2); break; // clearscreen
case '\1' : lcd_gotoxy(0,1); break; // goto beginning of line 1
case '\2' : lcd_gotoxy(0,2); break;
case '\3' : lcd_gotoxy(0,3); break;
case '\4' : lcd_gotoxy(0,4); break;
case '\b' : lcd_send_byte(0,0x10); break; // backspace
default : lcd_send_byte(1,c); break; // send the character
}
}
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);
}
Hope someone can help. |
|
|
Ttelmah Guest
|
|
Posted: Thu Jun 17, 2004 4:07 am |
|
|
Try setting the port pins to a 'known' state (idle, with the CCD deselected), at the start of your main function.
What you describe, is fairly common, where the newly powered chip, has the lines floating, and these go to state where perhaps the chip is selected, then when the first chip select is sent, this is not 'seen', and the first part of the initialisation is then not seen by the LCD controller. When you first program the chip, the behaviour is often not quite the same as the 'power on' state, leading to this type of difference.
Best Wishes |
|
|
Guest
|
|
Posted: Thu Jun 17, 2004 4:18 am |
|
|
Forgive me, but how to set the port pins, in this case port D to a known state. Thanks for the reply. |
|
|
Edward Guest
|
|
Posted: Thu Jun 17, 2004 10:41 am |
|
|
I am still figuring out
Try setting the port pins to a 'known' state (idle, with the CCD deselected), at the start of your main function
Anyone kindly help? |
|
|
Ttelmah Guest
|
|
Posted: Thu Jun 17, 2004 10:56 am |
|
|
Anonymous wrote: | Forgive me, but how to set the port pins, in this case port D to a known state. Thanks for the reply. |
If (for instance), your 'select' pin on the LCD, is (say) PORTD 0, and the 'select' is a low state, then at the start of the main, have 'output_high(PIN_D0)' statement. This ensures the line is high beore you go to your initialisation code. You can set the whole port using 'output_d(255)', which will set all the lines high.
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jun 17, 2004 11:04 am |
|
|
Quote: | I programmed the microchip usign ICD2 USB.
Upon ready, I pluck out the cable and the LCD works.
However, when I power off the device and power it on
again, the LCD doesn't work. |
Are you using ICD2 in Debugger mode or in Programmer mode ?
If you program your board when in Debugger mode, and
then click the Run command, the PIC will run. If you pull
off the ICD2 cable, the PIC will continue to run. If you
then power-cycle your board, it will not run. That's the
expected operation when using the ICD2 in Debugger mode.
Is this what you are doing ?
If so, the solution is to use the ICD2 in Programmer mode. |
|
|
Edward Guest
|
|
Posted: Thu Jun 17, 2004 11:11 am |
|
|
Thanks for the reply Ttelmah, I will try 'output_d(255)'
I am using is Programmer mode. Thanks 'PCM programmer'
Wish me good luck |
|
|
Edward Guest
|
|
Posted: Thu Jun 17, 2004 8:47 pm |
|
|
Tried it this morning and it still doesnt work.
However, when I try to do an init 2 times, like below
main(){
lcd_init(); //Initialise LCD
delay_ms(10);
lcd_init(); //Initialise LCD
delay_ms(10);
}
Everything is okay. It puzzles me and hope anyone can answer why.
Anyway, I am now glad. Thanks and I really like the forum.
Best Regards,
Edward |
|
|
Ttelmah Guest
|
|
Posted: Fri Jun 18, 2004 2:03 am |
|
|
Edward wrote: |
Tried it this morning and it still doesnt work.
However, when I try to do an init 2 times, like below
main(){
lcd_init(); //Initialise LCD
delay_ms(10);
lcd_init(); //Initialise LCD
delay_ms(10);
}
Everything is okay. It puzzles me and hope anyone can answer why.
Anyway, I am now glad. Thanks and I really like the forum.
Best Regards,
Edward |
This possibly comes back to getting the pins into the 'known' state.
Work out what voltages will be on all the control pins at the end of the init routine. Set the pins to these states before starting. I still suspect that what is happening, is that the first 'select' of the LCD is being missed, hence the init does not correctly initialise the display, but when called the second time, the pins are now in a good starting position, and it works.
The other possibility is time. Some displays take quite a long time to go 'ready' after power is applied. It may simply be that the first initialise is too quick.
Best Wishes |
|
|
|
|
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
|