News:

Let's find out together what makes a PIC Tick!

Main Menu

How to connect LCD1602 data pin to random pin MCU by Les

Started by Elektroart, Feb 03, 2021, 08:18 AM

Previous topic - Next topic

Elektroart

Below is a piece of code that will give the ability to use any 4 Port.Pin definitions for the LCD's data lines:

$ifndef _HITACHI_4_INC_
$define _HITACHI_4_INC_
'------------------------------------------------------------------------------------------------
' Replacement routine for the compiler's Print command for an Hitachi alphanumeric LCD
' Using a 4-bit interface where the data pins can be on any port using preprocessor defines:
'
' $define LCD_DTPin4 Port.Bit      ' Choose the Port and Bit for the LCD's D4 line
' $define LCD_DTPin5 Port.Bit      ' Choose the Port and Bit for the LCD's D5 line
' $define LCD_DTPin6 Port.Bit      ' Choose the Port and Bit for the LCD's D6 line
 '$define LCD_DTPin7 Port.Bit      ' Choose the Port and Bit for the LCD's D7 line

    #disable Print                              ' Disable the compiler's print library routine
'
' Create system variables for the routine
'   
    Dim PP0 As Byte System
    Dim PP0H As Byte System
    Dim BPF As Byte System
    Dim PP3 As Byte System
    Dim PP3H As Byte System
'
' Create some aliases to make the code's operation clearer
'
    Symbol Hitachi4_bByteOut = PP3
    Symbol Hitachi4_WREGStore = PP3H
    Symbol Hitachi4_tComOrData = BPF.0
    Symbol Hitachi4_tInitialised = BPF.1
   
'------------------------------------------------------------------------------------------------
    GoTo _Hitachi4_Main_                        ' Jump over the subroutine
'------------------------------------------------------------------------------------------------
Asm-
Print
Endasm-
    Hitachi4_WREGStore = WREG                  ' Save the byte sent
    Low __LCD_ENPORT.__LCD_ENPIN                ' Pull the EN pin to output low
    Low __LCD_RSPORT.__LCD_RSPIN                ' Pull the RS pin to output Low
    Output LCD_DTPin4                          ' \
    Output LCD_DTPin5                          ' | Set the port pins to output
    Output LCD_DTPin6                          ' |
    Output LCD_DTPin7                          ' /

    If Hitachi4_tInitialised = 0 Then          ' Has LCD been inititalised?
        DelayUS 15000                          ' No. So wait 15ms
        Hitachi4_bByteOut = $33                ' Initialise the LCD
        GoSub Hitachi4_NibbleSend              ' Send init
        DelayUS 5000                            ' Wait 5ms
        GoSub Hitachi4_NibbleSend              ' Send init again
        DelayUS 100                            ' Wait 100us
        GoSub Hitachi4_NibbleSend              ' Send init one more time
        DelayUS 100                            ' Wait 100us
        Hitachi4_bByteOut = $22                ' Set 4-bit mode
        GoSub Hitachi4_NibbleSend              ' Set the interface to 4-bit mode
        #ifdef __LCD_LINES                      ' Has the LCD_Lines declare been used in the main program?
            #if(__LCD_LINES == 1)              ' Yes. So...
                WREG = $20                      ' Set for 4-bit mode, 1 line, 5x7 font
            #else
                WREG = $28                      ' Set for 4-bit mode, 2+ lines, 5x7 font
            #endif
        #else                                  ' Otherwise... Default to 2 lines
            WREG = $28                          ' Set for 4-bit mode, 2+ lines, 5x7 font
        #endif
        GoSub Hitachi4_SetCommand              ' Send command
        WREG = $0C                              ' Set for Display on, no cursor, no blink
        GoSub Hitachi4_SetCommand
        WREG = $06                              ' LCD entry mode set, increment, no shift
        GoSub Hitachi4_SetCommand
        Set Hitachi4_tInitialised              ' Indicate that the LCD is initialised
        WREG = Hitachi4_WREGStore              ' Get the saved byte back
        GoTo Hitachi4_Skip
Hitachi4_SetCommand:
        Set Hitachi4_tComOrData                ' Set for command
    EndIf
