CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

lcd problems

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
newguy
Guest







lcd problems
PostPosted: Tue Nov 25, 2003 12:51 am     Reply with quote

Hi all,

Long time reader, first time poster.

I've done quite a bit of programming with CCS and pics (18f452, 252, 242, 16f877). However, I've run into a problem and I can't figure it out.

My present project uses an 18f242 and a standard 2x16 lcd character display. This is the first time that I've wired an lcd to port A, and I'm really beginning to question why I did that in the first place. Hindsight is always 20/20, I guess.

The code that I use to communicate with the lcd is basically the same code (lcd.c) that came with the ccs compiler. I've wired the lcd's D4-D7 lines to A0-A3, enable to A4, and rs to A5. Since A4 is an open drain output, I also have a pullup on that line. The lcd's R/W line is grounded, and I'm communicating with it in 4 bit mode. The relevant declarations follow:

struct lcd_pin_map {
int data : 4;
boolean enable;
boolean rs;
} lcd;

#byte lcd = 0xf80

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;
delay_us(350);
lcd.rs = address;
delay_cycles(1);
delay_cycles(1);
lcd.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}

What gets me is this same code works when I connect an lcd to port C on a 18f252. The only change I make is the #byte lcd = 0xf82 to point to port C's memory location.

Everything else seems to work, since I can get the pic to toggle lines which control relays, and they click away just fine if I make them toggle. The lcd seems sort of like it hasn't been initialized properly, which means that the code above isn't doing what it's supposed to be doing.

And yes, analogs have been turned off. Can someone please tell me what I'm overlooking? Was hooking an lcd to port A a really stupid idea?

Confused

-- Mark
Ttelmah
Guest







Re: lcd problems
PostPosted: Tue Nov 25, 2003 3:55 am     Reply with quote

newguy wrote:
Hi all,

Long time reader, first time poster.

I've done quite a bit of programming with CCS and pics (18f452, 252, 242, 16f877). However, I've run into a problem and I can't figure it out.

My present project uses an 18f242 and a standard 2x16 lcd character display. This is the first time that I've wired an lcd to port A, and I'm really beginning to question why I did that in the first place. Hindsight is always 20/20, I guess.

The code that I use to communicate with the lcd is basically the same code (lcd.c) that came with the ccs compiler. I've wired the lcd's D4-D7 lines to A0-A3, enable to A4, and rs to A5. Since A4 is an open drain output, I also have a pullup on that line. The lcd's R/W line is grounded, and I'm communicating with it in 4 bit mode. The relevant declarations follow:

struct lcd_pin_map {
int data : 4;
boolean enable;
boolean rs;
} lcd;

#byte lcd = 0xf80

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;
delay_us(350);
lcd.rs = address;
delay_cycles(1);
delay_cycles(1);
lcd.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}

What gets me is this same code works when I connect an lcd to port C on a 18f252. The only change I make is the #byte lcd = 0xf82 to point to port C's memory location.

Everything else seems to work, since I can get the pic to toggle lines which control relays, and they click away just fine if I make them toggle. The lcd seems sort of like it hasn't been initialized properly, which means that the code above isn't doing what it's supposed to be doing.

And yes, analogs have been turned off. Can someone please tell me what I'm overlooking? Was hooking an lcd to port A a really stupid idea?

Confused

-- Mark

Have you tried 'toggling relays' on portA?. If not, then the problem is almost certainly the initialisation of the port. On the 18F family, portA, also handles the analog inputs. By default it is configures in this way. Hence you have to add the line:
setup_adc_ports(NO_ANALOGS);

If you want to use the port for normal I/O.
There is nothing 'wrong' with using portA for the LCD. :-)

Best Wishes
newguy
Guest







Re: lcd problems
PostPosted: Tue Nov 25, 2003 10:38 am     Reply with quote

[guote="TTelma"]Have you tried 'toggling relays' on portA?. If not, then the problem is almost certainly the initialisation of the port. On the 18F family, portA, also handles the analog inputs. By default it is configures in this way. Hence you have to add the line:
setup_adc_ports(NO_ANALOGS);

If you want to use the port for normal I/O.
There is nothing 'wrong' with using portA for the LCD. :-)

Best Wishes
[/quote]

