This may be sort of OT (not sure). It involves porting code from an
8051 to
a PIC.
I've been having problems reading the busy flag on an LCD. The LCD
is using
a 4-bit interface. I have finally figured it out (I think). It appears that
the order you send
the various control signals matters (as the datasheet indicates, but several
examples
I found on the web don't follow that order).
It is also important that the data lines *NOT* change. I've tried
setting the
pins to HiZ before, after, and at the same time as setting 'E' high. The LCD
gets
messed up every time. The only way it works is to leave the I/O pins
"as-is".
The code is for an ADuC812, which has an 8051 core. I would like to
port this code to a PIC. Now, on the 8051, I can simply let the
external signal
drive the I/O pins, even though they may be outputs. But on the PIC, which
has
output drivers, this won't work. I've though of using the weak pull-ups (on
an 'F84),
but aren't these disabled when the port is configured as an output? Do I
have
to add hardware to support this?
Does anyone have any ideas of how to accomplish this on a PIC? Has
anyone successfully read the BUSY flag while using a 4-bit interface? I'd
greatly
appreciate some code snippets if you're willing to share.
In a message dated 4/20/00 12:56:08 PM Pacific Daylight Time, peisermaKILLspamRIDGID.COM writes:
The busy flag of an LCD (assuming you're using the HD44780 chipset)
is bit 7 of the 8-bit interface. One thing I gotta know, why are you setting
your pins to inputs? All you have to do is put the command/data (low/high
nibbles) on the data lines and strobe E (negative clock).
Regards,
Tim Hamel
<snip>
> Does anyone have any ideas of how to accomplish this on a PIC? Has
> anyone successfully read the BUSY flag while using a 4-bit interface? I'd
> greatly
> appreciate some code snippets if you're willing to share.
>
> Phil Eisermann
> H:(440) 284-3787 (.....mazerKILLspam.....ix.netcom.com)
> O:(440) 329-4680 (EraseMEpeisermaspam_OUTTakeThisOuTridgid.com)
I tried for two days to get the BUSY flag read to work on mine. The only
time it did was when I modified the "watch for BUSY flag" routine to take
long enough that the flag was moot. 8-) No luck other than that, so I'm
just using a delay. So if you figure it out, please let everyone (well,
me at least) know. Thanks!
Dale
On Thu,
20 Apr 2000, Eisermann, Phil [Ridg/CO] wrote:
> I've been having problems reading the busy flag on an LCD. The LCD
> is using
> a 4-bit interface. I have finally figured it out (I think). It appears that
> the order you send
> the various control signals matters (as the datasheet indicates, but several
> examples
> I found on the web don't follow that order).
>
> It is also important that the data lines *NOT* change. I've tried
> setting the
> pins to HiZ before, after, and at the same time as setting 'E' high. The LCD
> gets
> messed up every time. The only way it works is to leave the I/O pins
> "as-is".
>
> The code is for an ADuC812, which has an 8051 core. I would like to
> port this code to a PIC. Now, on the 8051, I can simply let the
> external signal
> drive the I/O pins, even though they may be outputs. But on the PIC, which
> has
> output drivers, this won't work. I've though of using the weak pull-ups (on
> an 'F84),
> but aren't these disabled when the port is configured as an output? Do I
> have
> to add hardware to support this?
>
> Does anyone have any ideas of how to accomplish this on a PIC? Has
> anyone successfully read the BUSY flag while using a 4-bit interface? I'd
> greatly
> appreciate some code snippets if you're willing to share.
>
> Phil Eisermann
> H:(440) 284-3787 (mazerspam_OUTix.netcom.com)
> O:(440) 329-4680 (@spam@peisermaKILLspamridgid.com)
>
---
The most exciting phrase to hear in science, the one that heralds new
discoveries, is not "Eureka!" (I found it!) but "That's funny ..."
-- Isaac Asimov
> In a message dated 4/20/00 12:56:08 PM Pacific Daylight Time,
> KILLspampeisermaKILLspamRIDGID.COM writes:
> The busy flag of an LCD (assuming you're using the HD44780 chipset)
> is bit 7 of the 8-bit interface. One thing I gotta know, why are you setting
> your pins to inputs? All you have to do is put the command/data (low/high
> nibbles) on the data lines and strobe E (negative clock).
Because:
> The busy flag of an LCD (assuming you're using the HD44780 chipset)
> is bit 7 of the 8-bit interface.
Actually, it's bit 7 of the 8-bit word read that includes the BUSY flag
and the DDRAM address or some such -- whether you use the 8-bit or 4-bit
interface. And we're trying to read the BUSY flag, so the PIC pins gotta
be inputs. No?
I've tried reading the pins once and twice, since the data sheets I have
are maddeningly sparse in precise detail and riddled with bits that don't
make sense, explain things halfway, or conflict with other sections. In
8-bit mode things work fine, but not in 4-bit mode.
Dale
---
The most exciting phrase to hear in science, the one that heralds new
discoveries, is not "Eureka!" (I found it!) but "That's funny ..."
-- Isaac Asimov
> The busy flag of an LCD (assuming you're using the HD44780 chipset)
> is bit 7 of the 8-bit interface. One thing I gotta know, why are you
> setting
> your pins to inputs? All you have to do is put the command/data (low/high
> nibbles) on the data lines and strobe E (negative clock).
>
>
yes, the display uses the HD44780. The reason I want to set
the pins as inputs is because the PIC has output drivers:
Suppose the last command was to write the number '1' to
the display. That means my data lines are driven to 31h,
or 00110001b. Notice that bit 7 is 0 (regardless if i'm using
8-bit or 4-bit interface). Now I want to read the busy flag.
The HD44780 tries to pull bit 7 high (because it's still
busy writing the '1' to the screen). However, the PIC is
trying to drive the pin low. Hence, I want to set the pins
as input. Does that make sense?
Ok...I think I understand what you're saying...you can't read the busy flag
(bit 7) unless you're using the 8-bit interface? I've found something that
might contradict that:
> Actually, it's bit 7 of the 8-bit word read that includes the BUSY flag
> and the DDRAM address or some such -- whether you use the 8-bit or 4-bit
> interface. And we're trying to read the BUSY flag, so the PIC pins gotta
> be inputs. No?
>
> I've tried reading the pins once and twice, since the data sheets I have
> are maddeningly sparse in precise detail and riddled with bits that don't
> make sense, explain things halfway, or conflict with other sections. In
> 8-bit mode things work fine, but not in 4-bit mode.
>
> Dale
Try reading the offical thick Optrex manual!
Talk about Chinglish. You're lucky to figure
out that you have to wait 1.64ms after a clear!
I NEVER read the BUSY signal. I just wait the
amount of time shown in the timing diagrams.
Doing that, I don't ever see any flickering,
even if I rewrite the whole display. I use
4x40s BTW.
> yes, the display uses the HD44780. The reason I want to set
> the pins as inputs is because the PIC has output drivers:
> Suppose the last command was to write the number '1' to
> the display. That means my data lines are driven to 31h,
> or 00110001b. Notice that bit 7 is 0 (regardless if i'm using
> 8-bit or 4-bit interface). Now I want to read the busy flag.
> The HD44780 tries to pull bit 7 high (because it's still
> busy writing the '1' to the screen). However, the PIC is
> trying to drive the pin low. Hence, I want to set the pins
> as input. Does that make sense?
>
Yes, it makes sense, except for one thing. If you're using a 4-bit interface,
you'll have to send 0x31h in nibbles. So, what you can do is TRIS PortB so
it's 01000000b. Then all you have to do is read it in, AND with 0x80h and if
Z of the STATUS register is 1, then it's still busy. Understand? If not, I
could try to write code to duplicate this. If, in the end it doesn't work,
the longest operation for the display is I think 1.64mS, so...delay =)
> > The busy flag of an LCD (assuming you're using the HD44780 chipset)
> > is bit 7 of the 8-bit interface. One thing I gotta know, why are you
> > setting
> > your pins to inputs? All you have to do is put the command/data
> (low/high
> > nibbles) on the data lines and strobe E (negative clock).
> >
> >
> yes, the display uses the HD44780. The reason I want to set
> the pins as inputs is because the PIC has output drivers:
> Suppose the last command was to write the number '1' to
> the display. That means my data lines are driven to 31h,
> or 00110001b. Notice that bit 7 is 0 (regardless if i'm using
> 8-bit or 4-bit interface). Now I want to read the busy flag.
> The HD44780 tries to pull bit 7 high (because it's still
> busy writing the '1' to the screen). However, the PIC is
> trying to drive the pin low. Hence, I want to set the pins
> as input. Does that make sense?
>
And i forgot to mention: this situation will mess up the LCD
if you go from output to input, because the pin was 0,
but changing it to an input makes it HiZ, which looks like
a logic '1' to the LCD. Scoping it confirms this. If the LCD
tries to pull the pin low, indicating it's no longer busy, you
see a 250nsec pulse that makes it to Vcc for a few nsec,
then decays to around 3 or 4 volts, then goes low.
> Try reading the offical thick Optrex manual!
> Talk about Chinglish. You're lucky to figure
> out that you have to wait 1.64ms after a clear!
> I NEVER read the BUSY signal. I just wait the
> amount of time shown in the timing diagrams.
> Doing that, I don't ever see any flickering,
> even if I rewrite the whole display. I use
> 4x40s BTW.
>
*grin* yeah, i've read it. It's pretty bad. I could
use a delay loop. But I don't want to. I want to
write as fast as possible, and I want to be able
to detect if the LCD is not responding.
> Yes, it makes sense, except for one thing. If you're using a 4-bit
> interface,
> you'll have to send 0x31h in nibbles. So, what you can do is TRIS PortB so
> it's 01000000b. Then all you have to do is read it in, AND with 0x80h and
> if
> Z of the STATUS register is 1, then it's still busy. Understand? If not,
> I
> could try to write code to duplicate this. If, in the end it doesn't work,
> the longest operation for the display is I think 1.64mS, so...delay =)
>
Aha. That's exactly what I tried to do. However, I think a problem will
occur when you TRIS portB. Correct me if i'm wrong, but:
If I set portB as an output (say 0011 0001b), and the LCD is
driving (or trying to) the pins the other way (say 1011 0001b), we
have a problem, right?
If this is not correct, then I guess everything should work.
But assuming you have to change from input to output, depending
on if you are reading or writing, you are going to have a problem, as
per my previous messages.
> And i forgot to mention: this situation will mess up the LCD
> if you go from output to input, because the pin was 0,
> but changing it to an input makes it HiZ, which looks like
> a logic '1' to the LCD. Scoping it confirms this. If the LCD
> tries to pull the pin low, indicating it's no longer busy, you
> see a 250nsec pulse that makes it to Vcc for a few nsec,
> then decays to around 3 or 4 volts, then goes low.
> Phil,
>
> I tried for two days to get the BUSY flag read to work on mine. The only
> time it did was when I modified the "watch for BUSY flag" routine to take
> long enough that the flag was moot. 8-) No luck other than that, so I'm
> just using a delay. So if you figure it out, please let everyone (well,
> me at least) know. Thanks!
>
>
Well, I *can* get it to work. Even on a 4-bit interface. At least on an
8051.
I want to do the same for the PIC. If I do, I will post it or give it to
someone
to host on their website.
The problem is that when you do a read, you have to change your
pins to be inputs. (unless I'm missing something here?). And as
soon as you do, the LCD gets confused.
I too spent about 2 days (closer to 3 now) trying to figure it out.
I went so far as to scope DB7 and E pins (triggered off RW).
That's when I discovered there's a 'glitch' in the data lines when
you change from outputs to inputs, and the lines aren't in the same
state (this glitch is about 250ns). The LCD gets confused every time.
It doesn't matter if you change TRIS before the E/RW, or after. Or
even if you change it simultaneously (as you can effectively do with
the 8051, since it doesn't have output drivers).
I have some ideas for hacks, but I want to try some things first.
<x-flowed>At 05:26 PM 4/20/00 -0400, Eisermann, Phil [Ridg/CO] wrote:
>Well, I *can* get it to work. Even on a 4-bit interface. At least on an
>8051.
>I want to do the same for the PIC. If I do, I will post it or give it to
>someone
>to host on their website.
>
>The problem is that when you do a read, you have to change your
>pins to be inputs. (unless I'm missing something here?). And as
>soon as you do, the LCD gets confused.
I haven't yet tried this (I take the easy way out and simply wait the
specified delay time) but its something to try:
1) It should NOT matter what happens to the data lines so long as the E
line is LO. Make sure that E is LO before changing anything.
I *know* that the LCD ignores data while E is LO because I have 68hc11
boards that put the LCD on the data buss - and they all worked just fine!
2) Another poster mentioned something that I have NOT tried - hold E high
and change the pin tied to b7 to input and wait til that pin goes LO, then
drop E and reset the ddr and send your next character.
> 1) It should NOT matter what happens to the data lines so long as the E
> line is LO. Make sure that E is LO before changing anything.
>
> I *know* that the LCD ignores data while E is LO because I have 68hc11
> boards that put the LCD on the data buss - and they all worked just fine!
>
Hmm. yesterday I would have sworn that I tried this. Looking over my
notes, I see that this is not so. That would be the ticket
Also, someone (Tim?) posted a link to an LCD tester using a PIC
that implements a read. I'll have to look into that, to see what
order the signals are changed.
Thanks everyone for their input. I'll let you know what I find out.
> Dale,
>
> Ok...I think I understand what you're saying...you can't read the busy flag
> (bit 7) unless you're using the 8-bit interface? I've found something that
> might contradict that:
>
> http://home.iae.nl/users/pouweha/lcd0.htm#4bit-transfer
>
> Apparently, you CAN read bit-7 regardless of the i/f type.
In *theory*, yes. In *practice*, we're having trouble doing so. Every
time I try it, the LCD goes south for the winter. That's why we're
working on this. It's more than a little frustrating -- I now have a
routine that uses 1ms delays, which works perfectly. But now it's getting
personal, and I wanna squash a bug.
Dale
---
The most exciting phrase to hear in science, the one that heralds new
discoveries, is not "Eureka!" (I found it!) but "That's funny ..."
-- Isaac Asimov
YOU CAN READ IT YES!!! Actually in all our new products we are using 4
bits interface and it works nicely. The busy flag will be at the first
4 bits reading. Some displays allow you to not even need to read the
last 4 bits (as the second transfer). But for more correction operation
you should read all the 8 bits (two readings of 4 bits each). What
really happens in your case?
Wagner Lipnharski
UST Research Inc. - Orlando, Florida http://www.ustr.net <-- 8051 site
>
> On Thu, 20 Apr 2000, Tim Hamel wrote:
>
> > Dale,
> >
> > Ok...I think I understand what you're saying...you can't read the busy flag
> > (bit 7) unless you're using the 8-bit interface? I've found something that
> > might contradict that:
> >
> > home.iae.nl/users/pouweha/lcd0.htm#4bit-transfer
> >
> > Apparently, you CAN read bit-7 regardless of the i/f type.
>
> In *theory*, yes. In *practice*, we're having trouble doing so. Every
> time I try it, the LCD goes south for the winter. That's why we're
> working on this. It's more than a little frustrating -- I now have a
> routine that uses 1ms delays, which works perfectly. But now it's getting
> personal, and I wanna squash a bug.
>
> Dale
> ---
> The most exciting phrase to hear in science, the one that heralds new
> discoveries, is not "Eureka!" (I found it!) but "That's funny ..."
> -- Isaac Asimov
While I haven't actually tried a BUSY bit read (I use a delay too), it seems
rather simple. The way I see it is:
RS=Low
R/W=High
E=Low -> High
Read Bit-7
No offense, but is that how you're doing it? If it is, and the LCD still goes
schitzo, then I'll work on this as a weekend project (teenagers have more
free-time than working adults <g>). If I figure it out, I'll be more than
happy to post the code!
> In *theory*, yes. In *practice*, we're having trouble doing so. Every
> time I try it, the LCD goes south for the winter. That's why we're
> working on this. It's more than a little frustrating -- I now have a
> routine that uses 1ms delays, which works perfectly. But now it's getting
> personal, and I wanna squash a bug.
>
> Dale
>
I apologize...E does NOT go from L->H, it's negative-edge (High->Low).
Sorry,
Tim Hamel
In a message dated 4/21/00 9:52:58 AM Pacific Daylight Time, TekPhobia writes:
> Dale,
>
> While I haven't actually tried a BUSY bit read (I use a delay too), it
seems {Quote hidden}
> rather simple. The way I see it is:
>
> RS=Low
> R/W=High
> E=Low -> High
> Read Bit-7
>
> No offense, but is that how you're doing it? If it is, and the LCD still
> goes schitzo, then I'll work on this as a weekend project (teenagers have
> more free-time than working adults <g>). If I figure it out, I'll be more
> than happy to post the code!
>
> Regards,
>
> Tim Hamel
> Dale,
>
> While I haven't actually tried a BUSY bit read (I use a delay too), it
> seems
> rather simple. The way I see it is:
>
> RS=Low
> R/W=High
> E=Low -> High
> Read Bit-7
>
> No offense, but is that how you're doing it? If it is, and the LCD still
> goes
> schitzo, then I'll work on this as a weekend project (teenagers have more
> free-time than working adults <g>). If I figure it out, I'll be more than
> happy to post the code!
>
>
well, i'm not Dale, but:
yes, that's how I'm doing it. except E toggles low->high->low.
and with a 4-bit interface, you're supposed to do it twice.
That's the way it is supposed to work in theory. In
practice, you need to change the data lines from
input to output in order to read the data. And as
soon as you do, the LCD (at least mine, and
apparantly Dale's as well) goes south.
As stated previously, it works fine on an 8051,
where you don't have to change the pins from
input to output. The LCD easily overpowers
the weak pull-ups. But now i'm trying to get
it to work on a PIC.
Perhaps my LCD is half-dead/ESD impaired?
If you figure it out and post the code, that
would be greatly appreciated.
> yes, that's how I'm doing it. except E toggles low->high->low.
> and with a 4-bit interface, you're supposed to do it twice.
Ditto. I tried doing it once, and doing it twice - either way it didin't
work. Since I don't have an ICE and didn't have the time to set up the
scope to see exactly what was going on, I don't know exactly what was
happening, only that the wait_busy routine wasn't working.
> That's the way it is supposed to work in theory. In
> practice, you need to change the data lines from
> input to output in order to read the data. And as
> soon as you do, the LCD (at least mine, and
> apparantly Dale's as well) goes south.
I was setting TRIS to 00001111 (LCD data pins input) before toggling any
of the RS, RW or E lines. In theory, this shouldn't affect the LCD - in
fact, I share pins <> E between the LCD and a DS1620 temp. sensor, so I
know the LCD can tolerate data pins being TRISed and used for other things
when it's not enabled.
> Perhaps my LCD is half-dead/ESD impaired?
I doubt it. I'm starting to wonder about the hardware now, though...
unfortunately it will be at least a day before I can go retrieve the board
and scope to play with it, I left it at work.
Dale
---
The most exciting phrase to hear in science, the one that heralds new
discoveries, is not "Eureka!" (I found it!) but "That's funny ..."
-- Isaac Asimov
Dwayne Reid wrote:
> 1) It should NOT matter what happens to the data lines so long as the E
> line is LO. Make sure that E is LO before changing anything.
>
> I *know* that the LCD ignores data while E is LO because I have 68hc11
> boards that put the LCD on the data buss - and they all worked just fine!
>
>
well, I tried that this morning. All i did was change the data lines while
E was low (confirmed on scope). The order of operation was:
1) change data lines to input
2) bring RW high
3) bring E high
4) read data DB7-DB4
5) bring E low
6) repeat 3-5 for reading DB3-DB0
Note that E, RS, RW are all low at the start of the operation.
The LCD remained blank, but data was sent continually back and forth.
The version that I was able to get to work omitted step 1.
I have another of the same display. I think I will wire that one up
and see if it behaves similarly.
I doubt if you can read anything at all back from the LCD, as data from
any DDRAM memory location.
As soon you satisfy the interface; RS LOW (pin 4), R/W HIGH (pin 5) and
the E HIGH (pin 6), the 4 bits (BF,DB6,5,4) interface should present,
flipping down and up again the E pin it will present the DB3-2-1-0. The
data should be read while E pin is high.
While R/W pin is UP, there is no way you can mess with the LCD if the
interface has some loads of few pullups caused by a bad programming
(in/out) of the PIC pins...
Just remember that E pin should be the last one to be turned on and
first to be off, if not, then you will mess something.
Make sure the interface is not in the middle of a two bytes read or
write if you did not complete the previous operation. Everything should
be done in two transfers steps of 4 bits, to fulfill the LCD 4 bits
operation mode. If you start a transfer in 4 bits mode, it will need to
have two E pin pulsed high, if not, the LCD will be lost waiting
something, and the next operation you do could mess everything.
>
> > Dale,
> >
> > While I haven't actually tried a BUSY bit read (I use a delay too), it
> > seems
> > rather simple. The way I see it is:
> >
> > RS=Low
> > R/W=High
> > E=Low -> High
> > Read Bit-7
> >
> > No offense, but is that how you're doing it? If it is, and the LCD still
> > goes
> > schitzo, then I'll work on this as a weekend project (teenagers have more
> > free-time than working adults <g>). If I figure it out, I'll be more than
> > happy to post the code!
> >
> >
> well, i'm not Dale, but:
>
> yes, that's how I'm doing it. except E toggles low->high->low.
> and with a 4-bit interface, you're supposed to do it twice.
>
> That's the way it is supposed to work in theory. In
> practice, you need to change the data lines from
> input to output in order to read the data. And as
> soon as you do, the LCD (at least mine, and
> apparantly Dale's as well) goes south.
>
> As stated previously, it works fine on an 8051,
> where you don't have to change the pins from
> input to output. The LCD easily overpowers
> the weak pull-ups. But now i'm trying to get
> it to work on a PIC.
>
> Perhaps my LCD is half-dead/ESD impaired?
>
> If you figure it out and post the code, that
> would be greatly appreciated.
Is this happening after the LCD is initialized? Because, up to some
point of the initialization sequence the Busy bit is not operational...
During the initialization you should do the first steps without looking
at the busy bit (will not work anyway), just use timming routines...
Are you sure your LCD pin 3 (Vo) is at some contrast satisfying voltage
level?
Are you waiting more than 15ms after power on to start sending data to
the LCD?
Wagner Lipnharski
UST Research Inc. - Orlando, Florida http://www.ustr.net <-- 8051 website
>
> Dwayne Reid wrote:
> > 1) It should NOT matter what happens to the data lines so long as the E
> > line is LO. Make sure that E is LO before changing anything.
> >
> > I *know* that the LCD ignores data while E is LO because I have 68hc11
> > boards that put the LCD on the data buss - and they all worked just fine!
> >
> >
> well, I tried that this morning. All i did was change the data lines while
> E was low (confirmed on scope). The order of operation was:
> 1) change data lines to input
> 2) bring RW high
> 3) bring E high
> 4) read data DB7-DB4
> 5) bring E low
> 6) repeat 3-5 for reading DB3-DB0
> Note that E, RS, RW are all low at the start of the operation.
>
> The LCD remained blank, but data was sent continually back and forth.
>
> The version that I was able to get to work omitted step 1.
>
> I have another of the same display. I think I will wire that one up
> and see if it behaves similarly.
Just to make sure you guys got it right.
LCD E pin (6) activate the LCD interface while it is in HIGH level, not
a transition L-->H or H-->L, it is just purely HIGH level.
Most LCDs require a minimum E HIGH width of 450ns, maximum raise time of
25ns. During the READ operation, data will be available at the Interface
no longer than 320ns after E settles HIGH.
450ns 450ns
min min
_________ __________
E _________/ \_______/ \_________
_____ ______
Data____________/ \___________/ \_________
--->| |<--- Delay max 320ns
If you try to read data earlier than 320ns after raise the E pin, it is
possible that you get wrong data. If you are not sure, include some
dummy instructions after raising E and Read the port.
>
> I apologize...E does NOT go from L->H, it's negative-edge (High->Low).
>
> Sorry,
>
> Tim Hamel
>
> In a message dated 4/21/00 9:52:58 AM Pacific Daylight Time, TekPhobia writes:
>
> > Dale,
> >
> > While I haven't actually tried a BUSY bit read (I use a delay too), it
> seems
> > rather simple. The way I see it is:
> >
> > RS=Low
> > R/W=High
> > E=Low -> High
> > Read Bit-7
> >
> > No offense, but is that how you're doing it? If it is, and the LCD still
> > goes schitzo, then I'll work on this as a weekend project (teenagers have
> > more free-time than working adults <g>). If I figure it out, I'll be more
> > than happy to post the code!
> >
> > Regards,
> >
> > Tim Hamel
> Is this happening after the LCD is initialized? Because, up to some
> point of the initialization sequence the Busy bit is not operational...
> During the initialization you should do the first steps without looking
> at the busy bit (will not work anyway), just use timming routines...
Yes, the LCD inits fine, and I'm not trying to use BF until long after.
I did... were I using an 8051 and an 8-bit interface to the LCD, it would
doubtless have been quite helpful, but I'm using a 16F84 and a 4-bit
interface. The instruction set and the hardware are just a bit different.
I agree completely that the sequence *should* work, and in your case no
doubt does. The problem is that a similar sequence in my case does *not*
work at all.
> Are you sure your LCD pin 3 (Vo) is at some contrast satisfying voltage
> level?
Yes.
> Are you waiting more than 15ms after power on to start sending data to
> the LCD?
Yes. Like I said, if I do nothing more than replace the BF wait with a
short delay, it works perfectly.
Dale
---
The most exciting phrase to hear in science, the one that heralds new
discoveries, is not "Eureka!" (I found it!) but "That's funny ..."
-- Isaac Asimov
Are you able to read anything from LCD DDRAM memory? Try to send "ABCD"
to the LCD DDRAM address 00h (80h) and read it back, just to make sure
the "read" instruction is working, keep using the "timming" solution for
the "busyflag" during the test...
Of course "timmed" solutions work pretty nice instead of reading the
busy flag, but you never know, and for fast display updates nothing
better than reading the busy flag.
Good Luck and keep us posted about the possible solution.
This thread already came to PICLIST last year, without a conclusion.
Below some part of it:
This text came up from PICLIST last year, from a similar problem.
Aparently this code works for 4 bits interface. Maybe it can helps.
Wagner.
; Before writing tot the LCD check if busy
; This routine returns only when LCD BUSY flag is clear
; and has the current DD-RAM address in TEMP.
; (for 4 MC XTAL; E should be active for min 480 nsec is less than 1
cycle)
;
CheckLCDBusy
bcf PORTA, LCD_RS_BIT ; command mode so RS bit 0
bsf PORTA, LCD_RW_BIT ; we are going to Read so RW bit
1
movlw b'11111111' ; set PORTB for input
tris PORTB ; the quick an dirty way
Read_Busy
bsf PORTA, LCD_E_BIT ; switch the Enable bit on
movf PORTB, W ; read the port with leaving a
working copy in W
movwf TEMP ; save LCD data addresd in TEMP
bcf PORTA, LCD_E_BIT ; switch E-bit off
andlw b'10000000' ; is bit 7 (busyflag set?)
skpz ; if busy flag is cleared then
skip
goto Read_Busy ; keep reading till cleared
bcf PORTA, LCD_RS_BIT ; exit command mode = clear RS
movlw b'00000000' ; and make PORTB
tris PORTB ; an output port again
bcf PORTA, LCD_RW_BIT ; reading done, back to write
return ; with DD-RAM address in TEMP
(note: BUSY Fl. cleared)
OK, I got it to work. Actually, I went back and re-examined my source
code, and Lo and behold! I was using the waitlcd() and not delayms() as
of the last time I tried it, so I guess I did get it sooner than I
remembered. Maybe all of the times I tried to make it work and failed got
to me?
Anyway, here's the code as I'm currently using it. The LCD uses PORTB0:3
for the data lines, PORTA.0 for RW, PORTA.1 for RW, and PORTA.2 for EN.
void waitlcd(void) {
char temp;
TRISB = 0b.0000.1111; // Input from LCD
RS = 0; // RS low to get BF
RW = 1; // Read operation
do {
EN = 1; // EN up to read data
temp = (PORTB & 0x08); // Mask off all but BF
EN = 0; // Drop EN
EN = 1; // Finish up last 4 bits
EN = 0; // and finish the read
} while(temp != 0x08); // (we ignore the low bits)
TRISB = 0; // All pins output again
RS = 1; // and set up to send to LCD
RW = 0;
}
And in assembler, as generated by CC5Xfree. I could save a few
instructions here, quite frankly... the compiler sometimes isn't bright
enough to remember what bank one's in.
;void waitlcd(void) {
waitlcd
; char temp;
; TRISB = 0b.0000.1111; // Input from LCD
MOVLW .15
BSF 0x03,RP0
MOVWF TRISB
; RS = 0; //RS low to get BF
BCF 0x03,RP0
BCF 0x05,RS
; RW = 1; //Read operation
BSF 0x05,RW
; do {
; EN = 1; //EN up to read data
m017 BCF 0x03,RP0
BSF 0x05,EN
; temp = (PORTB & 0x08); // Mask
;off all but BF
MOVLW .8
ANDWF PORTB,W
MOVWF temp
; EN = 0; //Drop EN
BCF 0x05,EN
; EN = 1; //Finish up last 4 bits
BSF 0x05,EN
; EN = 0; //and finish the read
BCF 0x05,EN
; } while(temp != 0x08); // (we ignore the
;low bits)
MOVF temp,W
XORLW .8
BTFSS 0x03,Zero_
GOTO m017
; TRISB = 0; //All pins output again
BSF 0x03,RP0
CLRF TRISB
; RS = 1; //and set up to send to LCD
BCF 0x03,RP0
BSF 0x05,RS
; RW = 0;
BCF 0x05,RW
;}
RETURN
;
Of course, as a programmer, I pretty much suck. If anyone's got ways to
make this tighter, smaller, faster, or generally better, I appreciate
constructive input.
Dale
---
The most exciting phrase to hear in science, the one that heralds new
discoveries, is not "Eureka!" (I found it!) but "That's funny ..."
-- Isaac Asimov
Dale Botkin wrote:
>
> OK, I got it to work. Actually, I went back and re-examined my source
> code, and Lo and behold! I was using the waitlcd() and not delayms() as
> of the last time I tried it, so I guess I did get it sooner than I
> remembered. Maybe all of the times I tried to make it work and failed got
> to me?
[snip]
Hey Dale, good work, I knew you would do it. As usual, if you are a
fighter, it is not a matter of to be able to do it or not, but just a
matter of time, huh?
Wagner.
> Dale Botkin wrote:
> >
> > OK, I got it to work. Actually, I went back and re-examined my source
> > code, and Lo and behold! I was using the waitlcd() and not delayms() as
> > of the last time I tried it, so I guess I did get it sooner than I
> > remembered. Maybe all of the times I tried to make it work and failed got
> > to me?
> [snip]
> Hey Dale, good work, I knew you would do it. As usual, if you are a
> fighter, it is not a matter of to be able to do it or not, but just a
> matter of time, huh?
> Wagner.
Thanks for the kind words. Yeah, after a while, I don't care if I *need*
to do it or not -- I refuse to let a $6.00 bit of epoxy and silicon get
the better of me.
Dale
---
The most exciting phrase to hear in science, the one that heralds new
discoveries, is not "Eureka!" (I found it!) but "That's funny ..."
-- Isaac Asimov
congratualtions. My code does the same thing as yours, in the same
sequence, and it *doesn't* work. May I ask how your E, RW, and RS
bits are set on entry? looking at your code, I will guess E & RW low,
and RS high.
Maybe I need to look closer at my code and make sure it's doing
what I think it is doing :)
> Anyway, here's the code as I'm currently using it. The LCD uses PORTB0:3
> for the data lines, PORTA.0 for RW, PORTA.1 for RW, and PORTA.2 for EN.
>
> void waitlcd(void) {
> char temp;
> TRISB = 0b.0000.1111; // Input from LCD
> RS = 0; // RS low to get BF
> RW = 1; // Read operation
> do {
> EN = 1; // EN up to read data
> temp = (PORTB & 0x08); // Mask off all but BF
> EN = 0; // Drop EN
> EN = 1; // Finish up last 4 bits
> EN = 0; // and finish the read
> } while(temp != 0x08); // (we ignore the low bits)
> TRISB = 0; // All pins output again
> RS = 1; // and set up to send to LCD
> RW = 0;
> }
>
RW low, RS high, and E low. Sorry, should've said that in the first
place. I sent the full code to the project archives, but it hasn't shown
up yet. I also have the PORTB pullups enabled, dunno if that would make a
difference in this case or not.
Dale
On Tue, 25 Apr 2000, Eisermann, Phil [Ridg/CO] wrote:
> congratualtions. My code does the same thing as yours, in the same
> sequence, and it *doesn't* work. May I ask how your E, RW, and RS
> bits are set on entry? looking at your code, I will guess E & RW low,
> and RS high.
>
> Maybe I need to look closer at my code and make sure it's doing
> what I think it is doing :)
---
The most exciting phrase to hear in science, the one that heralds new
discoveries, is not "Eureka!" (I found it!) but "That's funny ..."
-- Isaac Asimov