Problems with 16F88 & 2 Wire LCD (Assembly Language)

Discussion in 'Embedded Systems and Microcontrollers' started by icedtea, Aug 28, 2010.

  1. icedtea

    Thread Starter New Member

    Aug 28, 2010
    10
    0
    Hello Everyone!

    I recently started using PIC microcontollers for a project that I want to complete. I found the 2 Wire LCD program and schematic by Mike Predko at http://www.rentron.com/Myke1.htm The assembly code was written for the PIC16C84 and thought that I might be able to port it over to the PIC16F88 instead. I've been trying everything that I can and hunting through the online forums for any clue that might help me get it operational.

    If anyone would be so kind to look over the code that has been modified from the original, unsuccessfully. :(

    I know it has been done by someone else using the C language, however, I'm liking the assembly language and how easy it is to compile it into the .HEX file. The page with the C language code is located at: http://ghmicro.com/index.php?option...cd-interface&catid=6:16f88&Itemid=2&showall=1 if this helps at all.

    The .asm file has been attached as a .txt document and the code has also been copied below:

    Code ( (Unknown Language)):
    1.  
    2. ;  Using 2WireLCD to write messages to LCD Screen
    3. ;   - 4 Bit Mode
    4. ;   - Data is shifted out to a 74LS174 with The High Order Bit being a "Gate"
    5. ;    Bit connected to the LCD's "E" line.  The next Highest Bit goes to the
    6. ;    LCD's "RS" Bit.  The lowest Bit goes to D4 (and each Bit is higher from
    7. ;    there).
    8. ;
    9. ;  Hardware Notes:
    10. ;   - Reset is tied directly to Vcc and PWRT is Enabled.
    11. ;   - The PIC is a 16F88 Running at 4 MHz.
    12. ;   - PortA.0 is the Data Bit
    13. ;   - PortA.1 is the Clock Bit
    14. ;
    15. ;  Shift Data:
    16. ;  Bit 1 - Always High (Gate for "E")
    17. ;  Bit 2 - RS Bit
    18. ;  Bit 3 - LCD D4
    19. ;  Bit 4 - LCD D5
    20. ;  Bit 5 - LCD D6
    21. ;  Bit 6 - LCD D7
    22. ;
    23.   LIST P=16F88, R=DEC          ;  16F88 Decimal
    24.   errorlevel 0,-305
    25.   INCLUDE "P16F88.inc"
    26.  
    27. ;  Register Usage
    28.  CBLOCK 0x00C       ;  Start Registers at End of the Values
    29. Dlay             ;  8 Bit Delay Variable
    30. Temp           ;  Temporary Value Used When Sending Out Data
    31. NOTemp       ;  Temporary Value to "NybbleOutput"
    32. CounterA      ;  Counter Value - For Time Delay Calculations
    33. CounterB      ;  Counter Value - For Time Delay Calculations
    34. CounterC      ;  Counter Value - For Time Delay Calculations
    35. Next2           ;  Don't know why but MPLAB IDE told me I needed this one
    36.  ENDC
    37.  
    38. ;  Define Inforation
    39. #DEFINE Data PORTA,0
    40. #DEFINE Clock PORTA, 1
    41.  
    42. ;  Macros
    43. ClockStrobe MACRO  ;  Strobe the Data Bit
    44.   bsf  Clock
    45.   bcf  Clock
    46.  ENDM
    47.  
    48. EStrobe MACRO   ;  Strobe the "E" Bit
    49.   bsf  Data
    50.   bcf  Data
    51.  ENDM
    52.  
    53.  PAGE
    54.  
    55.  __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO
    56.  __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
    57.  
    58.   org    0
    59.  
    60.   clrf   PORTA
    61.   clrf   PORTB
    62.  
    63.   bsf STATUS, RP0  ; BANK 1
    64.   movlw  b'01100000' ; Set internal osc to 4Mhz
    65.   movwf  OSCCON & 0x7F
    66.   movlw  b'111100'  ; Set PortA 0 & 1 to Digital I/O - Added 8-24-10
    67.   movwf  ANSEL   ; Write the data to ANSEL File - Added 8-24-10
    68.   movlw  0x07       ; Load 7 into W register - Added 8-24-10
    69.   movwf  CMCON    ; CMCON = contents of W register 7h - Added 8-24-10
    70.   movwf  TRISA ^ 0x080
    71.   bcf STATUS, RP0  ; BANK 0
    72.  
    73.   call   Dlay5                  ;  Wait 20 msecs before Reset
    74.   call   Dlay5
    75.   call   Dlay5
    76.   call   Dlay5
    77.  
    78.   bcf    STATUS, C              ;  Clear Carry (Instruction Out)
    79.   movlw  0x03                   ;  Reset Command
    80.   call   NybbleOut              ;  Send the Nybble
    81.   call  Dlay5   ;  Wait 5 msecs before Sending Again
    82.  
    83.   EStrobe
    84.   call  Dlay160  ;  Wait 160 usecs before Sending the Third Time
    85.   EStrobe
    86.   call  Dlay160  ;  Wait 160 usecs before Sending the Third Time
    87.   bcf    STATUS, C              
    88.   movlw  0x02                   ;  Set 4 Bit Mode
    89.   call   NybbleOut              
    90.   call  Dlay160  
    91.   movlw  0x028   ;  Note that it is a 2 Line Display
    92.   call  SendINS
    93.   movlw  0x008   ;  Turn off the Display
    94.   call  SendINS
    95.   movlw  0x001   ;  Clear the Display RAM
    96.   call  SendINS
    97.   call  Dlay5   ;  Note, Can take up to 4.1 msecs
    98.   movlw  0x006   ;  Enable Cursor Move Direction
    99.   call  SendINS
    100.   movlw  0x00C   ;  Turn the LCD Back On
    101.   call  SendINS
    102.  
    103. ;----------------------------------------------------------------------
    104. ;OutPut Message Screen 1 Line 1
    105.   call   OutLoopA
    106.   call   IntroMessageLine1
    107.   call   OutLoopC
    108.  
    109. ;----------------------------------------------------------------------
    110. ;Delay 1 Second Before Displaying Screen 1 Line 2
    111. Next1    ;  Next Line
    112.   call   Delay1s  ;  1 Second Delay
    113.   movlw  0x0C0   ;  Move to Next Line on LCD
    114.   call  SendINS
    115.  
    116. ;----------------------------------------------------------------------
    117. ;OutPut Message Screen 1 Line 2
    118.   call   OutLoopA
    119.   call   IntroMessageLine2
    120.   call   OutLoopC
    121.  
    122. ;----------------------------------------------------------------------
    123. ;Delay 4 Seconds Before Clearing LCD Screen and Displaying Next Screen
    124. Next4     ;  4 Second Delay Loop
    125.   call   Delay1s  ;  1 Second Delay
    126.   call   Delay1s  ;  + 1 Second Delay = 2 Second Delay
    127.   call   Delay1s  ;  + 1 Second Delay = 3 Second Delay
    128.   call   Delay1s  ;  + 1 Second Delay = 4 Second Delay (5 Seconds Total)
    129.  
    130. ;----------------------------------------------------------------------
    131. ;Display Program 1 Screen Line 1
    132.   call   ClearDR
    133.   call   OutLoopA
    134.   call   Prog1Line1
    135.   call   OutLoopC
    136.  
    137. ;----------------------------------------------------------------------
    138. ;Display Program 1 Screen Line 2
    139.   call   OutLoopA
    140.   call   Prog1Line2
    141.   call   OutLoopC
    142. Loop123
    143.   goto  Loop123    ;Loop forever until code development continues...
    144.  
    145. ;----------------------------------------------------------------------
    146. ;Output Loops for Sending Text to LCD Screen
    147. OutLoopA
    148.   clrf  FSR   ;  Output the Message
    149. OutLoopB
    150.   movf  FSR, w   ;  Get the Offset to Output
    151.   incf  FSR
    152.   return
    153. OutLoopC
    154.   iorlw  0   ;  At the End of the Line?
    155.   btfsc  STATUS, Z
    156.   goto  NextLn   ;  Yes - Equal to Zero
    157.   call  SendCHAR  ;  Output the ASCII Character
    158.   goto  OutLoopB
    159.   return
    160.  
    161. ;----------------------------------------------------------------------
    162. ;Commands for Clearing LCD Screen & RAM
    163. ClearDR
    164.   movlw  0x001   ;  Clear the Display & RAM
    165.   call  SendINS
    166.   call  Dlay5   ;  Can take up to 4.c1 msecs
    167.   return
    168.  
    169. ;----------------------------------------------------------------------
    170. ;Commands for Moving to the Next Line on the LCD Screen
    171. NextLn    ;  Next Line
    172.   movlw  0x0C0   ;  Move to Next Line on LCD
    173.   call  SendINS
    174.   return
    175.  
    176. ;  Subroutines
    177. ;----------------------------------------------------------------------
    178. IntroMessageLine1  ;  Message to Output
    179.   addwf  PCL   ;  Output the Characters
    180.   dt  "Initializing...", 0
    181.  
    182. ;----------------------------------------------------------------------
    183. ;Commands to Send Characters to LCD Screen
    184. SendCHAR    ;  Send the Character to the LCD
    185.   movwf  Temp   ;  Save the Temporary Value
    186.   swapf  Temp, w  ;  Send the High Nybble
    187.   bsf  STATUS, C  ;  RS = 1
    188.   call  NybbleOut
    189.   movf  Temp, w  ;  Send the Low Nybble
    190.   bsf  STATUS, C
    191.   call  NybbleOut
    192.   return
    193.  
    194. ;----------------------------------------------------------------------
    195. IntroMessageLine2  ;  Message to Output
    196.   addwf  PCL   ;  Output the Characters
    197.   dt     "Loading Menu...", 0
    198.   goto   SendCHAR
    199.  
    200. ;----------------------------------------------------------------------
    201. Prog1Line1   ;  Message to Output
    202.   addwf  PCL   ;  Output the Characters
    203.   dt     "Program #1:", 0
    204.   goto   SendCHAR
    205.  
    206. ;----------------------------------------------------------------------
    207. Prog1Line2
    208.   addwf  PCL   ;  Message to Output
    209.   dt     "Reflex Timing", 0
    210.   goto   SendCHAR
    211.  
    212. ;----------------------------------------------------------------------
    213. ;Commands to Send Instructions to LCD Screen
    214.  
    215. SendINS     ;  Send the Instruction to the LCD
    216.   movwf  Temp   ;  Save the Temporary Value
    217.   swapf  Temp, w  ;  Send the High Nybble
    218.   bcf  STATUS, C  ;  RS = 0
    219.   call  NybbleOut
    220.   movf  Temp, w  ;  Send the Low Nybble
    221.   bcf  STATUS, C
    222.   call  NybbleOut
    223.   return
    224.  
    225. ;----------------------------------------------------------------------
    226. ;Commands to Sending Nibbles to LCD Screen
    227.  
    228. NybbleOut    ;  Send a Nybble to the LCD
    229.   movwf  NOTemp   ;  Save the Nybble to Shift Out
    230.   swapf  NOTemp   ;  Setup to Output to the High Part of the Byte
    231.   movlw  6   ;  Clear the Shift Register
    232.   movwf  Dlay
    233.  
    234. NOLoop1
    235.   ClockStrobe
    236.   decfsz Dlay
    237.    goto  NOLoop1
    238.   bsf  Data   ;  Put out the Gate Bit
    239.   ClockStrobe
    240.   bcf  Data   ;  Put out the RS Bit
    241.   rlf  PORTA
    242.   ClockStrobe
    243.   movlw  4   ;  Now, Shift out the Data
    244.   movwf  Dlay
    245.  
    246. NOLoop2
    247.   rlf  NOTemp   ;  Shift Through the Nybble to Output
    248.   bcf  Data   ;  Clear the Data Bit (which is the Clock)
    249.   rlf  PORTA   ;  Shift the Carry into the Shift Register
    250.   ClockStrobe
    251.   decfsz Dlay
    252.    goto  NOLoop2
    253.   EStrobe   ;  Strobe out the LCD Data
    254.   return
    255.  
    256. ;----------------------------------------------------------------------
    257. Dlay160                         ;  Delay 160 usecs
    258.   movlw  256 - ( 160 / 4 )      ;  Loop Until Carry Set
    259.   addlw  1
    260.   btfss  STATUS, C
    261.    goto  $-2
    262.   return
    263. ;----------------------------------------------------------------------
    264. Dlay5                           ;  Delay 5 msecs
    265.   movlw  4                      ;  Set up the Delay
    266.   movwf  Dlay
    267.   movlw  256 - 0x0E8
    268.   addlw  1
    269.   btfsc  STATUS, Z
    270.    decfsz Dlay
    271.     goto $-3
    272.   return
    273. ;----------------------------------------------------------------------
    274. Delay1s    ;  Delay Loop for 1 Second
    275.   movlw  6
    276.   movwf  CounterC
    277.   movlw  24
    278.   movwf  CounterB
    279.   movlw  167
    280.   movwf  CounterA
    281. loop  decfsz  CounterA,1
    282.   goto  loop
    283.   decfsz  CounterB,1
    284.   goto loop
    285.   decfsz  CounterC,1
    286.   goto  loop
    287.   return
    288. ;----------------------------------------------------------------------
    289.   end
    290.  
    Thanks for any insights you might be able to provide. I really, really appreciate it!
    Jared
     
  2. eblc1388

    Senior Member

    Nov 28, 2008
    1,542
    102
    When porting codes from one PIC into another, one needs to take care of the general purpose registers(GPR) locations as newer PICs usually have more user registers but in different area of the memory map.

    This by far is the most common gotcha concerning porting 16F84 codes into newer PICs.

    Are you sure that the user GPR in 16F88 starts at 0x0C?

    [​IMG]
     
  3. icedtea

    Thread Starter New Member

    Aug 28, 2010
    10
    0
    I did have the register location wrong like you pointed out. I changed this in the file and tried again but still, no luck with displaying anything but two symbols and two blocks (this is as far as I've ever gotten within the last three weeks). I'm not sure what I should do but am considering scrapping the 88 and switch to another PIC microcontroller that isn't as complicated as this one though I'd hate to do that.
     
  4. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    After a quick glance at your code I wonder if using the rlf PORTA instructions might be a problem?

    Does your Predko interface look anything like mine (below)?
     
  5. retched

    AAC Fanatic!

    Dec 5, 2009
    5,201
    312
    It looks close, but it doesn't have the pink gradient in the back. ;)
     
  6. elementalrage

    Active Member

    Jul 30, 2009
    59
    3
    Are you using an external crystal or internal clock? Many 16x2 LCDs, that I have used, won't work 100% with the internal clock...

    The 16F88 is an awesome chip! Many tutorials were created using that chip.
     
  7. icedtea

    Thread Starter New Member

    Aug 28, 2010
    10
    0
    Update: I have finally got something to work. I used an 8-bit interface (11 pins used total) and a PIC16F54. Since this one does not have an internal oscillator I used a 20 MHz crystal hoping it would work. It seems to work perfectly!

    The problem, however, is that the 16F54 has limited programming space to accomplish what I'm trying to do. Since this is working, I thought I'd try to get it to work on the 16F88 but am STILL running into problems.

    I understand that this chip has a default configuration on PortA which needs to be turned off using the ANSEL register and also to turn the comparators off via the CMCON register.

    Here is the 16F54 code that works:
    Code ( (Unknown Language)):
    1.  
    2.     LIST P=16F54, F=INHX8M
    3.     Include <P16F5X.inc>
    4.     __CONFIG _CP_OFF & _WDT_OFF & _HS_OSC
    5.  
    6. ; Equates, I/O, vars
    7. RESET_V        EQU    0x0000        ; Address of RESET Vector
    8. ISR_V        EQU    0x0004        ; Address of Interrupt Vector
    9. OSC_FREQ    EQU    D'20000000'    ; Oscillator Frequency = 20 MHz
    10.  
    11. LCD_DATA    EQU    PORTB        ; LCD data lines
    12. LCD_CTRL    EQU    PORTA        ; LCD control lines
    13.  
    14. LCD_LINE0    EQU    0x000
    15. LCD_LINE1    EQU    0x040
    16.  
    17. ; PORTA Bits
    18. LCD_E        EQU    2        ; LCD Enable control line
    19. LCD_RW        EQU    1        ; LCD Read/Write control line
    20. LCD_RS        EQU    0        ; LCD Register-Select control line
    21.  
    22. ; PORTB Bits
    23. DB7        EQU    7        ; LCD dataline 7 (MSB)
    24. DB6        EQU    6
    25. DB5        EQU    5
    26. DB4        EQU    4
    27. DB3        EQU    3
    28. DB2        EQU    2
    29. DB1        EQU    1
    30. DB0        EQU    0        ; LCD dataline 0 (LSB)
    31.  
    32. ; Miscellaneous
    33. LCD_TEMP    EQU    0x007        ; LCD subroutines internal use
    34. TABLE_INDEX    EQU    0x008        ; Index to table strings
    35. DELAY        EQU    0x009        ; Used in DELAYxxx routines
    36. X_DELAY        EQU    0x00A        ; Used in X_DELAYxxx routines
    37. T1        EQU    0x00B        ; Delay Variables
    38. T2        EQU    0x00C
    39. T3        EQU    0x00D
    40.  
    41. ; Program start
    42.     ORG    RESET_V            ; RESET vector location
    43. RESET        GOTO    START
    44.  
    45. ; Initialize processor registers
    46.  
    47. START                    ; POWER_ON Reset (Beginning of program)
    48.         CLRF    STATUS        ; Do initialization, Select bank 0
    49.         CLRF    PORTA        ; ALL PORT output should output Low.
    50.         CLRF    PORTB
    51.  
    52.         MOVLW    0x0F8        ; RA2-0 outputs, RA4-3 inputs
    53.         TRIS    PORTA
    54.         MOVLW    0x000        ; RB7-0 outputs
    55.         TRIS    PORTB
    56.  
    57. ; LCDINIT - Initialize LCD Display
    58.  
    59.                     ; Busy-flag is not yet valid
    60.         CLRF    LCD_CTRL    ; ALL PORT output should output Low.
    61.         MOVLW    0x028        ; Power-up Delay
    62.         MOVWF    X_DELAY        ; +1    1 cycle
    63. X_DELAY500_LOOP
    64.         CALL    DELAY500    ; Step1    Wait 500uSec
    65.         DECFSZ    X_DELAY, F    ; Step2    1 Cycle
    66.         GOTO    X_DELAY500_LOOP    ; Step3    2 Cycles
    67.         NOP
    68.         NOP
    69.                     ; Busy Flag should be valid from here
    70.         MOVLW    0x038        ; 8-bit-interface, 2-lines
    71.         CALL    LCDPUTCMD
    72.         MOVLW    0x000        ; Display Off, Cursor Off, No-Blink
    73.         ANDLW    0x007        ; Strip upper bits
    74.         IORLW    0x008        ; Function set
    75.         CALL    LCDPUTCMD
    76.         MOVLW    0x001
    77.         CALL    LCDPUTCMD
    78.         MOVLW    0x004        ; Display On, Cursor Off
    79.         ANDLW    0x007        ; Strip upper bits
    80.         IORLW    0x008        ; Function set
    81.         CALL    LCDPUTCMD
    82.         MOVLW    0x002        ; Auto-Increment (Shift-Cursor)
    83.         ANDLW    0x003        ; Strip upper bits
    84.         IORLW    0x004        ; Function set
    85.         CALL    LCDPUTCMD
    86.  
    87. ; Display - Line0:|Welcome Message | & Line1:|Wait 4 seconds..|
    88.         CALL    Delay1S
    89.  
    90.         MOVLW    LCD_LINE0    ; Position Cursor Leftmost on 1st Line        
    91.         IORLW    0x080        ; Function set
    92.         CALL    LCDPUTCMD
    93.                         ; TABLE_MSG - Display Message
    94.         MOVLW    0        ; Startindex of table message
    95. DISP_MSG1
    96.         MOVWF    TABLE_INDEX    ; Holds message address
    97.         CALL    MSG1
    98.         ANDLW    0x0FF        ; Check if at end of message
    99.         BTFSC    STATUS, Z    ; (Zero returned at end)
    100.         GOTO    TABLE_MSG_END1            
    101.                             ; LCDPUTCHAR - Display Character
    102.         MOVWF    LCD_TEMP    ; Character to be sent is in W
    103.                             ; LCDBUSY - Wait for LCD to be ready
    104. LCDBUSY1
    105.         MOVLW    0x0FF            ; Set PORTB for input
    106.         TRIS    PORTB    
    107.         BCF        LCD_CTRL, LCD_RS; Set LCD for command mode
    108.         BSF        LCD_CTRL, LCD_RW; Setup to read busy flag
    109.         BSF        LCD_CTRL, LCD_E    ; LCD E-line High
    110.         MOVF    LCD_DATA, W        ; Read busy flag + DDram address
    111.         BCF        LCD_CTRL, LCD_E    ; LCD E-line Low
    112.         ANDLW    0x80            ; Check Busy flag, High = Busy
    113.         BTFSS    STATUS, Z
    114.         GOTO    LCDBUSY1
    115. LCDNOTBUSY1
    116.         BCF    LCD_CTRL, LCD_RW
    117.         MOVLW    0x000
    118.         TRIS    PORTB        ; Set PORTB for output
    119.  
    120.         BCF    LCD_CTRL, LCD_RW; Set LCD in read mode
    121.         BSF    LCD_CTRL, LCD_RS; Set LCD in data mode
    122.         BSF    LCD_CTRL, LCD_E    ; LCD E-line High
    123.         MOVF    LCD_TEMP, W
    124.         MOVWF    LCD_DATA    ; Send data to LCD
    125.         BCF    LCD_CTRL, LCD_E    ; LCD E-line Low
    126.  
    127.         MOVF    TABLE_INDEX, W    ; Point to next character
    128.         INCF    TABLE_INDEX, W
    129.         GOTO    DISP_MSG1
    130. TABLE_MSG_END1
    131.  
    132. ; 1 Second Delay
    133.         CALL    Delay1S
    134.  
    135.         MOVLW    LCD_LINE1
    136.         IORLW    0x080        ; Function set
    137.         CALL    LCDPUTCMD
    138.                             ; TABLE_MSG
    139.         MOVLW    0            ; Startindex of table message
    140. DISP_MSG2
    141.         MOVWF    TABLE_INDEX    ; Holds message address
    142.         CALL    MSG2
    143.         ANDLW    0x0FF        ; Check if at end of message
    144.         BTFSC    STATUS, Z    ; (zero returned at end)
    145.         GOTO    TABLE_MSG_END2            
    146.                             ; LCDPUTCHAR - Display Character
    147.         MOVWF    LCD_TEMP    ; Character to be sent is in W
    148. LCDBUSY3
    149.         MOVLW    0x0FF        ; Set PORTB for input
    150.         TRIS    PORTB    
    151.         BCF    LCD_CTRL, LCD_RS; Set LCD for command mode
    152.         BSF    LCD_CTRL, LCD_RW; Setup to read busy flag
    153.         BSF    LCD_CTRL, LCD_E    ; LCD E-line High
    154.         MOVF    LCD_DATA, W    ; Read busy flag + DDram address
    155.         BCF    LCD_CTRL, LCD_E    ; LCD E-line Low
    156.         ANDLW    0x80        ; Check Busy flag, High = Busy
    157.         BTFSS    STATUS, Z
    158.         GOTO    LCDBUSY3
    159. LCDNOTBUSY3
    160.         BCF    LCD_CTRL, LCD_RW
    161.         MOVLW    0x000
    162.         TRIS    PORTB        ; Set PORTB for output
    163.  
    164.         BCF    LCD_CTRL, LCD_RW; Set LCD in read mode
    165.         BSF    LCD_CTRL, LCD_RS; Set LCD in data mode
    166.         BSF    LCD_CTRL, LCD_E    ; LCD E-line High
    167.         MOVF    LCD_TEMP, W
    168.         MOVWF    LCD_DATA    ; Send data to LCD
    169.         BCF    LCD_CTRL, LCD_E    ; LCD E-line Low
    170.  
    171.         MOVF    TABLE_INDEX, W    ; Point to next character
    172.         INCF    TABLE_INDEX, W
    173.         GOTO    DISP_MSG2
    174. TABLE_MSG_END2
    175.  
    176. ; 4 Second Delay
    177.         CALL    Delay1S
    178.         CALL    Delay1S
    179.         CALL    Delay1S
    180.         CALL    Delay1S
    181.  
    182.         MOVLW    0x001        ; LCDCLEAR
    183.         CALL    LCDPUTCMD
    184.  
    185. ; Program Ends Here
    186. LOOP
    187.         GOTO    LOOP        ; Loop forever
    188.  
    189. LCDPUTCMD
    190.         MOVWF    LCD_TEMP    ; Command to be sent is in W
    191. LCDBUSY
    192.         MOVLW    0x0FF        ; Set PORTB for input
    193.         TRIS    PORTB    
    194.         BCF    LCD_CTRL, LCD_RS; Set LCD for command mode
    195.         BSF    LCD_CTRL, LCD_RW; Setup to read busy flag
    196.         BSF    LCD_CTRL, LCD_E    ; LCD E-line High
    197.         MOVF    LCD_DATA, W    ; Read busy flag + DDram address
    198.         BCF    LCD_CTRL, LCD_E    ; LCD E-line Low
    199.         ANDLW    0x80        ; Check Busy flag, High = Busy
    200.         BTFSS    STATUS, Z
    201.         GOTO    LCDBUSY
    202. LCDNOTBUSY
    203.         BCF    LCD_CTRL, LCD_RW
    204.         MOVLW    0x000
    205.         TRIS    PORTB        ; Set PORTB for output
    206.         BCF    LCD_CTRL, LCD_RW; Set LCD in read mode
    207.         BCF    LCD_CTRL, LCD_RS; Set LCD in command mode
    208.         BSF    LCD_CTRL, LCD_E    ; LCD E-line High
    209.         MOVF    LCD_TEMP, W
    210.         MOVWF    LCD_DATA    ; Send data to LCD
    211.         BCF    LCD_CTRL, LCD_E    ; LCD E-line Low
    212.         RETLW    0
    213.  
    214. ; 500 uSecond Delay Routine
    215.  
    216. DELAY500                    ;2493 cycles
    217.     movlw    0xF2
    218.     movwf    T1
    219.     movlw    0x02
    220.     movwf    T2
    221. Delay500_0
    222.     decfsz    T1, f
    223.     goto    $+2
    224.     decfsz    T2, f
    225.     goto    Delay500_0
    226.     goto    $+1                ;3 cycles
    227.     nop
    228.     retlw    0                ;4 cycles (including call)
    229.  
    230. ; 1 Second Delay Routine @ Clock frequency = 20 MHz
    231.  
    232. Delay1S                        ; 4999993 Cycles
    233.     movlw    0x2C
    234.     movwf    T1
    235.     movlw    0xE7
    236.     movwf    T2
    237.     movlw    0x0B
    238.     movwf    T3
    239. Delay1S_0
    240.     decfsz    T1, f
    241.     goto    $+2
    242.     decfsz    T2, f
    243.     goto    $+2
    244.     decfsz    T3, f
    245.     goto    Delay1S_0
    246.     goto    $+1                ; 3 Cycles
    247.     nop
    248.     retlw    0                ; 4 Cycles (including call)
    249.  
    250. ; Table Messages to Display
    251. MSG1
    252.         addwf    PCL ,F        ;Jump to char pointed to in W reg
    253.         retlw    'W'
    254.         retlw    'e'
    255.         retlw    'l'
    256.         retlw    'c'
    257.         retlw    'o'
    258.         retlw    'm'
    259.         retlw    'e'
    260.         retlw    ' '
    261.         retlw    'M'
    262.         retlw    'e'
    263.         retlw    's'
    264.         retlw    's'
    265.         retlw    'a'
    266.         retlw    'g'
    267.         retlw    'e'
    268.         retlw    0
    269.  
    270. MSG2
    271.         addwf    PCL ,F        ;Jump to char pointed to in W reg
    272.         retlw    'W'
    273.         retlw    'a'
    274.         retlw    'i'
    275.         retlw    't'
    276.         retlw    ' '
    277.         retlw    '4'
    278.         retlw    ' '
    279.         retlw    's'
    280.         retlw    'e'
    281.         retlw    'c'
    282.         retlw    'o'
    283.         retlw    'n'
    284.         retlw    'd'
    285.         retlw    's'
    286.         retlw    '.'
    287.         retlw    '.'
    288.         retlw    0
    289.  
    290.     END                ; End of Program (Required)
    291.  
     
    • LCD.jpg
      LCD.jpg
      File size:
      104.2 KB
      Views:
      82
  8. icedtea

    Thread Starter New Member

    Aug 28, 2010
    10
    0
    The code that has been modified, yet does not yet work:
    Code ( (Unknown Language)):
    1.  
    2.     LIST P=16F88, F=INHX8M
    3.     Include <P16F88.inc>
    4.     ERRORLEVEL  -302
    5.     __CONFIG    _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_OFF & _WDT_OFF & _HS_OSC
    6.     __CONFIG    _CONFIG2, _IESO_OFF & _FCMEN_OFF
    7.  
    8. ; Equates, I/O, vars
    9.  
    10. RESET_V        EQU    0x0000     ; Address of RESET Vector
    11. OSC_FREQ    EQU    D'20000000' ; Osc. Frequency = 20 MHz
    12.  
    13. LCD_DATA    EQU    PORTB    ; LCD data lines
    14. LCD_CTRL    EQU    PORTA    ; LCD control lines
    15.  
    16. LCD_LINE0    EQU    0x000
    17. LCD_LINE1    EQU    0x040
    18.  
    19. ; PORTA Bits
    20. LCD_E        EQU    2     ; LCD Enable control line
    21. LCD_RW        EQU    1   ; LCD Read/Write control line
    22. LCD_RS        EQU    0   ; LCD Register-Select control line
    23.  
    24. ; PORTB Bits
    25. DB7        EQU    7 ; LCD dataline 7 (MSB)
    26. DB6        EQU    6
    27. DB5        EQU    5
    28. DB4        EQU    4
    29. DB3        EQU    3
    30. DB2        EQU    2
    31. DB1        EQU    1
    32. DB0        EQU    0 ; LCD dataline 0 (LSB)
    33.  
    34. ; Miscellaneous
    35.     CBLOCK    0x020
    36. LCD_TEMP
    37. TABLE_INDEX
    38. DELAY     ; DELAYxxx routines
    39. X_DELAY  ; X_DELAYxxx routines
    40. T1          ; Delay Variables
    41. T2
    42. T3
    43.     ENDC
    44.  
    45. ; Program start
    46.  
    47.     ORG    RESET_V
    48. RESET        GOTO    START
    49.  
    50. ; Initialize Processor Registers
    51. START
    52.     clrf    STATUS
    53.     clrf    PORTA
    54.     clrf    PORTB
    55.     movlw  0x000
    56.     banksel TRISA    
    57.     movwf  TRISA
    58.     banksel TRISB
    59.     movwf  TRISB
    60.     banksel ANSEL
    61.     clrf ANSEL        ; Set Port A to Digital I/O
    62.     MOVLW    0x007
    63.     BANKSEL    CMCON
    64.     MOVWF    CMCON  ; Turn OFF Comparators
    65.  
    66.     banksel OSCCON
    67.     bsf    OSCCON, IRCF2  ; Set 8 MHz clock (Back-up if Ext Osc fails)
    68.     bsf    OSCCON, IRCF1
    69.     bsf    OSCCON, IRCF0
    70.                 ; STABL    BTFSS    OSCCON,IOFS
    71.                 ; GOTO    STABL
    72.     bcf    OSCCON,SCS1        ; Oscillator Mode Defined by FOSC<2:0>
    73.     bcf    OSCCON,SCS0
    74.  
    75.     banksel    INTCON
    76. KILLINT    BCF    INTCON,7   ; Turn GIE OFF
    77.         BTFSC    INTCON,7    ; GIE is really OFF?
    78.         GOTO    KILLINT
    79.  
    80.     banksel    TRISA
    81.     MOVLW    0x0F8    ; RA2-0 outputs, RA4-3 inputs
    82.     MOVWF    TRISA    
    83.     banksel    TRISB
    84.     MOVLW    0x000    ; RB7-0 outputs
    85.     MOVWF    TRISB
    86.  
    87.     banksel PORTA
    88.  
    89.     CLRF PORTA
    90.     CLRF PORTB
    91.  
    92. ; LCDINIT
    93.         CLRF    LCD_CTRL  ; ALL PORT output should be low
    94.         MOVLW    0x028    ; Power-up Delay
    95.         MOVWF    X_DELAY
    96. X_DELAY500_LOOP
    97.         CALL    DELAY500   ; Wait 500uSec
    98.         DECFSZ    X_DELAY, F
    99.         GOTO    X_DELAY500_LOOP
    100.         NOP
    101.         NOP
    102.  
    103.         MOVLW    0x038        ; 8-bit-interface, 2-lines
    104.         CALL    LCDPUTCMD
    105.         MOVLW    0x000        ; Display & Cursor Off, No-Blink
    106.         ANDLW    0x007        ; Strip upper bits
    107.         IORLW    0x008        ; Function (F(x)) set
    108.         CALL    LCDPUTCMD
    109.         MOVLW    0x001
    110.         CALL    LCDPUTCMD
    111.         MOVLW    0x004        ; Display On, Cursor Off
    112.         ANDLW    0x007        ; Strip upper bits
    113.         IORLW    0x008        ; F(x) set
    114.         CALL    LCDPUTCMD
    115.         MOVLW    0x002        ; Auto-Increment (Shift-Cursor)
    116.         ANDLW    0x003        ; Strip upper bits
    117.         IORLW    0x004        ; F(x) set
    118.         CALL    LCDPUTCMD
    119.  
    120. ; Display: Line0: |Welcome Message | & Line1: |Wait 4 seconds..|
    121.  
    122.         CALL    Delay1S
    123.         MOVLW    LCD_LINE0    ; Position Cursor Home        
    124.         IORLW    0x080        ; F(x) set
    125.         CALL    LCDPUTCMD
    126. ; TABLE_MSG - Display Message
    127.         MOVLW    0        ; Startindex of table message
    128. DISP_MSG1
    129.         MOVWF    TABLE_INDEX  ; Holds message address
    130.         CALL    MSG1
    131.         ANDLW    0x0FF  ; At end of message?
    132.         BTFSC    STATUS, Z    ; (Zero returned at end)
    133.         GOTO    TABLE_MSG_END1            
    134. ; LCDPUTCHAR - Display Character
    135.         MOVWF    LCD_TEMP    ; Character to be sent is in W
    136. ; LCDBUSY - Wait for LCD to be ready
    137. LCDBUSY1
    138.         MOVLW    0x0FF            ; Set PORTB for input
    139.         BSF        STATUS,RP0
    140.         MOVWF    TRISB
    141.         BCF        STATUS,RP0
    142.         BCF        LCD_CTRL, LCD_RS; Set LCD for command mode
    143.         BSF        LCD_CTRL, LCD_RW; Setup to read busy flag
    144.         BSF        LCD_CTRL, LCD_E    ; LCD E-line High
    145.         MOVF    LCD_DATA, W    ; Read busy flag + DDram address
    146.         BCF        LCD_CTRL, LCD_E    ; LCD E-line Low
    147.         ANDLW    0x80  ; Check Busy flag, High = Busy
    148.         BTFSS    STATUS, Z
    149.         GOTO    LCDBUSY1
    150. LCDNOTBUSY1
    151.         BCF    LCD_CTRL, LCD_RW
    152.         MOVLW    0x000
    153.         BSF        STATUS,RP0
    154.         MOVWF    TRISB        ; Set PORTB for output
    155.         BCF        STATUS,RP0
    156.  
    157.         BCF    LCD_CTRL, LCD_RW; Set LCD in read mode
    158.         BSF    LCD_CTRL, LCD_RS; Set LCD in data mode
    159.         BSF    LCD_CTRL, LCD_E    ; LCD E-line High
    160.         MOVF    LCD_TEMP, W
    161.         MOVWF    LCD_DATA    ; Send data to LCD
    162.         BCF    LCD_CTRL, LCD_E   ; LCD E-line Low
    163.  
    164.         MOVF    TABLE_INDEX, W   ; Point to next character
    165.         INCF    TABLE_INDEX, W
    166.         GOTO    DISP_MSG1
    167. TABLE_MSG_END1
    168.  
    169. ; 1 Second Delay
    170.         CALL    Delay1S
    171.  
    172.         MOVLW    LCD_LINE1
    173.         IORLW    0x080        ; F(x) set
    174.         CALL    LCDPUTCMD
    175. ; TABLE_MSG
    176.         MOVLW    0    ; Startindex of table message
    177. DISP_MSG2
    178.         MOVWF    TABLE_INDEX  ; Holds message address
    179.         CALL    MSG2
    180.         ANDLW    0x0FF    ; At end of message?
    181.         BTFSC    STATUS, Z
    182.         GOTO    TABLE_MSG_END2            
    183. ; LCDPUTCHAR - Display Character
    184.         MOVWF    LCD_TEMP  ; Character to be sent is in W
    185. LCDBUSY2
    186.         MOVLW    0x0FF        ; Set PORTB for input
    187.         BSF        STATUS,RP0
    188.         MOVWF    TRISB
    189.         BCF        STATUS,RP0
    190.  
    191.         BCF    LCD_CTRL, LCD_RS; Set LCD for command mode
    192.         BSF    LCD_CTRL, LCD_RW; Setup to read busy flag
    193.         BSF    LCD_CTRL, LCD_E    ; LCD E-line High
    194.         MOVF    LCD_DATA, W    ; Read busy flag + DDram address
    195.         BCF    LCD_CTRL, LCD_E    ; LCD E-line Low
    196.         ANDLW    0x80        ; Check Busy flag, High = Busy
    197.         BTFSS    STATUS, Z
    198.         GOTO    LCDBUSY2
    199. LCDNOTBUSY2
    200.         BCF    LCD_CTRL, LCD_RW
    201.         MOVLW    0x000
    202.         BSF        STATUS,RP0
    203.         MOVWF    TRISB        ; Set PORTB for output
    204.         BCF        STATUS,RP0
    205.  
    206.         BCF    LCD_CTRL, LCD_RW; Set LCD in read mode
    207.         BSF    LCD_CTRL, LCD_RS; Set LCD in data mode
    208.         BSF    LCD_CTRL, LCD_E    ; LCD E-line High
    209.         MOVF    LCD_TEMP, W
    210.         MOVWF    LCD_DATA    ; Send data to LCD
    211.         BCF    LCD_CTRL, LCD_E    ; LCD E-line Low
    212.  
    213.         MOVF    TABLE_INDEX, W    ; Point to next character
    214.         INCF    TABLE_INDEX, W
    215.         GOTO    DISP_MSG2
    216. TABLE_MSG_END2
    217.  
    218. ; 4 Second Delay
    219.         CALL    Delay1S
    220.         CALL    Delay1S
    221.         CALL    Delay1S
    222.         CALL    Delay1S
    223. ; LCDCLEAR
    224.         MOVLW    0x001
    225.         CALL    LCDPUTCMD
    226.  
    227. ; Program Ends Here (Loops Forever)
    228. LOOP
    229.         GOTO    LOOP
    230.  
    231. LCDPUTCMD
    232.         MOVWF    LCD_TEMP    ; Command to be sent is in W
    233. LCDBUSY
    234.         MOVLW    0x0FF        ; Set PORTB for input
    235.         MOVWF    TRISB    
    236.         BCF    LCD_CTRL, LCD_RS; Set LCD for command mode
    237.         BSF    LCD_CTRL, LCD_RW; Setup to read busy flag
    238.         BSF    LCD_CTRL, LCD_E    ; LCD E-line High
    239.         MOVF    LCD_DATA, W    ; Read busy flag + DDram address
    240.         BCF    LCD_CTRL, LCD_E    ; LCD E-line Low
    241.         ANDLW    0x80        ; Check Busy flag, High = Busy
    242.         BTFSS    STATUS, Z
    243.         GOTO    LCDBUSY
    244. LCDNOTBUSY
    245.         BCF    LCD_CTRL, LCD_RW
    246.         MOVLW    0x000
    247.         MOVWF    TRISB        ; Set PORTB for output
    248.         BCF    LCD_CTRL, LCD_RW; Set LCD in read mode
    249.         BCF    LCD_CTRL, LCD_RS; Set LCD in command mode
    250.         BSF    LCD_CTRL, LCD_E    ; LCD E-line High
    251.         MOVF    LCD_TEMP, W
    252.         MOVWF    LCD_DATA    ; Send data to LCD
    253.         BCF    LCD_CTRL, LCD_E    ; LCD E-line Low
    254.         RETLW    0
    255.  
    256. ; 500 uSecond Delay Routine
    257.  
    258. DELAY500                    ;2493 cycles
    259.     movlw    0xF2
    260.     movwf    T1
    261.     movlw    0x02
    262.     movwf    T2
    263. Delay500_0
    264.     decfsz    T1, f
    265.     goto    $+2
    266.     decfsz    T2, f
    267.     goto    Delay500_0
    268.     goto    $+1                ;3 cycles
    269.     nop
    270.     retlw    0                ;4 cycles (including call)
    271.  
    272. ; 1 Second Delay Routine @ Clock frequency = 20 MHz
    273.  
    274. Delay1S                        ; 4999993 Cycles
    275.     movlw    0x2C
    276.     movwf    T1
    277.     movlw    0xE7
    278.     movwf    T2
    279.     movlw    0x0B
    280.     movwf    T3
    281. Delay1S_0
    282.     decfsz    T1, f
    283.     goto    $+2
    284.     decfsz    T2, f
    285.     goto    $+2
    286.     decfsz    T3, f
    287.     goto    Delay1S_0
    288.     goto    $+1                ; 3 Cycles
    289.     nop
    290.     retlw    0                ; 4 Cycles (including call)
    291.  
    292. ; Table messages to display
    293. MSG1
    294.         addwf    PCL ,F        ;Jump to char pointed to in W reg
    295.         retlw    'W'
    296.         retlw    'e'
    297.         retlw    'l'
    298.         retlw    'c'
    299.         retlw    'o'
    300.         retlw    'm'
    301.         retlw    'e'
    302.         retlw    ' '
    303.         retlw    'M'
    304.         retlw    'e'
    305.         retlw    's'
    306.         retlw    's'
    307.         retlw    'a'
    308.         retlw    'g'
    309.         retlw    'e'
    310.         retlw    0
    311.  
    312. MSG2
    313.         addwf    PCL ,F        ;Jump to char pointed to in W reg
    314.         retlw    'W'
    315.         retlw    'a'
    316.         retlw    'i'
    317.         retlw    't'
    318.         retlw    ' '
    319.         retlw    '4'
    320.         retlw    ' '
    321.         retlw    's'
    322.         retlw    'e'
    323.         retlw    'c'
    324.         retlw    'o'
    325.         retlw    'n'
    326.         retlw    'd'
    327.         retlw    's'
    328.         retlw    '.'
    329.         retlw    '.'
    330.         retlw    0
    331.  
    332.     END                ; End of program
    333.  
    334.  
    I've read some of the datasheet for this particular chip, however, there is more over 200 pages to read through. It would be easier to read up on the answers if I had some idea of what the problem is - but I'm stuck without knowing what I need to even check on.

    Thanks for any ideas you might have. Your suggestions have helped getting some parts of the code right but there is more work to be done.
     
  9. wannaBinventor

    Member

    Apr 8, 2010
    179
    4
    Have you stepped through the code in MPLAB and confirmed that the registers are behaving like you expect them to?
     
  10. icedtea

    Thread Starter New Member

    Aug 28, 2010
    10
    0
    Yes, to a point... I can step through until it get's stuck. For instance, it continually loops through the check to see if the internal oscillator is up to speed. Therefore, I 'commented out' that section to check the rest.

    It then 'gets stuck' in the code that checks to see if the LCD display is busy. I suppose this is because the LCD is external hardware. How is MPLAB supposed to know when and if the LCD display's bit is clear (not processing any more commands)?

    The code does work on the 16F54 with the 20 MHz crystal. All I'm doing is trying to set up the same code on the 16F88 with only the changes that should make it work. The changes I've made include:

    1.) Change __CONFIG settings to those required by the 16F88
    2.) Clear ANSEL Register (Digital I/O) on Port A
    3.) Turn Comparators off on Port A
    4.) Place variables in 0x020 memory area and later as required by the 16F88.

    Still, the code refuses to run with darker squares on Line 0 of the LCD display (top line). I cannot figure this out...:(
     
  11. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    I've spotted a couple of places where banksel TRISB, etc are missing. There could be more.
    You can use the Stimulus window to change port values to get the code further in the simulator, or change the values in the Special Function Registers window.

    Code ( (Unknown Language)):
    1. LCDBUSY
    2.         MOVLW    0x0FF        ; Set PORTB for input
    3.         MOVWF    TRISB    
    4.         BCF    LCD_CTRL, LCD_RS; Set LCD for command mode
    5.         BSF    LCD_CTRL, LCD_RW; Setup to read busy flag
    6.         BSF    LCD_CTRL, LCD_E    ; LCD E-line High
    7.         MOVF    LCD_DATA, W    ; Read busy flag + DDram address
    8.         BCF    LCD_CTRL, LCD_E    ; LCD E-line Low
    9.         ANDLW    0x80        ; Check Busy flag, High = Busy
    10.         BTFSS    STATUS, Z
    11.         GOTO    LCDBUSY
    12. LCDNOTBUSY
    13.         BCF    LCD_CTRL, LCD_RW
    14.         MOVLW    0x000
    15.         MOVWF    TRISB        ; Set PORTB for output

    This bit threw me for a while - it essentially does very little but presumably needs 3 instructions for timing purposes.
    Code ( (Unknown Language)):
    1. MOVLW    0x000        ; Display Off, Cursor Off, No-Blink
    2.         ANDLW    0x007        ; Strip upper bits
    3.         IORLW    0x008        ; Function set
    4.         CALL    LCDPUTCMD
     
  12. icedtea

    Thread Starter New Member

    Aug 28, 2010
    10
    0
    Thanks Markd77!!! I guess I didn't catch them all when I was looking over the code earlier. I'll fix the problems you pointed out and give this a try early this afternoon.

    I think the other section of code is just "stripping the upper bits" so that it doesn't interfere with anything else you are using the other pins on Port A for, i.e. switches, LEDs, etc. Though, I could be wrong. On the 16F54, the program runs flawlessly. It would take too much experimentation for me to fully understand it right now - maybe down the road. Thanks again for your help by pointing the BANKSEL problem out! I'll let you know...
     
  13. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    You can ignore the second section, it's just a little odd:
    movlw 0x00 ;set W to zero
    andlw 0x007 ;W still zero
    iorlw 0x008 ;W still zero
     
  14. icedtea

    Thread Starter New Member

    Aug 28, 2010
    10
    0
    I never got back to everyone but did get the code working on the 16F88. I have since opted to go with a bigger chip, the 16F917 and the 4-bit LCD communication route. Thanks again for all of your help in conquering the 2-wire LCD interface - I really appreciate all of your expertise! :)
     
Loading...