PDA

View Full Version : LCD 4-bit mode affecting rest of port?



Mark Scotford
- 28th August 2004, 14:39
PicBasic Pro
PIC17C756A
Slow Learner

I am using the bottom half of a port to write data to an LCD in 4-bit mode and using the top half to output to another device. My trouble is that everytime I send data to the LCD, it changes the data on the top half of the port. Everthing is displayed correctly on the LCD, and everthing works when controlling the other device, but only after removing the LCDout commands. Your help would be very much appreciated.

TRISB = %00110000
TRISC = %00000100
TRISD = %11111111
TRISE = %1101
TRISF = %00000000
TRISG = %11101110

ADCON1 = %000000000111

ADCON1.7 = 1 'Right Justify the results

DEFINE LCD_DREG PORTF
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTC
DEFINE LCD_RSBIT 7
DEFINE LCD_EREG PORTC
DEFINE LCD_EBIT 6
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 50

DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50

(rest of code removed for clarity)

PORTF = %10110000
LCDOut $FE,1,#B8

(rest of code removed for clarity)

(I get the value of B8 displayed OK, but this intereferes with my attempt to write 1011 to the top half of the port)

Dwayne
- 1st September 2004, 20:15
Hello Mark,

Mark>>
PORTF = %10110000
LCDOut $FE,1,#B8

(rest of code removed for clarity)

(I get the value of B8 displayed OK, but this intereferes with my attempt to write 1011 to the top half of the port)<<


I think what is happening is your computer Chip is too fast.
When you write to PORTF, you are writing B0,
PORTF=%10110000 (Writing B0)


And a immediate write of a #B8 will destory your B0.

You need to make SURE that the B0 is read BEFORE you write your #B8. If you don't, you r B0 is worthless and gone.

Maybe you need a PAUSE statement inbetween your statements. When you put a pause there, you are giving your device enough time to read Port f the first time. Then you are outputting your data to your screen.

PORTF = %10110000
PAUSE 1000 'enough time to ENSURE device reads Portf
LCDOut $FE,1,#B8


Dwayne

Mark Scotford
- 2nd September 2004, 21:53
Just found another problem (I am sinking fast) Using the same defines/TRIS etc as before, if I use PORTB.3 = 1 (for example) this does not work. If I use HIGH PORTB.3 this does work. This only applies to PORTB, for example I can use PORTC.1 = 1 with no problem. Please help.

Mark Scotford
- 2nd September 2004, 22:44
Thanks Dwayne, I tried putting a long pause in between statements and this did in deed sort the problem, this has created another problem, because I did need to update the LCD with an ever changing value (within a loop), without upsetting the write I am trying to do to the other half of the port. I thought that in the LCD DEFINE (4-Bit Mode), this meant theoretically that you isolated one half of the port from the other, but from my experience, and from what you suggested, this appears not to be the case, am I correct?

Ingvar
- 3rd September 2004, 09:51
Hi Mark,

It sounds like you have found the ReadModifyWrite "feature" of the pics. Even when you manipulate one bit on a port, the pic internally reads the entire port, modifies the bit and then writes it back to the port. This means that if you have a capacitive load on a pin, the pin will need some time to reach the "correct" value. If you try to change another pin on the port too soon, the pic will read an erronous value on the previous pin. The easiest solution is to wait for the pin/port to settle.

However ....... If you have this problem, you have exceeded the pics specifications. If you change your design to get "inside" the specs, the problem will go away.

Cheers
/Ingvar

PS. This problem is usually caused by a capacitor connected directly to a pin or a LED connected without a series res. DS

Dwayne
- 3rd September 2004, 14:47
hello Ingvar,

I>>PS. This problem is usually caused by a capacitor connected directly to a pin or a LED connected without a series res. DS<<

For the gents problem, it doesn't matter whether a capacitor is there or not....

His code is this:

PORTF = %10110000
LCDOut $FE,1,#B8


It will immediately assign portf to B0, and a microsecond later output a value to the LCD on the exact same port. This means, the receiver of the B0 *MUST* be EXTREMELY FAST, and *MUST* be in the Recieve Data mode at almost the very same time your POrtF sends the B0. Or you will lose the data. Capacitor or not...don't matter.

I play with this with my home made Serial communication programs. It times the Transmit and Recieve parts of two chips. The reciever MUST be Slower than the transmitter at the initialization, but faster than the transmitter when receiving the data. The result is a extremely high baudrate transmittion.

