Shop OBEX P1 Docs P2 Docs Learn Events
LCD problem with 80mHz — Parallax Forums

LCD problem with 80mHz

kenmackenmac Posts: 96
edited 2008-10-20 07:06 in Propeller 1
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:

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

  • kenmackenmac Posts: 96
    edited 2008-10-16 05:18
    That should read "clock independant"

    kenmac

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Perth, Western Australia
    Time Zone = GMT + 8
  • mparkmpark Posts: 1,305
    edited 2008-10-16 06:12
    Gentle reminder: "mHz" means millihertz. If you're going to capitalize the "H", go all the way and make it "MHz" (megahertz) which is the unit you want anyway.

    Sorry, pet peeve.
  • Capt. QuirkCapt. Quirk Posts: 872
    edited 2008-10-16 07:25
    Write some code to incorperate the "busy flag", It will stop your program from cramming data into the lcd before it's ready to accept it.

    Post Edited (Capt. Quirk) : 10/16/2008 7:30:26 AM GMT
  • kenmackenmac Posts: 96
    edited 2008-10-16 07:57
    mpark
    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
  • kenmackenmac Posts: 96
    edited 2008-10-17 02:29
    Are there any more suggestions on why this is happening?

    kenmac

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Perth, Western Australia
    Time Zone = GMT + 8
  • hippyhippy Posts: 1,981
    edited 2008-10-17 02:50
    Maybe the microsecond delays just aren't long enough ? When running slower, the time it takes to execute the Spin itself may be pushing the timing out to what is acceptable and works, faster and it doesn't, for example ...

    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.
  • Lord SteveLord Steve Posts: 206
    edited 2008-10-17 03:27
    I believe that the Spin compiler does not optimize "x / 16" as "x >> 4", does it?

    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.

    ·
  • VIRANDVIRAND Posts: 656
    edited 2008-10-18 00:44
    kenmac said...
    Point taken re MHz, but I've never heard the term millihertz used anywhere.

    Just FYI and LOL, millihertz can be found in seismological instrumentation.
  • RaymanRayman Posts: 14,243
    edited 2008-10-18 01:14
    Can you tell us exactly what LCD you're using?
  • kenmackenmac Posts: 96
    edited 2008-10-18 11:51
    Rayman,
    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
  • RaymanRayman Posts: 14,243
    edited 2008-10-18 16:28
    I would add a delay between each OUTA occurance...

    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
  • kenmackenmac Posts: 96
    edited 2008-10-20 07:06
    Rayman,
    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
Sign In or Register to comment.