Menu

LCD Problems (related to interrupts)

Help
joe rocci
2009-08-13
2013-05-30
  • joe rocci

    joe rocci - 2009-08-13

    Hi guys!
    Thanks in part to Hugh's recent interrupt context-save fixes and in part to discovering my own dumb circuit mistake, I now have my multiple interrupts system running (see "Multiple Interrupts Problem" and "INT Interrupts Problems").

    The next problem seems related to the previous, but in regards to the LCD. I'm using a 4-bit device with no R/W line connection. I had a problem with the device coming up blank after a CPU reset, but I fixed that by disabling interrupts until the initialization part of my code finished and back on just before entering the main loop. Now the LCD comes up, but about every other reset, it just spews out all display data on one long line, despite the proper use of LOCATEs. When it does come up properly, all works fine until the next CPU reset. If I turn off interrupts, the LCD seems to work properly.

    My suspicion is that the interrupts are interfering with the LCD timing, but I can't prove it yet. I tried INTOFFs at various points in the application code, but nothing conclusive came of it.

    Suggestions ?

    Joe

     
    • Hugh Considine

      Hugh Considine - 2009-08-14

      This is pretty normal behaviour for an HD44780 in 4 bit mode.

      Normally, when first powered up the LCD will be in 8 bit mode. The PIC code will set the DB7:4 bits, then pulse Enable once. As long as the DB3:0 lines are tied down, the LCD will receive the byte b'xxxx0000', where xxxx is the DB7:4 bits. This will generally be the command to switch the LCD to 4 bit mode. Every transfer after this will involve the PIC setting DB7:4 to the contents of the first nibble of the byte it needs to send, then pulsing enable, then setting DB7:4 to the lower nibble of the byte, and pulsing Enable again.

      If the LCD is not completely powered down, and is sent the initialisation codes again, it will become confused. It will interpret the command to change to 4 bit mode as being the high nibble of an initialisation command, and then the high nibble of the next byte as the low nibble of the initialisation command. It will then end up 4 bits out of step for every command it's sent.

      If initialised a third time, the LCD will end up reading the initial 8 bit mode command as the low nibble of the previous byte, then will be back in step. GCBASIC will then send the clear screen command, and it will go back to normal.

      The best solution to this is to make sure that the LCD is reset when the PIC resets, but if this is not possible you can probably get away with initialising the LCD a third time to return it to normal.

       
    • joe rocci

      joe rocci - 2009-08-14

      I think I see what's causing this problem and it seems to be related to an invalid SFR bank pointer. First, look at the EQU table from the .asm file:
      ;Set aside memory locations for variables
      DELAYTEMP    EQU    112
      DELAYTEMP2    EQU    113
      SYSDIVLOOP    EQU    116
      SYSDIVMULTA    EQU    119
      SYSDIVMULTA_H    EQU    120
      SYSDIVMULTB    EQU    123
      SYSDIVMULTB_H    EQU    124
      SYSDIVMULTX    EQU    114
      SYSDIVMULTX_H    EQU    115
      SYSSTRINGLENGTH    EQU    118
      SysCalcTempA    EQU    117
      SysCalcTempA_H    EQU    118
      SysCalcTempB    EQU    121
      SysCalcTempB_H    EQU    122
      SysCalcTempX    EQU    112
      SysCalcTempX_H    EQU    113
      SysSTATUS    EQU    127
      SysStringA    EQU    119
      SysStringA_H    EQU    120
      SysStringB    EQU    114
      SysStringB_H    EQU    115
      SysW    EQU    126
      SysWaitTemp10US    EQU    117
      SysWaitTempMS    EQU    114
      SysWaitTempMS_H    EQU    115
      SysWaitTempS    EQU    116
      SysWaitTempUS    EQU    117
      SysWaitTempUS_H    EQU    118
      SYSSTRINGPARAM1    EQU    453
      DIGITS    EQU    443
      DIGIT    EQU    436
      BINARYBYTES    EQU    431
      BWORD    EQU    422
      ADREADPORT    EQU    32
      CARRYBYTE    EQU    33
      COUNTERVALUE    EQU    34
      DELTA1    EQU    35
      DELTA2    EQU    36
      DESIREDFREQ    EQU    37
      DESIREDFREQ_H    EQU    38
      ENCODER    EQU    40
      FREQCOUNTER    EQU    41
      FREQCOUNTER_H    EQU    42
      FREQERROR    EQU    43
      FREQERROR_H    EQU    44
      FREQH    EQU    45
      GATECAL    EQU    46
      GPBYTE    EQU    47
      GPWORDVARIABLE1    EQU    48
      GPWORDVARIABLE1_H    EQU    49
      GPWORDVARIABLE2    EQU    50
      GPWORDVARIABLE2_H    EQU    51
      I    EQU    52
      J    EQU    53
      K    EQU    54
      LCDBYTE    EQU    55
      LCDCHAR    EQU    56
      LCDCOLUMN    EQU    57
      LCDLINE    EQU    58
      LCDPUTCOLUMN    EQU    59
      LCDPUTLINE    EQU    60
      LCDREADY    EQU    61
      LCDVALUE    EQU    62
      LCDVALUETEMP    EQU    63
      MODE    EQU    64
      NEWCOUNTAVAILABLE    EQU    65
      PORT    EQU    66
      PRINTLEN    EQU    67
      PRODUCT    EQU    68
      PRODUCT_H    EQU    69
      PULSECONSTANT1    EQU    71
      PULSECONSTANT2    EQU    72
      PULSEWIDTH    EQU    73
      PULSEWIDTH_H    EQU    74
      READAD10    EQU    75
      READAD10_H    EQU    76
      STARTUPCOUNTER    EQU    78
      STARTUPFINISHED    EQU    79
      SYSBITVAR0    EQU    80
      SYSPRINTTEMP    EQU    81
      StringPointer    EQU    82
      SysIFTemp    EQU    83
      SysIntOffCount    EQU    84
      SysPRINTDATAHandler    EQU    85
      SysPRINTDATAHandler_H    EQU    86
      SysTemp1    EQU    87
      SysTemp1_H    EQU    88
      SysTemp2    EQU    89
      T1H    EQU    90
      T1L    EQU    91
      TEMP    EQU    92
      TMR0OVERFLOWS    EQU    93
      TMR0PRES    EQU    94
      TMR0SOURCE    EQU    95
      TMR1OVERFLOWS    EQU    96
      TMR1PRES    EQU    97
      TMR1SOURCE    EQU    98
      TMR2PRES    EQU    99
      TMRNUMBER    EQU    100
      TUNINGVOLTS    EQU    101
      TUNINGVOLTS_H    EQU    102
      VOLTS    EQU    103
      VOLTS_H    EQU    104

      Notice those variable assignments up in the 430-450 range of bank 3. Now notice that the LCD display variables are in the range of about 55-63 in bank 0. These bank 0 variables would directly underlay the bank 3 variable addresses if the bank pointer were set wrong. Now look at the asm code for part of the LCD stuff:
      ENDIF25
          movlw    198
          subwf    DESIREDFREQ,W
          movwf    SysTemp1
          movlw    47
          btfss    STATUS,C
          addlw    1
          subwf    DESIREDFREQ_H,W
          movwf    SysTemp1_H
          movwf    SysCalcTempA_H
          movf    SysTemp1,W
          movwf    SysCalcTempA
          movlw    82
          movwf    SysCalcTempB
          movlw    6
          movwf    SysCalcTempB_H
          call    SysDivSub16
          movf    SysCalcTempA_H,W
          movwf    GPWORDVARIABLE2_H
          movf    SysCalcTempA,W
          movwf    GPWORDVARIABLE2
          movlw    1
          movwf    LCDPUTLINE
          movf    GPWORDVARIABLE2,W
          movwf    LCDPUTCOLUMN
          movlw    94
          movwf    LCDCHAR
          call    PUT

      There are references to a bunch of variables located in bank 0, then some writes to the LCD variables which are located in bank, with no intervening "banksel" to point to bank3.

      I think that the code is pointing to an address in bank 3 while the bank pointer is still pointing to bank 0, causing the LCD variables to get overwritten.

      Comments?

      Joe

       
    • joe rocci

      joe rocci - 2009-08-14

      I may have mis-analyzed the presumed banksel problem above, but it sure seems more than coincidental that variables up in bank3 directly overlay the LCD variables down in bank 0 that would cause the problem I'm seeing.

      BTW, the chip is a 16F877A @ 20MHz.

      Joe

       
      • Hugh Considine

        Hugh Considine - 2009-08-14

        The array and string variables that are placed at the end of the last bank are all quite large, so there's a good chance they'll overlap some variables in bank 0. Arrays and strings are generally dealt with using indirect addressing, which has a different bank select bit (STATUS.IRP) to the direct addressing used for normal variables (which uses STATUS.RP0 and STATUS.RP1 for bank select).

        What causes the reset?

         
    • joe rocci

      joe rocci - 2009-08-14

      Hugh,

      Sorry, I didn't see your post above before I made my log-winded post.

      The PIC and the LCD are powered from the same supply, and the problem occurs even at power-on. I tried putting in extra INITLCD's, but that didn't seem to help either.

      Joe

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.