No announcement yet.

lcdout corrupts data in array

  • Filter
  • Time
  • Show
Clear All
new posts

  • lcdout corrupts data in array

    lcdout seems to corrupt array variables when sending str's
    the following code snippet produces this result
    from a serial stream without the lcdout cmd
    ABCDEFGHI,012345678 "as expected
    with the lcdout commands
    the result is on the serial stream @BCDEFGHI,002345678

    and displayed on the lcd first pass


    on the lcd next pass


    if i only send row 1 to the lcd
    buff2 array still gets corrupted but not buff1
    sending a str longer than 8 chrs has this effect
    nb: a long string displays ok one time only but at what cost to other variables

    i dont want this to happen help!!! is it a bug or
    is the max length of [str arrayvar \n] where n < 9 in lcdout function

    tried 16f819 and 16f648a pics

    buff1 var BYTE[16]
    buff2 var BYTE[16]
    cnt var byte

    'put some data in the arrays
    FOR CNT = 0 TO 8
    TMP = (CNT + 65 )
    buff1[CNT] = TMP

    FOR CNT = 0 TO 8
    TMP = (CNT + 48 )
    buff2[CNT] = TMP
    'sent it out to verify data
    serout2 portb.7,396,[ str buff1\9,",",str buff2\9 ,13,10]
    'send to lcd
    lcdout $FE,$1, str buff1\9 'row 1
    lcdout $FE,$C0, str buff2\9 'row 2
    PAUSE 10000
    'resend to serial device
    serout2 portb.7,396,[ str buff1\9,",",str buff2\9 ,13,10]

    PAUSE 10000
    goto loop

  • #2
    Well, first I have to make a few assumptions here.

    1. There are no LCD defines in your program, so you are using these defaults ...
    DEFINE LCD_DREG PORTA     ' LCD data port 
    DEFINE LCD_DBIT 0         ' LCD data starting bit 0 or 4 
    DEFINE LCD_RSREG PORTA    ' LCD register select port 
    DEFINE LCD_RSBIT 4        ' LCD register select bit 
    DEFINE LCD_EREG PORTB     ' LCD enable port 
    DEFINE LCD_EBIT 3         ' LCD enable bit 
    DEFINE LCD_BITS 4         ' LCD bus size 4 or 8 
    DEFINE LCD_LINES 2        ' Number lines on LCD 
    DEFINE LCD_COMMANDUS 2000 ' Command delay time in us 
    DEFINE LCD_DATAUS 50      ' Data delay time in us
    2. There is no TMP variable declared, so there is more code than you have shown.

    3. You are using a label called Loop:, so your version of PBP is prior to 2.60 even though you posted in the PBP3 forum.

    4. There is no ADCON1 statement, so the pins used for the LCD are still in Analog mode.

    5. The serout pin has not been initialized, so the first output you receive is all garbage characters.

    When I run your code in PBP3/Proteus, it looks like this ...

    Click image for larger version

Name:	Corrupt_LCDOUT.jpg
Views:	1
Size:	90.6 KB
ID:	5158

    Can you clear up any of my assumptions?
    PBP3 Manual : Microchip Datasheets - 10F, 12F, 16F, 18F
    Never download a PIC datasheet from anywhere but


    • #3
      thanks for your consideration
      a more complete example to demonstrate problem
      i get the same result with pbp 2.6 and 3.0
      chip is prg via a pickit2 and serial data is monitored via its uart function

      with this version the variable tmp won't increment past 19 either and after the 8th loop
      buff3 becomes corrupted on the display too yet with the
      lcdout str buff2 \8, str buff3 \8 ,$FE,$C0,#tmp
      remarked out tmp can increment to its limit and buff3 is ok

      the problem only occurs when a str is output via lcdout

      this program is only to demonstrate the problem




      '// Define port pins as inputs and outputs ...


      buff2 var BYTE[8]
      CNT var byte ' Byte for counter
      TMP var byte ' Byte for second counter
      buff1 var BYTE[16]
      buff3 var BYTE[8]
      dw con 15 'display width not used
      'LCD defines begin here
      DEFINE LCD_BITS 4 'defines the number of data interface lines (4 or 8)
      DEFINE LCD_DREG PORTB 'defines the port where data lines are connected to
      DEFINE LCD_DBIT 4 'defines the position of data lines for 4-bit interface (0 or 4)
      DEFINE LCD_RSREG PORTA 'defines the port where RS line is connected to
      DEFINE LCD_RSBIT 1 'defines the pin where RS line is connected to
      DEFINE LCD_EREG PORTA 'defines the port where E line is connected to
      DEFINE LCD_EBIT 0 'defines the pin where E line is connected
      DEFINE LCD_RWREG 0 'defines the port where R/W line is connected to (set to 0 if not used)
      DEFINE LCD_RWBIT 0 'defines the pin where R/W line is connected to (set to 0 if not used)
      DEFINE LCD_COMMANDUS 2500 'defines the delay after LCDOUT statement
      DEFINE LCD_DATAUS 255 'delay in micro seconds
      ' DEFINE HSER_RCSTA 90h will use hserin/out later
      ' define HSER_BAUD 2400
      'define HSER_BITS 8

      TRISA = %11111100
      TRISB = %00001110

      'includes begin here
      ' INCLUDE "modedefs.bas"

      'end of includes

      'Main code begins here


      Pause 500 ' LCD initialize time
      lcdout $FE,1,"ready 2400 BAUD" 'clear display
      PAUSE 1000
      FOR CNT = 0 TO 15 ' fill buff1 with data

      buff1[CNT] = (CNT + 65 + TMP)
      NEXT CNT

      FOR CNT = 0 TO 7
      buff2[CNT] = buff1[CNT] 'copy first 8 bytes to buff2
      buff3[CNT] = buff1[(CNT+8)] 'and last 8 to buff3
      NEXT CNT

      tmp = tmp+1
      if tmp=30 then tmp=0

      serout2 portb.7,396,10,[ #tmp,str buff1 \16 , "," ,str buff2 \8 , "," , str buff3 \8 ,10,13 ]

      lcdout $FE,$1
      lcdout str buff2 \8, str buff3 \8 ,$FE,$C0,#tmp ' try with this line remarked out
      PAUSE 1000
      'send buff1 to serial port and note change
      serout2 portb.7,396,10,[ str buff1 \16 ,"," ,str buff2 \8,",",str buff3 \8 ,10 ,13]

      PAUSE 2000
      goto main



      • #4
        I thought portb.7 being used for icsp and serial out and in the lcd data port too might be a bit much, i have moved the serial output to porta.6 (otherwise unused) and get
        the same result except now the tmp variable won't increment beyond 13


        • #5
          Thanks for the full program Richard.
          The problem's are often not where you think they are.

          In this case, I believe the culprit is in this line.
          DEFINE LCD_RWREG 0 'defines the port where R/W line is connected to (set to 0 if not used)
          By setting it to 0, it points the R/W pin's register to address 0 which is the INDF (indirect addressing) register.

          LCDOUT with STRings uses the FSR/INDF registers to access the strings and leaves the FSR pointing to the arrays. When you write to the LCD it will try to change the R/W bit which instead changes the values in the array.

          If you are not using the R/W pin, do not add defines for it.
          Remove the LCD_RWREG define and you should see a difference.
          PBP3 Manual : Microchip Datasheets - 10F, 12F, 16F, 18F
          Never download a PIC datasheet from anywhere but


          • #6
            many thanks darrel I would have no hair left by the time I worked that out
            keep up the good work