LCD problem with 80mHz
kenmac
Posts: 96
Hi folks,
I have a program that normally operates at 5mHz and uses a parallel LCD.
I have now increased the clock to 80mHz, and find that the LCD no longer works.
Looking at the object that controls the LCD, I can't see any reason for this to occur - all the delays are implemented as "clock dependent" and shouldn't be affected by the clock speed change.
I isolated this object as a standalone to display one character (A), varying the clock multiplier top see what effect that had.
The LCD displays correctly for all multipliers except the final 16x (80mHz).
This is the relevant code:
Can anyone shed some light on why this is ocurring?
kenmac
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Perth, Western Australia
Time Zone = GMT + 8
I have a program that normally operates at 5mHz and uses a parallel LCD.
I have now increased the clock to 80mHz, and find that the LCD no longer works.
Looking at the object that controls the LCD, I can't see any reason for this to occur - all the delays are implemented as "clock dependent" and shouldn't be affected by the clock speed change.
I isolated this object as a standalone to display one character (A), varying the clock multiplier top see what effect that had.
The LCD displays correctly for all multipliers except the final 16x (80mHz).
This is the relevant code:
con _clkmode = xtal1 + pll16x _clkfreq = 5_000_000 ' 5 mHz rs = 4 'Register select Pin en = 5 'Enable Pin msb = 0 'Highest dataline lsb = 3 'Lowest dataline 'LCD Commands EightBitInit = 3 'Eight Bit mode FourBitInit = 2 'Four Bit mode ClearLcd = 1 'Clear the LCD CursorBlink = $0F 'Turn the cursor on and blink it NoCursor = $0C 'Turn the cursor off Line1 = $80 'Address of the First Line Line2 = $C0 'Address of the Second Line var byte CurrentLine 'Current Line position Value 0-3 byte CurrentPos 'Current Column position Value 0-19 pub main init ' initialise LCD cls ' clear display write("A") ' display character A repeat { Initialize the LCD to four bit mode and clear it } pub init dira[noparse][[/noparse]msb..lsb]~~ ' set data pins as outputs outa[noparse][[/noparse]msb..lsb]~ dira[noparse][[/noparse]en..rs]~~ ' set Enable/RS as pins as outputs. outa[noparse][[/noparse]en..rs]~ outa[noparse][[/noparse]msb..lsb] := EightBitInit ' = 3 enable uSdelay(5000) ' 5ms enable uSdelay(1000) ' 1ms enable uSdelay(1000) ' 1ms outa[noparse][[/noparse]msb..lsb] := FourBitInit ' = 2 enable commandOut(40) ' 4bit mode, 2 lines, 5 x 7 format commandOut(12) ' display on,cursor off/no blink commandOut(6) ' increment, no shift commandOut(ClearLcd) ' = 1 CurrentLine := 0 CurrentPos := 0 uSdelay(5000) ' 5ms { Write out a single character to the display } pub write(character) outa[noparse][[/noparse]msb..lsb] := character / 16 ' get high nibble enable ' enable write outa[noparse][[/noparse]msb..lsb] := character & 15 ' get lower nibble enable ' enable write outa[noparse][[/noparse]rs]~~ { Clear the display } pub cls commandOut(ClearLcd) CurrentLine := 0 CurrentPos := 0 uSdelay(5000) { Toggle the enable line } pri enable outa[noparse][[/noparse]en]~~ ' set enable pin uSdelay(100) outa[noparse][[/noparse]en]~ ' clear enable pin { Send a command } pri commandOut(char) ' outa[noparse][[/noparse]rs]~ write(char) ' send command character { Delay for # of microseconds } pub uSdelay(DelayuS) ' waitcnt((clkfreq/1_000_000) * DelayuS + cnt)
Can anyone shed some light on why this is ocurring?
kenmac
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Perth, Western Australia
Time Zone = GMT + 8
Comments
kenmac
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Perth, Western Australia
Time Zone = GMT + 8
Sorry, pet peeve.
Post Edited (Capt. Quirk) : 10/16/2008 7:30:26 AM GMT
Point taken re MHz, but I've never heard the term millihertz used anywhere.
Capt Quirk
There is a fixed "realtime" delay between each write, so that should maintain the normal operation of the LCD.
All the delays automatically adjust to the Clock speed, maintaining the real delay. ( waitcnt(clkfreq/1_000_000 * delay + cnt) )
So, the data shouldn't be creating a log-jam in the LCD.
Ken Mac
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Perth, Western Australia
Time Zone = GMT + 8
kenmac
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Perth, Western Australia
Time Zone = GMT + 8
outa[noparse][[/noparse]msb..lsb] := character / 16
enable
outa[noparse][[/noparse]msb..lsb] := character & 15
enable
When running faster, the time between changing OUTA and then setting the LCD enable as the first thing in the 'enable' routine will be a much shorter period. Maybe you need additional delays before asserting LCD enable.
If not, then the effect hippy just mentioned could happen.· I would try replacing the divide by 16 with a right shift by 4 and trying that with the original, SLOWER clock speed.
If it does not work, then it would seem that the divide by 16 operation bought you your time.
If it does work, crank up the clock speed until it does not work.· If the clock speed it breaks at is significantly lower than the clock speed you are currently having trouble at, then it would seem that the divide by 16 operation bought you your time.
At any rate, I don't know if the Spin compiler optimizes divides, so this may be the wrong road.
·
Just FYI and LOL, millihertz can be found in seismological instrumentation.
The LCD is a generally available item (no brand) which I have used successfully for years.
I am aware that some models are particular about the length of the Enable pulse, but not this one (that I know of).
This LCD control program works OK at PLL8x but not at 16x.
As you can see in the program, all the delays should remain the same "realtime" whatever the Clock speed, so the LCD isn't really being addressed any faster.
Anyway, I only noticed the effect by accident when experimenting with the 80MHz Clock on another program.
It didn't make sense to me so I decided to check on the Forum.
I'm not going to worry about it at this stage because I haven't any plans to use the LCD in any project at that speed.
Later I may drag out the CRO and see if I can spot something.
Thanks folks,
kenmac
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Perth, Western Australia
Time Zone = GMT + 8
For example, there is no delay between the last OUTA in the enable call and the next statement here:
enable ' enable write
outa[noparse][[/noparse]msb..lsb] := character & 15 ' get lower nibble
That makes sense.
Today I had another look at it, intending to implement the extra delays, and wouldn't you know it, the problem seems to have gone away.
That is, without putting in the extra delays, the LCD is now behaving normally at 80MHz.
The only difference that I know of is that the ambient temperature has increased by about 15C.
Perhaps that is enough to change the reaction of the LCD electronics.
However, I'll add the extra delays, just in case I use the LCD in a project running at 80MHz.
Thanks for your help.
kenmac
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Perth, Western Australia
Time Zone = GMT + 8