![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
Charles Linquist
Joined: 07 May 2005 Posts: 28 Location: Campbell, CA
|
Another LCD question |
Posted: Sat Jun 04, 2005 6:24 pm |
|
|
I have been trying to modify Mark's LCDD.c example for my application, but so far without much success.
I'm using a 18F8720
The data lines are H0->H3
R/W is connected to H4
RS is connected to H5
Enable is connected to J2
I am including the pin assignment part of Mark's code, and have commented out his original.
Can someone tell me what I'm doing wrong?
Code: |
struct lcd_pin_map
{
// ---------------------------- Mark's --------------------------
// BOOLEAN dummy; // PinA0 is not used
// BOOLEAN enable; // PinA1
// BOOLEAN rw; // PinA2
// BOOLEAN rs; // PinA3
// int unusedA : 4; // The rest of portA
// 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 unusedD : 4; // The rest of portD
//-------------------- End of Mark's ----------------------
// --------------------- Mine --------------------------------
int unusedA;
int unusedB;
int unusedC;
int unusedD;
int unusedE;
int unusedF;
int unusedG;
int data :4 ; //Pins H0-H3
BOOLEAN rw; //Pin H4
BOOLEAN rs; //Pin H5
int unusedH :2 ; // Rest of port H
BOOLEAN dummy; //J0
BOOLEAN dummy2; //J1
Boolean enable; //J2
int unusedJ :5; // Rest of port J
// ---------------------- End of Mine ----------------------------
// ---------------------- Mark's ----------------------------
} lcd;
#if defined(__PCH__)
// #locate lcd = 0xF80 // Mark's
#locate lcd = 0xF87 // PortH // Mine
#else
#locate lcd = 5
#endif
struct lcd_tris_map
{
// -------------------- Mark's --------------------------------
// BOOLEAN dummy; // PinA0 is not used
// int control : 3;
// int unusedA : 4; // The rest of portA
// 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 unusedD : 4; // The rest of portD
// --------------------- End of Mark's -------------------------------
// ----------------------- Mine -----------------------------------------
int unusedA;
int unusedB;
int unusedC;
int unusedD;
int unusedE;
int unusedF;
int unusedG;
int data :4 ; //Pins H0-H3
BOOLEAN rw; //Pin H4
BOOLEAN rs; //Pin H5
int unusedH :2 ; // Rest of port H
int unusedI;
BOOLEAN dummy; //J0
BOOLEAN dummy2; //J1
Boolean enable; //J2
int unusedJ :5; // Rest of port J
// --------------- End of Mine ---------------------------
} lcdtris;
#if defined(__PCH__)
//#locate lcdtris = 0xF92 // Mark's
#locate lcdtris = 0XF99 // Mine
#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
|
|
|
![](templates/subSilver/images/spacer.gif) |
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sat Jun 04, 2005 6:46 pm |
|
|
This is wrong
Code: | #if defined(__PCH__)
// #locate lcd = 0xF80 // Mark's
#locate lcd = 0xF87 // PortH // Mine
#else
#locate lcd = 5
#endif |
It should be
Code: |
#if defined(__PCH__)
#locate lcd = 0xF80 /
#else
#locate lcd = 5
#endif
|
Since the lcd struct starts at port A
Change this
Code: | #define set_tris_lcd(x) lcdtris.data = (x); lcdtris.control = 0;
|
to
Code: | #define set_tris_lcd(x) lcdtris.data = (x); lcdtris.rs=0;lcdtris.rw=0;lcdtris.enable=0;
|
|
|
![](templates/subSilver/images/spacer.gif) |
Charles Linquist
Joined: 07 May 2005 Posts: 28 Location: Campbell, CA
|
|
Posted: Sun Jun 05, 2005 10:55 am |
|
|
I changed the code as you suggested. By looking at the .LST file I found another error that I had introduced, and I corrected that.
Still, the code doesn't work. I increased some delays, thinking that the display was slower than your model.
It still doesn't even light up the display.
I know the hardware works, PicBasicPro has no trouble running it.
(and does it with 4 lines of code - setup included!)
What could be wrong?
The calling program block:
delay_ms(100); \\Give the LCD time to start up
lcd_init(); \\ Initialize
delay_ms(100); \\ Wait some more
printf (lcd_putc("\fReady...")); \\ Show me the money
The modified driver:
Code: |
struct lcd_pin_map
{
int unusedA;
int unusedB;
int unusedC;
int unusedD;
int unusedE;
int unusedF;
int unusedG;
int data :4 ; //Pins H0-H3
BOOLEAN rw; //Pin H4
BOOLEAN rs; //Pin H5
int unusedH :2 ; // Rest of port H
BOOLEAN dummy; //J0
BOOLEAN dummy2; //J1
Boolean enable; //J2
int unusedJ :5; // Rest of port J
} lcd;
#if defined(__PCH__)
#locate lcd = 0xF80
#else
#locate lcd = 5
#endif
struct lcd_tris_map
{
int unusedA;
int unusedB;
int unusedC;
int unusedD;
int unusedE;
int unusedF;
int unusedG;
int data :4 ; //Pins H0-H3
BOOLEAN rw; //Pin H4
BOOLEAN rs; //Pin H5
int unusedH :2 ; // Rest of port H
int unusedI;
BOOLEAN dummy; //J0
BOOLEAN dummy2; //J1
Boolean enable; //J2
int unusedJ :5; // Rest of port J
} lcdtris;
#if defined(__PCH__)
#locate lcdtris = 0xF92
#else
#locate lcdtris = 0x85
#endif
#define set_tris_lcd(x);lcdtris.data = (x); lcdtris.rs=0;lcdtris.rw=0;lcdtris.enable=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(5);
lcd.enable = 1;
delay_us(200);
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(5);
lcd.rw = 0;
delay_cycles(5);
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(4);
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);
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jun 05, 2005 3:45 pm |
|
|
Quote: | I'm using a 18F8720
The data lines are H0->H3
R/W is connected to H4
RS is connected to H5
Enable is connected to J2 |
The data sheet says this:
Quote: | Note 1: On Power-on Reset, Port H pins
RH7:RH4 default to A/D inputs and read as ‘0’.
2: On Power-on Reset, Port H pins
RH3:RH0 default to system bus signals. |
So I would strongly question whether these pins are being re-configured
as digital i/o, or are they being left in their default state ?
CCS has sort of a "standard" of inserting startup code at the
beginning of main() to make all A/D pins be digital. But quite often
they don't do it correctly or completely. You didn't show us your
own initialization source code.
The data sheet further says this:
Quote: |
Register ADCON1 configures RH7:RH4 as I/O or A/D
inputs. Register MEMCON configures RH3:RH0 as I/O
or system bus pins. |
So I think you should use #byte statements to define the addresses
of each of those registers, and then manually setup those registers
with code to configure your LCD pins as digital i/o. Refer to the data
sheet to get the addresses of those registers and also for the bit settings
necessary to configure those pins for digital i/o. |
|
![](templates/subSilver/images/spacer.gif) |
Charles Linquist
Joined: 07 May 2005 Posts: 28 Location: Campbell, CA
|
|
Posted: Sun Jun 05, 2005 8:32 pm |
|
|
That was it! Thanks! |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|