Menu

LCD Library

2007-10-04
2013-05-30
  • Nobody/Anonymous

    '******* This version uses the 16F876A ****************
    '   This version fails

    #chip 16F876a, 10

    #define LCD_IO 4
    #define LCD_DB4 PORTB.0
    #define LCD_DB5 PORTB.1
    #define LCD_DB6 PORTB.2
    #define LCD_DB7 PORTB.3
    #define LCD_RS PORTA.3
    #define LCD_RW PORTA.2
    #define LCD_Enable PORTA.1

    'InitLCD
    TRISA = 0x30
    TRISB = 0xf0
    ADCON1 = 0x07

    loop:
    Print "LCDterm II"
    wait 1 sec
    CLS
    wait 100 ms
    goto loop

    '********************************************************
    '******** This version uses the 16F877A
    '   This version runs

    #chip 16F877a, 10

    #define LCD_IO 4
    #define LCD_DB4 PORTD.4
    #define LCD_DB5 PORTD.5
    #define LCD_DB6 PORTD.6
    #define LCD_DB7 PORTD.7
    #define LCD_RS PORTE.0
    #define LCD_RW PORTE.1
    #define LCD_Enable PORTE.2

    'InitLCD
    loop:
    Print "LCDterm II"
    wait 1 sec
    CLS
    wait 100 ms
    goto loop

     
    • Hugh Considine

      Hugh Considine - 2007-10-06

      Very strange!

      I can't see any alternate pin functions that would be causing trouble - LVP, the comparator and A/D converter are all disabled correctly. The fact that the code works fine on the 16F877A but not the 16F876A is very odd!

      Could you please post the assembly code generated for the 876A by GCBASIC?

      If you haven't already, it might also be worth checking to see if the PIC is working:
      - Check that MCLR is pulled up to 5 volts
      - Check that there is a voltage on the oscillator pins
      - Download an LED flashing program, and see if it works
      - Check that all of the LCD pins are wired up as specified in the constants

       
    • Nobody/Anonymous

      I will post the assembly code. As far as the PIC is concerned, I have a 4K word program compiled with Oshonsoft Basic that is running fine. What I was in the process of doing is getting the same code compiled with GCBASIC but starting with some small test programs.

      You notice that one main difference is the failing code uses the lower nibble of the port. Maybe the nibble section of the library has a problem.

       
    • Hugh Considine

      Hugh Considine - 2007-10-10

      Using the lower nibble shouldn't make any difference, when in 4-bit mode the GCBASIC LCD library only uses operations that act on a single bit.

      Does GCBASIC initialise the LCD properly? If you're using a 2-line LCD, you can tell by setting the contrast on the LCD to the maximum and then checking to see how many lines there are. 1 line means it's not initialised, 2 means it is.

      I'll look thoroughly at the assembly when you post it, hopefully there will be some clue!

      What version of GCBASIC are you using? The latest released version (0.9.3.0, dated January some time), or a more recent update? If you're using the latest update, what is the date on it?

       
    • Nobody/Anonymous

      ;Program compiled by Great Cow BASIC (0.9 6/10/2007)
      ;Need help? See the GCBASIC forums at http://sourceforge.net/forum/?group_id=169286,
      ;check the documentation or email hconsidine@bigpond.com.

      ;********************************************************************************

      ;Set up the assembler options (Chip type, clock source, other bits and pieces)
      LIST p=16F876A, r=DEC
      #include <P16F876A.inc>
      __CONFIG _HS_OSC & _WDT_OFF & _LVP_OFF

      ;********************************************************************************

      ;Set aside memory locations for variables
      SysTempArray    equ    454 ;Array
      DELAYTEMP    equ    32
      DELAYTEMP2    equ    33
      LCDBYTE    equ    34
      LCDREADY    equ    35
      PRINTLEN    equ    36
      SYSCALCTEMPA    equ    37
      SYSCALCTEMPA_H    equ    38
      SYSLCDTEMP    equ    39
      SYSPRINTTEMP    equ    40
      SYSSTRINGLENGTH    equ    41
      StringPointer    equ    42
      SysPRINTDATAHandler    equ    43
      SysPRINTDATAHandler_H    equ    44
      SysStringA    equ    45
      SysStringA_H    equ    46
      SysStringB    equ    47
      SysStringB_H    equ    48
      SysWaitTemp10US    equ    49
      SysWaitTempMS    equ    50
      SysWaitTempMS_H    equ    51
      SysWaitTempS    equ    52

      ;********************************************************************************

      ;Jump to initialisation code when PIC is reset
          ORG    0
          clrf    PCLATH
          goto    SystemInitialise

      ;********************************************************************************

      ;Interrupt vector
          ORG    4
          retfie
      ;Various initialisation routines, automatically called by GCBASIC
      SystemInitialise
          call    INITSYS
          call    INITLCD

      ;********************************************************************************

      ;Start of the main program
          movlw    48
          banksel    TRISA
          movwf    TRISA
          movlw    240
          movwf    TRISB
          movlw    7
          movwf    ADCON1
      LOOP
          movlw    low SysTempArray
          banksel    SYSSTRINGB
          movwf    SysStringB
          movlw    high SysTempArray
          movwf    SysStringB_H
          movlw    low StringTable1
          movwf    SysStringA
          movlw    high StringTable1
          movwf    SysStringA_H
          call    SysReadString
          movlw    low SYSTEMPARRAY
          movwf    SysPRINTDATAHandler
          movlw    high SYSTEMPARRAY
          movwf    SysPRINTDATAHandler_H
          call    PRINT
          movlw    1
          movwf    SysWaitTempS
          call    Delay_S
          call    CLS
          movlw    100
          movwf    SysWaitTempMS
          clrf    SysWaitTempMS_H
          call    Delay_MS
          goto    LOOP
      BASPROGRAMEND
          sleep
          goto    $

      ;********************************************************************************

      ; String Lookup Table
      SysStringTables
          movf    SysStringA_H,W
          movwf    PCLATH
          movf    SysStringA,W
          incf    SysStringA,F
          btfsc    STATUS,Z
          incf    SysStringA_H,F
          movwf    PCL

      StringTable1
          retlw    10
          retlw    76    ;L
          retlw    67    ;C
          retlw    68    ;D
          retlw    116    ;t
          retlw    101    ;e
          retlw    114    ;r
          retlw    109    ;m
          retlw    32    ;
          retlw    73    ;I
          retlw    73    ;I

      ;********************************************************************************
      ;Subroutines included in program
      ;********************************************************************************

      CLS
          bcf    PORTA,3
          movlw    1
          movwf    LCDBYTE
          call    LCDWRITEBYTE
          movlw    2
          movwf    SysWaitTempMS
          clrf    SysWaitTempMS_H
          call    Delay_MS
          movlw    128
          movwf    LCDBYTE
          call    LCDWRITEBYTE
          movlw    10
          movwf    SysWaitTemp10US
          call    Delay_10US
          return

      ;********************************************************************************

      Delay_10US
      D10US_START
          movlw    8
          movwf    DELAYTEMP
      D10US_LOOP
          decfsz    DELAYTEMP, F
          goto    D10US_LOOP
          decfsz    SysWaitTemp10US, F
          goto    D10US_START
          return

      ;********************************************************************************

      Delay_MS
          incf    SysWaitTempMS_H, F
      DMS_START
          movlw    10
          movwf    DELAYTEMP2
      DMS_OUTER
          movlw    83
          movwf    DELAYTEMP
      DMS_INNER
          decfsz    DELAYTEMP, F
          goto    DMS_INNER
          decfsz    DELAYTEMP2, F
          goto    DMS_OUTER
          decfsz    SysWaitTempMS, F
          goto    DMS_START
          decfsz    SysWaitTempMS_H, F
          goto    DMS_START
          return

      ;********************************************************************************

      Delay_S
      DS_START
          movlw    232
          movwf    SysWaitTempMS
          movlw    3
          movwf    SysWaitTempMS_H
          call    Delay_MS
          decfsz    SysWaitTempS, F
          goto    DS_START
          return

      ;********************************************************************************

      FN_LCDREADY
          clrf    LCDREADY
          bcf    SYSLCDTEMP,2
          btfsc    PORTA,3
          bsf    SYSLCDTEMP,2
          bsf    PORTA,2
          bcf    PORTA,3
          bsf    PORTA,1
          movlw    5
          movwf    SysWaitTemp10US
          call    Delay_10US
          banksel    TRISB
          bsf    TRISB,3
          banksel    PORTB
          btfsc    PORTB,3
          goto    ENDIF1
          movlw    255
          movwf    LCDREADY
      ENDIF1
          bcf    PORTA,1
          movlw    25
          movwf    SysWaitTemp10US
          call    Delay_10US
          bcf    PORTA,3
          btfsc    SYSLCDTEMP,2
          bsf    PORTA,3
          return

      ;********************************************************************************

      INITLCD
          banksel    TRISA
          bcf    TRISA,3
          bcf    TRISA,2
          bcf    TRISA,1
          movlw    10
          banksel    SYSWAITTEMPMS
          movwf    SysWaitTempMS
          clrf    SysWaitTempMS_H
          call    Delay_MS
      SysWaitLoop1
          call    FN_LCDREADY
          movf    LCDREADY,F
          btfsc    STATUS,Z
          goto    SysWaitLoop1
          bcf    PORTA,3
          banksel    TRISB
          bcf    TRISB,0
          bcf    TRISB,1
          bcf    TRISB,2
          bcf    TRISB,3
          banksel    PORTA
          bcf    PORTA,3
          bcf    PORTA,2
          bcf    PORTB,0
          bsf    PORTB,1
          bcf    PORTB,2
          bcf    PORTB,3
          bsf    PORTA,1
          movlw    5
          movwf    SysWaitTemp10US
          call    Delay_10US
          bcf    PORTA,1
          movlw    5
          movwf    SysWaitTempMS
          clrf    SysWaitTempMS_H
          call    Delay_MS
          movlw    40
          movwf    LCDBYTE
          call    LCDWRITEBYTE
          movlw    25
          movwf    SysWaitTemp10US
          call    Delay_10US
          bcf    PORTA,3
          movlw    6
          movwf    LCDBYTE
          call    LCDWRITEBYTE
          movlw    5
          movwf    SysWaitTemp10US
          call    Delay_10US
          movlw    12
          movwf    LCDBYTE
          call    LCDWRITEBYTE
          movlw    5
          movwf    SysWaitTemp10US
          call    Delay_10US
          call    CLS
          return

      ;********************************************************************************

      INITSYS
          bcf    ADCON0,ADON
          banksel    ADCON1
          bcf    ADCON1,ADFM
          bcf    ADCON1,PCFG3
          bsf    ADCON1,PCFG2
          bsf    ADCON1,PCFG1
          bcf    ADCON1,PCFG0
          movlw    7
          movwf    CMCON
          banksel    PORTA
          clrf    PORTA
          clrf    PORTB
          clrf    PORTC
          return

      ;********************************************************************************

      LCDWRITEBYTE
      SysWaitLoop2
          call    FN_LCDREADY
          movf    LCDREADY,F
          btfsc    STATUS,Z
          goto    SysWaitLoop2
          bcf    PORTA,2
          banksel    TRISB
          bcf    TRISB,0
          bcf    TRISB,1
          bcf    TRISB,2
          bcf    TRISB,3
          banksel    PORTB
          bcf    PORTB,0
          bcf    PORTB,1
          bcf    PORTB,2
          bcf    PORTB,3
          btfsc    LCDBYTE,7
          bsf    PORTB,3
          btfsc    LCDBYTE,6
          bsf    PORTB,2
          btfsc    LCDBYTE,5
          bsf    PORTB,1
          btfsc    LCDBYTE,4
          bsf    PORTB,0
          bsf    PORTA,1
          movlw    5
          movwf    SysWaitTemp10US
          call    Delay_10US
          bcf    PORTA,1
          movlw    5
          movwf    SysWaitTemp10US
          call    Delay_10US
          bcf    PORTB,0
          bcf    PORTB,1
          bcf    PORTB,2
          bcf    PORTB,3
          btfsc    LCDBYTE,3
          bsf    PORTB,3
          btfsc    LCDBYTE,2
          bsf    PORTB,2
          btfsc    LCDBYTE,1
          bsf    PORTB,1
          btfsc    LCDBYTE,0
          bsf    PORTB,0
          bsf    PORTA,1
          movlw    5
          movwf    SysWaitTemp10US
          call    Delay_10US
          bcf    PORTA,1
          movlw    5
          movwf    SysWaitTemp10US
          call    Delay_10US
          bcf    PORTB,3
          bcf    PORTB,2
          bcf    PORTB,1
          bcf    PORTB,0
          return

      ;********************************************************************************

      PRINT
          movf    SysPRINTDATAHandler,W
          movwf    FSR
          bcf    STATUS, IRP
          btfsc    SysPRINTDATAHandler_H,0
          bsf    STATUS, IRP
          movf    INDF,W
          movwf    PRINTLEN
          movlw    0
          subwf    PRINTLEN,W
          btfsc    STATUS, Z
          return
          bsf    PORTA,3
          clrf    SYSPRINTTEMP
      SysForLoop1
          incf    SYSPRINTTEMP,F
          movf    SYSPRINTTEMP,W
          addwf    SysPRINTDATAHandler,W
          movwf    FSR
          bcf    STATUS, IRP
          btfsc    SysPRINTDATAHandler_H,0
          bsf    STATUS, IRP
          movf    INDF,W
          movwf    LCDBYTE
          call    LCDWRITEBYTE
          movf    PRINTLEN,W
          subwf    SYSPRINTTEMP,W
          btfss    STATUS, C
          goto    SysForLoop1
          return

      ;********************************************************************************

      SYSREADSTRING
          movf    SYSSTRINGB, W
          movwf    FSR
          bcf    STATUS, IRP
          btfsc    SYSSTRINGB_H, 0
          bsf    STATUS, IRP
          call    SYSSTRINGTABLES
          movwf    SYSCALCTEMPA
          movwf    INDF
          addwf    SYSSTRINGB, F
          goto    SYSSTRINGREADCHECK
      SYSREADSTRINGPART
          movf    SYSSTRINGB, W
          movwf    FSR
          bcf    STATUS, IRP
          btfsc    SYSSTRINGB_H, 0
          bsf    STATUS, IRP
          call    SYSSTRINGTABLES
          movwf    SYSCALCTEMPA
          addwf    SYSSTRINGLENGTH,F
          addwf    SYSSTRINGB,F
      SYSSTRINGREADCHECK
          movf    SYSCALCTEMPA,F
          btfsc    STATUS,Z
          return
      SYSSTRINGREAD
          call    SYSSTRINGTABLES
          incf    FSR, F
          movwf    INDF
          decfsz    SYSCALCTEMPA, F
          goto    SYSSTRINGREAD
          return

      ;********************************************************************************

      END

       
    • Hugh Considine

      Hugh Considine - 2007-10-10

      The assembly produced looks absolutely fine - aside from a few (expected) differences, it's identical to the copy of your code that runs fine on the 877A I have.

      Are you using the same LCD on your 876A and 877A? If not, it could be a timing issue.

      Another possibility is that there is a problem with the R/W wire. GCBASIC reads the status from the LCD and doesn't continue until it is ready, but I know that some other compilers/routines don't do this.

      Could you add some code to toggle a port to see if GCBASIC is detecting whether the LCD is ready? To do this, open include\lowlevel\lcd.h, find this section:

      sub LCDWriteByte(LCDByte) #NR

      #IFDEF LCD_IO 4,8
      wait until LCDReady
      set LCD_RW OFF 'Write mode
      #ENDIF

      and replace it with:

      sub LCDWriteByte(LCDByte) #NR

      #IFDEF LCD_IO 4,8
      Set LED On
      wait until LCDReady
      Set LED Off
      set LCD_RW OFF 'Write mode
      #ENDIF

      where LED is some output pin. If the pin stays on, then there is some problem with reading back the LCD status.

       
    • Nobody/Anonymous

      No it is the very same 4x20 display in both cases. I will try your suggestion.

       
    • Nobody/Anonymous

      I have tested LCDbusy, as you suggested, and it is working fine. I have written assembly code for an LCD before and I know they are very sensitive to timing. I looked closely at the library and I can't see anything obvious. I have also looked at the assembly code from the Pic_Sim_Ide from Oshonsoft, which is working. The only difference that I see, is that in the LCDWriteByte routine he checks busy at the end, not at the beginning of the routine.

       

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.