Yep, did that. The port initializes properly, and timer0 is setup so that it uses the internal source, not the external source on pin A4.

Here's the initialization code:
Code:

void main() {

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_spi(FALSE);
   setup_wdt(WDT_ON);
   setup_timer_0(RTCC_DIV_256|RTCC_8_bit);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_ccp1(CCP_OFF);
   setup_ccp2(CCP_OFF);
 
   set_tris_a(0x00);
   
   lcd_init();

   lcd_putc("\fTest");
}

I've taken a look at the .lst file, and it seems as though everything is getting initialized properly.

What size pullup would you recommend to use on pin A4? 10k? 20k? Smaller?

I'm really starting to pull my hair out over this. Is there something that I'm overlooking?

I should mention that I'm using PCH v3.178.

Thanks,

-- Mark
Guest
Guest







PostPosted: Tue Nov 25, 2003 10:58 am     Reply with quote

Your problem might be that your enable pin (RA4) has a pullup which pulls the signal H during program reset thus causing one pulse on E which the display might misinterpret ...

Just try to swap your E and RS pins as a pulse on the RS line should not cause any harm and check if the problem is still there.

hope this helps
Guest








PostPosted: Tue Nov 25, 2003 10:59 am     Reply with quote

Are you reseting the WDT? TTY
newguy
Guest







THAT DID IT!!!!
PostPosted: Tue Nov 25, 2003 12:16 pm     Reply with quote

Guest wrote:
Your problem might be that your enable pin (RA4) has a pullup which pulls the signal H during program reset thus causing one pulse on E which the display might misinterpret ...

Just try to swap your E and RS pins as a pulse on the RS line should not cause any harm and check if the problem is still there.

hope this helps


Guest, whoever you are, THANK YOU!!!!

I'm now finally able to display a test message on the lcd - your suggestion to swap the E and RS pins was excellent. I owe you a beer. Very Happy Exclamation

-- Mark
curt2go



Joined: 21 Nov 2003
Posts: 200

View user's profile Send private message

PostPosted: Tue Nov 25, 2003 12:35 pm     Reply with quote

Guest
Guest







Re: THAT DID IT!!!!
PostPosted: Wed Nov 26, 2003 1:54 am     Reply with quote

newguy wrote:
Guest wrote:
Your problem might be that your enable pin (RA4) has a pullup which pulls the signal H during program reset thus causing one pulse on E which the display might misinterpret ...

Just try to swap your E and RS pins as a pulse on the RS line should not cause any harm and check if the problem is still there.

hope this helps


Guest, whoever you are, THANK YOU!!!!

I'm now finally able to display a test message on the lcd - your suggestion to swap the E and RS pins was excellent. I owe you a beer. Very Happy Exclamation

I know thes problems for a long time :-)

You might consider changeing your LCD init code to something like this which works for me in all configurations:

1) POWER ON

2) Wait 15ms

3)
RS R/W DB7 DB6 DB5 DB4
0 0 0 0 1 1

4) Wait 4.1ms

5)
RS R/W DB7 DB6 DB5 DB4
0 0 0 0 1 1

6) Wait 100us

7)
RS R/W DB7 DB6 DB5 DB4
0 0 0 0 1 1

8) Wait 4.1ms

9)
RS R/W DB7 DB6 DB5 DB4
0 0 0 0 1 0

4-bit operation

10) Wait 40us

11)
RS R/W DB7 DB6 DB5 DB4
0 0 0 0 1 0

12)
RS R/W DB7 DB6 DB5 DB4
0 0 1 F x x

4-bit operation
1/16 duty cycle
F=font, 1 for 5x11 dot matrix
0 for 5x8 dot matrix
x=don't care

13) Wait 40us

14)
RS R/W DB7 DB6 DB5 DB4
0 0 0 0 0 0

15)
RS R/W DB7 DB6 DB5 DB4
0 0 1 0 0 0

Display off, cursor off, blink off

16) Wait 40us

17)
RS R/W DB7 DB6 DB5 DB4
0 0 0 0 0 0

18)
RS R/W DB7 DB6 DB5 DB4
0 0 0 0 0 1

Clear screen, cursor home

19) Wait 1.64ms

20)
RS R/W DB7 DB6 DB5 DB4
0 0 0 0 0 0