Hitachi4_Skip:
    Hitachi4_bByteOut = WREG                    ' Get the byte to send from WREG
    If Hitachi4_tComOrData = 1 Then            ' Is it a command this time?
        Clear __LCD_RSPORT.__LCD_RSPIN          ' Yes. So set command register select
        If Hitachi4_bByteOut >= 4 Then Hitachi4_SetData  ' Short delay
        GoSub Hitachi4_SetData                  ' Long delay
        DelayUS __LCD_COMMANDUS                ' Wait for the command to complete     
        Return
    EndIf
    Set Hitachi4_tComOrData                    ' Indicate first nibble, or command next time
    If Hitachi4_bByteOut = $FE Then Hitachi4_Exit  ' Command next time?
    Set __LCD_RSPORT.__LCD_RSPIN                ' Set the RS pin
   
Hitachi4_SetData:
    Swap Hitachi4_bByteOut,Hitachi4_bByteOut    ' Swap top and bottom nibbles
    If Hitachi4_tComOrData = 0 Then            ' First time through only
Hitachi4_NibbleSend:
        Clear Hitachi4_tComOrData              ' Indicate second nibble, and data next time
    EndIf
    Set __LCD_ENPORT.__LCD_ENPIN                ' Enabled
'
' Write the byte to the port
'
    LCD_DTPin4 = Hitachi4_bByteOut.0
    LCD_DTPin5 = Hitachi4_bByteOut.1
    LCD_DTPin6 = Hitachi4_bByteOut.2
    LCD_DTPin7 = Hitachi4_bByteOut.3
    DelayCS 6
    Clear __LCD_ENPORT.__LCD_ENPIN              ' Disabled
    Swap Hitachi4_bByteOut,Hitachi4_bByteOut    ' Move to the other nibble
    DelayCS 6
    If Hitachi4_tComOrData = 1 Then Hitachi4_NibbleSend ' Send the lower 4-bits to the LCD
    DelayUS __LCD_DATAUS                        ' Wait for the data operation to complete 
Hitachi4_Exit:
    WREG = Hitachi4_WREGStore                  ' Return the original byte in WREG
    Return

'------------------------------------------------------------------------------------------------
_Hitachi4_Main_:
$endif  ' _HITACHI_4_INC_

Make the above code into a file named "Hitachi_4.inc"

Below is a demo program that shows the above code working:

'
' Demonstrate the replacement print routine with multiple Port.bit definitions for the Data lines
' For use with 18F devices and enhanced 14-bit core devices
'
    Include "Amicus18.inc"                  ' Use an 18F25K20 operating at 64MHz
'
' Setup the LCD. These must be included in the program
'
    $define LCD_DTPin4 PORTA.1
    $define LCD_DTPin5 PORTB.4
    $define LCD_DTPin6 PORTB.0
    $define LCD_DTPin7 PORTC.0
   
    Declare LCD_RSPin = PORTB.5
    Declare LCD_ENPin = PORTB.6
    Declare LCD_Interface = 4
    Declare LCD_Lines = 2
    Declare LCD_Type = Alphanumeric
    Declare LCD_CommandUs = 2000
    Declare LCD_DataUs = 50

    Include "Hitachi_4.inc"                ' Load the replacement Print command for a 4-bit interface

    Dim wLoop As Word = 0
   
'------------------------------------------------------------------------------------------------
Main:
    DelayMS 30                              ' Wait for the LCD to initialise

    Cls
    While
        Print At 1,1,Dec wLoop, "    "
        Inc wLoop
        DelayMS 100
    Wend

The code hasn't been extensively tested, but seems to work, and will give pointers as to how it's done.

top204

Many thanks for your post, and welcome to the new forum. However, this is now standard with the compiler's Print command. See page 422 in the manual. "Alphanumeric (Hitachi HD44780) LCD Print Declares"

It does make the program very slightly larger because it has to load the Data lines individually, but it adds a whole lot more flexability to the layout of a PCB.

In the new, updated, manual coming soon, I have also added the Declares section text from this section of the manual to the Print command's section.