Dwayne

Dwayne
- 3rd September 2004, 15:01
Hello Mark,

Mark>>Thanks Dwayne, I tried putting a long pause in between statements and this did in deed sort the problem<<

Ok. that is good. That means your receiver is recieving the data.

Mark >>, this has created another problem, because I did need to update the LCD with an ever changing value (within a loop), without upsetting the write I am trying to do to the other half of the port. I thought that in the LCD DEFINE (4-Bit Mode), this meant theoretically that you isolated one half of the port from the other, but from my experience, and from what you suggested, this appears not to be the case, am I correct?<<

I do not know this, I did not write the LCDout for PBP. I would assume you are correct. But since you are writing a 8 Bit to the port, your LCD has a chance to see the 1/2 of the bit write when you toggle.

This may sound rather crude, But have you thought about using a Serial Based LCD program? Instead of using a pin to Toggle a LCD read, us that pin to output the data to the Serial LCD. I think that would be slick as snot, and very easy to impliment. If you need the Code, I will send it to you. I built one with a 16F648A (But any chip with a PortB will probably work).

Granted, it is transmitting at 2400 to 9600 baud, but even at that speed, it shoots that data out to that LCD faster than you can see it go.


Dwayne

Dwayne
- 3rd September 2004, 15:10
Hello Mark,

One other thing,

That pause statement is 1 second long. I used this, to make sure that the receiver read the data.

You might be able to experiment with that pause statement and find that "PERFECT" Pause, so that both the Reciever reads the data, and the output to the LCD works. (I don't know your setup, so I don't knwo what you are trying to accomplish).

Try lowering the pause to
Pause 1

if it still works,

Pauseus 500

if it still works

Pauses 250.

And keep dividing in half.

Soon it will stop working... and you have a range to play with. You may find that if you have a pauseus between (lets say) 100 and 150 both receiver and LCD will work.

Why? because the pause is long enough for the receiver to work, and long enough for the LCD to work.

Another idea, is have your receiver check for something other than B0. Why? because the reciever will know that the data is LCD data, not its data. As soon as the Reciever sees its different than B0, it knows its good data, and can process it. Then you can happily have a LCD and your receiver working at the same time.

Mark Scotford
- 3rd September 2004, 15:45
Thanks Dwayne, I cannot change the Hardware at this stage, its already cost me over £300 in prototyping expenses. So I will have to live with the longish pause, I will experiment as you suggest with ever dcreasing Pauses, till I find the minimum and add a bit for safety. Incidentaly there are no Capacitive loads on any of the PIC pins. I have now found another short coming in my limited knowledge to do with the ADC, will post as a different question.

Yuantu Huang
- 19th August 2005, 05:20
Dear Sir,

The LCD works fine as long as the power is supplied non-stop. However, when I turn LCD power off and turn on again, LCD displays two line black square forever, similar to power on first time. The power of PIC18F8520 is always on (never off). The definition of LCD is as follows:

DEFINE LCD_EREG PORTA
DEFINE LCD_EBIT 2
DEFINE LCD_LINES 4
DEFINE LCD_RSREG PORTA
DEFINE LCD_RSBIT 0
DEFINE LCD_DREG PORTF
DEFINE LCD_DBIT 0
DEFINE LCD_BITS 8

Your help and advice would be very much appreciated.

Yuantu

Ingvar
- 19th August 2005, 08:46
The display needs to be initialized again, after poweron(and a pause) you need to do ......

Flags=0
LCDOUT blah,blah ,blah.......

/Ingvar

Yuantu Huang
- 22nd August 2005, 03:12
Hi Ingvar,

Thank you very much. You are right. The LCD needs to be reset after the power is restored. I can use

lcdout $fe,$38
lcdout $fe,$0c
lcdout $FE, 1

to restore 8 data line LCD display. But the above did not make 4 data line LCD display work. Could you please give me some suggestion how to fix the problems.

Thank you very much.

Yuantu

mister_e
- 22nd August 2005, 04:37
Sorry but Ingvar gives you the solution...
FLAGS=0

it's written in the PBP manual too.

Yuantu Huang
- 22nd August 2005, 08:43
Hi Steve,

I thought FLAGS was a pseudo flag. Now I understand FLAGS = 0 is a LCD reset statement. It is working.

Thank you and Ingvar for your help.