21)
RS R/W DB7 DB6 DB5 DB4
0 0 0 1 1 0

Increment cursor to the right
when writing, don't shift screen

21 and a half!!! (addendum)
>RS R/W DB7 DB6 DB5 DB4
>0 0 0 0 0 0
>0 0 0 1 1 0 Increment cursor to the right
> when writing, don't shift screen
>
>Wait 40us

RS R/W DB7 DB6 DB5 DB4
0 0 0 0 0 0
0 0 1 1 C B Turn on display, C=1: turn cursor on,
B=1: make character at cursor position blink
(end addendum)

22) Wait 40us

23) INITIALIZATION COMPLETE

This is from the LCD Faq posted here:

http://preterhuman.net/texts/computing/HardwareDIY/LCDFaq.txt

have fun

-- Mark
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Wed Nov 26, 2003 5:49 pm     Reply with quote

You might want to be careful about simply connecting your R/W line to ground. I've done several projects using 1 and 2 line displays with the R/W line tied to ground. It works fine but every once-in-a-while I would get garbage on the display and would need to cycle power to get it to go away. After digging into the actual requirements I found out that it is best if you check the 'busy' flag each time you want to send a command or data to the display. Here's the code that I came up with. It might not be the cleanest code but since I have started using it I have not had any problems with any of my LCD displays 'wigging' out.

I have the display lines connected up in the following order:

MCU---------LCD
PIN_A0-----DB4
PIN_A1-----DB5
PIN_A2-----DB6
PIN_A3-----DB7
PIN_A4-----ENABLE
PIN_A5-----RS
PIN_E0-----R/W

This code is for a 1X16 display. Modify it slightly to be used for a 2X16.

//////////////////////
#define ENB PIN_A4 // enable for the LCD display
#define RS PIN_A5 // RS pin of the LCD display
#define RW PIN_E0 // R/W bit for the LCD display

void pulse(unsigned int8 bits) // sends out the clock pulse to the LCD display
{
output_high(ENB);
output_a(bits);
delay_cycles(2);
output_low(ENB);
}

void bf_check(void) // checks the 'busy flag' for the LCD chipset
{
int1 BF = 0;

set_tris_a(0x0F);// set bits 0-3 as inputs
output_low(RS);
output_high(RW);
delay_cycles(3);

do
{
output_high(ENB);
delay_cycles(6);
if(input(PIN_A3))
{
BF = 1;
}
else
{
BF = 0;
}

output_low(ENB);
delay_cycles(3);
output_high(ENB);
delay_cycles(6);
output_low(ENB);

}while(BF);

set_tris_a(0x00);// set all bits to outputs
}

void ctlnib(int8 niblet) // sends a control command to the LCD display
{
int8 msn, lsn;

bf_check();

msn = niblet & 0xF0;
msn = msn >> 4;
msn = msn | 0x10;

output_low(RW);
output_low(RS);

pulse(msn);
lsn = niblet & 0x0F;
lsn = lsn | 0x10;
pulse(lsn);
}

void datnib(int8 niblet) // sends a data byte to the LCD display
{
int8 msn, lsn;

bf_check();

msn = niblet & 0xF0;
msn = msn >> 4;
msn = msn | 0x30;

output_low(RW);
output_high(RS);

pulse(msn);
lsn = niblet & 0x0F;
lsn = lsn | 0x30;
pulse(lsn);
}

void disline(char outstr[], int8 dline) // format is; string - line
{ // displays a line of text on the LCD display
int8 llg, dindex, track;

track = dline;
ctlnib(dline);
llg = strlen(outstr);
for(dindex = 0; dindex <= llg - 1; dindex++)
{
if(track == 0x88) //this is for 1X16 displays, modify this section for 2X16 displays
{
ctlnib(0xC0);
}
datnib(outstr[dindex]);
track++;
}
}

void initdisp(void) // initialize the LCD display
{
output_low(RW);
delay_ms(30);
pulse(0x03);
delay_ms(10);
pulse(0x03);
delay_us(300);
pulse(0x03);
pulse(0x02);
ctlnib(0x28);
ctlnib(0x80);
ctlnib(0x01);
ctlnib(0x06);
ctlnib(0x0C);
}

Hope this might help. :o)

Ronald
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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