User Tools

Site Tools


pic18f4685_8bit_lcd_driver

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pic18f4685_8bit_lcd_driver [2007/04/10 00:06]
pic18f4685_8bit_lcd_driver [2007/04/10 00:06] (current)
Line 1: Line 1:
 +<​file>​
 +;
 +; MIOS Custom LCD Driver Example for character LCDs
 +;
 +; NOTE: this is just a template for LCDs which are different to 
 +;       ​HD44780 (that is natively supported by MIOS -> LCD type #0)
 +;       Note also that this driver only supports a single CLCD
 +;       and no free definable enable (E) line
 +;
 +; ==========================================================================
 +;
 +;  Copyright (C) 2003  Thorsten Klose (tk@midibox.org)
 +;  Licensed for personal non-commercial use only.
 +;  All other rights reserved.
 +
 +; ==========================================================================
  
 +;; --------------------------------------------------------------------------
 +;;  Following system variables are given by MIOS and can be directly ​
 +;;  accessed by the driver. The addresses are defined in mios.h and
 +;;  should not be changed
 +;; 
 +;;  MIOS_GLCD_BUFFER  ​    a 8 byte buffer for data transfers
 +;;  MIOS_LCD_OPTION1  ​    ​contains the first LCD option given by MIOS_LCD_TypeSet
 +;;  MIOS_LCD_OPTION2  ​    ​contains the second LCD option given by MIOS_LCD_TypeSet
 +;;  MIOS_LCD_CURSOR_POS  ​    the current cursor pos of characters (GLCD: multiplied by width)
 +;;  MIOS_GLCD_GCURSOR_X  ​    for GLCDs: the current X position of graphical cursor
 +;;  MIOS_GLCD_GCURSOR_Y  ​    for GLCDs: the current Y position of graphical cursor
 +;;  MIOS_GLCD_FONT_WIDTH ​    for GLCDs: the fontwidth given by MIOS_GLCD_FontInit
 +;;  MIOS_GLCD_FONT_HEIGHT ​   for GLCDs: the fontheight given by MIOS_GLCD_FontInit
 +;;  MIOS_GLCD_FONT_X0 ​       for GLCDs: the first byte within a char entry
 +;;  MIOS_GLCD_FONT_OFFSET ​   for GLCDs: the byte offset between the characters
 +;;  MIOS_GLCD_FONT_PTRL ​     for GLCDs: pointer to the character table, low-byte
 +;;  MIOS_GLCD_FONT_PTRH ​     for GLCDs: pointer to the character table, high-byte
 +;;  MIOS_LCD_TIMEOUT0 ​       can be used for timeout loops
 +;;  MIOS_LCD_TIMEOUT1 ​       can be used for timeout loops
 +;;  MIOS_GLCD_TMP1 ​          can be used as temporary buffer
 +;;  MIOS_GLCD_TMP2 ​          can be used as temporary buffer
 +;;  MIOS_GLCD_TMP3 ​          can be used as temporary buffer
 +;;  MIOS_GLCD_TMP4 ​          can be used as temporary buffer
 +;;  MIOS_LCD_Y0_OFFSET ​      Y0 offset of LCD
 +;;  MIOS_LCD_Y1_OFFSET ​      Y1 offset of LCD
 +;;  MIOS_LCD_Y2_OFFSET ​      Y2 offset of LCD
 +;;  MIOS_LCD_Y3_OFFSET ​      Y3 offset of LCD
 +;;  MIOS_LCD_CURSOR_POS_REAL unmapped cursor position which has been set with MIOS_LCD_CursorSet
 +;; 
 +;;  Note: the addresses are located in an upper bank and therefore have to
 +;;        be accessed with the BANKED flag. Also the BSR has to be justified
 +;;        before using the registers
 +;;  Example:
 +;; SET_BSR MIOS_LCD_OPTION1 ;​ sets BSR to the bank where MIOS_LCD_*
 +;; ; has been located. You don't need to
 +;; ; change the BSR for the other LCD registers
 +;;      movf    MIOS_LCD_OPTION1,​ W, BANKED ; get LCD option #1
 +;; 
 +;;  Important: to allow a proper interaction with MIOS applications,​ you are
 +;;  only allowed to modify MIOS_PARAMETER[123],​ the mutliplication registers
 +;;  and FSR1. You are not allowed to change TMP[1-5] or FSR0
 +;;  if you need some temporary registers, use the given addresses above or
 +;;  locate them to addresses which are not used by the application
 +;; --------------------------------------------------------------------------
 +
 +;; Pins of LC-Display
 +USER_LCD_LAT_D EQU LATB ;​ Pin B.7-0
 +USER_LCD_PORT_D EQU ​    PORTB
 +USER_LCD_TRIS_D EQU ​    TRISB
 +
 +USER_LCD_LAT_RW EQU ​    LATD
 +USER_LCD_PIN_RW EQU ​    ​6 ​              ; Pin D.6
 +USER_LCD_LAT_RS EQU ​    LATD
 +USER_LCD_PIN_RS EQU ​    ​5 ​              ; Pin D.5
 +
 +USER_LCD_LAT_E EQU ​    ​LATD ;​ Pin D.7
 +USER_LCD_PIN_E EQU ​    7
 +
 +;; new names for CLCD registers
 +USER_LCD_STATUS EQU MIOS_GLCD_TMP1
 +USER_LCD_SC_CTR EQU MIOS_GLCD_TMP3
 +
 +#define USER_LCD_STATUS_LCD0_DISABLED 0 ;​ bit0: if set, first LCD disabled
 +#define USER_LCD_STATUS_LCD1_DISABLED 1 ;​ bit1: if set, second LCD disabled -- not provided by this driver!
 +#define USER_LCD_STATUS_CUR_DISABLED 2 ;​ bit2: if set, currently selected LCD disabled
 +#define USER_LCD_STATUS_CUR_LCD 3 ;​ bit3: if cleared: current LCD is first LCD, else second LCD
 +
 +;; --------------------------------------------------------------------------
 +;;  This function is called by MIOS when the custom LCD should be initialized
 +;;  In:  MIOS_LCD_OPTION1 - contains the first LCD option given by MIOS_LCD_TypeSet
 +;;       ​MIOS_LCD_OPTION2 - contains the second LCD option given by MIOS_LCD_TypeSet
 +;;  Out: -
 +;; --------------------------------------------------------------------------
 +USER_LCD_Init
 + ;; notify that no graphical LCD is connected
 + bcf MIOS_BOX_CFG0,​ MIOS_BOX_CFG0_USE_GLCD
 +
 + movlw 0xf9 ;​ set only TRISE[2:1] as output
 + andwf TRISE,​ F
 +
 + ; (Initialization of Ports: done in Init_Ports)
 + SET_BSR MIOS_LCD_TIMEOUT1
 + clrf USER_LCD_STATUS,​ BANKED
 +
 + movlw 100 ;​ 100 ms delay
 + call MIOS_Delay
 +
 +        bcf     ​USER_LCD_LAT_RW,​ USER_LCD_PIN_RW ;​ LCD_WRITE
 +        bcf     ​USER_LCD_LAT_RS,​ USER_LCD_PIN_RS ;​ USER_LCD_PIN_RS_0
 +
 + ;; initialize LCD
 + movlw 0x38
 + movwf USER_LCD_LAT_D
 + rcall USER_LCD_Strobe_Set
 + rcall USER_LCD_Strobe_Clr
 + movlw 50 ;​ 50 ms delay
 + call MIOS_Delay
 + rcall USER_LCD_Strobe_Set
 + rcall USER_LCD_Strobe_Clr
 + movlw 50 ;​ 50 ms delay
 + call MIOS_Delay
 + rcall USER_LCD_Strobe_Set
 + rcall USER_LCD_Strobe_Clr
 +
 + movlw 0x08 ;​ Display Off
 + rcall USER_LCD_Cmd
 + movlw 0x0c ;​ Display On
 + rcall USER_LCD_Cmd
 + movlw 0x06 ;​ Entry Mode
 + rcall USER_LCD_Cmd
 + movlw 0x01 ;​ Clear Display
 + call USER_LCD_Cmd
 + bcf MIOS_LCD_TIMEOUT1,​ 7, BANKED ; everything ok, make sure that LCD_TIMEOUT,​ bit 7 is cleared
 +
 + movlw 0x38 ;​ without these lines the LCD will not work
 + rcall USER_LCD_Cmd ;​ correctly after a second USER_LCD_Init
 + movlw 0x0c
 + rcall USER_LCD_Cmd
 + movlw 0x00 ;​ set cursor to zero pos
 + rgoto USER_LCD_CursorSet
 +
 +;; --------------------------------------------------------------------------
 +;;  FUNCTION: USER_LCD_Data
 +;;  DESCRIPTION:​ sends a data value to the LCD display.<​BR>​
 +;;  On CLCDs: branch directly to USER_LCD_PrintChar<​BR>​
 +;;  On GLCDs: ignore this function!
 +;;  IN:  data which should be sent
 +;;  OUT: -
 +;; --------------------------------------------------------------------------
 +USER_LCD_Data
 + ;; store byte in data latch
 + movwf USER_LCD_LAT_D
 + ;; store bits 3:2 into port E bits 2:1
 + rrncf WREG, 0, 0 ;; shift right
 + movwf LATE ;;​ store in port E latch
 + rlncf WREG,​ 0, 0 ;; shift left, leave WREG as it was!
 +
 + ;; wait until display unbusy
 + rcall USER_LCD_WaitUnbusy
 +
 + ;; exit if current LCD not available due to timeout
 + BIFSET USER_LCD_STATUS,​ USER_LCD_STATUS_CUR_DISABLED,​ BANKED, return
 +
 + ;; select data register
 +        bsf     ​USER_LCD_LAT_RS,​ USER_LCD_PIN_RS
 +
 + ;; activate write
 +        bcf     ​USER_LCD_LAT_RW,​ USER_LCD_PIN_RW
 +
 + ;; strobe and exit
 + rcall USER_LCD_Strobe_Set
 + rgoto USER_LCD_Strobe_Clr
 +
 +
 +;; --------------------------------------------------------------------------
 +;;  FUNCTION: USER_LCD_Cmd
 +;;  DESCRIPTION:​ sends a command to the LCD display.<​BR>​
 +;;  On CLCDs: use this function to decode the HD44780 commands if required<​BR>​
 +;;  On GLCDs: ignore this function!
 +;;  IN:  command which should be sent
 +;;  OUT: -
 +;; --------------------------------------------------------------------------
 +USER_LCD_Cmd
 + ;; store byte in data latch
 + movwf USER_LCD_LAT_D
 + ;; store bits 3:2 into port E bits 2:1
 + rrncf WREG, 0, 0 ;; shift right
 + movwf LATE ;;​ store in port E latch
 + rlncf WREG,​ 0, 0 ;; shift left, leave WREG as it was!
 +
 + ;; wait until display unbusy
 + rcall USER_LCD_WaitUnbusy
 +
 + ;; exit if current LCD not available due to timeout
 + BIFSET USER_LCD_STATUS,​ USER_LCD_STATUS_CUR_DISABLED,​ BANKED, return
 +
 + ;; select command register
 +        bcf     ​USER_LCD_LAT_RS,​ USER_LCD_PIN_RS
 +
 + ;; activate write
 +        bcf     ​USER_LCD_LAT_RW,​ USER_LCD_PIN_RW
 +
 + ;; strobe and exit
 + rcall USER_LCD_Strobe_Set
 + rgoto USER_LCD_Strobe_Clr
 +
 +
 +;; --------------------------------------------------------------------------
 +;;  This function is NOT called by MIOS, but only used by the custom driver
 +;;  to wait until the LCD is unbusy
 +;;  In:  -
 +;;  Out: -
 +;; --------------------------------------------------------------------------
 +USER_LCD_WaitUnbusy
 + ;; exit if current LCD not available due to timeout
 + BIFSET USER_LCD_STATUS,​ USER_LCD_STATUS_CUR_DISABLED,​ BANKED, return
 +
 + ;; turn off output drivers
 + movlw 0xf3 ;​ set all except TRISB[3:2] as input
 + iorwf USER_LCD_TRIS_D,​ F
 + movlw 0x06 ;​ set only TRISE[2:1] as input
 + iorwf TRISE,​ F
 +
 + ;; select command register
 +        bcf     ​USER_LCD_LAT_RS,​ USER_LCD_PIN_RS
 +
 + ;; poll busy bit
 + clrf MIOS_LCD_TIMEOUT0,​ BANKED
 + clrf MIOS_LCD_TIMEOUT1,​ BANKED
 +
 +        bsf     ​USER_LCD_LAT_RW,​ USER_LCD_PIN_RW ;​ LCD_READ
 +USER_LCD_WaitUnbusy_Loop
 + rcall USER_LCD_Strobe_Clr
 + incf MIOS_LCD_TIMEOUT0,​ F, BANKED
 + skpnz
 + incf MIOS_LCD_TIMEOUT1,​ F, BANKED
 + bz USER_LCD_WaitUnbusy_Disable ;​ leave loop when LCD_TIMEOUT = 0xff. Up to now bit 7 is set and the LCD
 + ; busy routine will never be called again
 + rcall USER_LCD_Strobe_Set
 + IFSET USER_LCD_PORT_D,​ 7, rgoto USER_LCD_WaitUnbusy_Loop
 + rcall USER_LCD_Strobe_Clr
 +
 +USER_LCD_WaitUnbusy_End
 + ;; turn on output drivers again
 + movlw 0x0c ;​ set all except TRISB[3:2] as output
 + andwf USER_LCD_TRIS_D,​ F
 + movlw 0xf9 ;​ set only TRISE[2:1] as output
 + andwf TRISE,​ F
 + return
 +
 +USER_LCD_WaitUnbusy_Disable
 + ;; disable currently selected LCD
 + btfss USER_LCD_STATUS,​ USER_LCD_STATUS_CUR_LCD,​ BANKED
 + bsf USER_LCD_STATUS,​ USER_LCD_STATUS_LCD0_DISABLED,​ BANKED
 + btfsc USER_LCD_STATUS,​ USER_LCD_STATUS_CUR_LCD,​ BANKED
 + bsf USER_LCD_STATUS,​ USER_LCD_STATUS_LCD1_DISABLED,​ BANKED
 + rgoto USER_LCD_WaitUnbusy_End
 +
 +
 +;; --------------------------------------------------------------------------
 +;;  This function is NOT called by MIOS, but only used by the custom driver
 +;;  to set the strobe line to logic-1
 +;;  In:  -
 +;;  Out: -
 +;; --------------------------------------------------------------------------
 +USER_LCD_Strobe_Set
 + ;; (code for variable E output removed)
 + bsf USER_LCD_LAT_E,​ USER_LCD_PIN_E
 + nop
 + nop
 + nop
 + nop
 + nop
 + return
 +
 +;; --------------------------------------------------------------------------
 +;;  This function is NOT called by MIOS, but only used by the custom driver
 +;;  to set the strobe line to logic-0
 +;;  In:  -
 +;;  Out: -
 +;; --------------------------------------------------------------------------
 +USER_LCD_Strobe_Clr
 + ;; (code for variable E output removed)
 + nop
 + nop
 + nop
 + nop
 + nop
 + bcf USER_LCD_LAT_E,​ USER_LCD_PIN_E
 + return
 +
 +
 +;; --------------------------------------------------------------------------
 +;;  This function is called by MIOS when the custom LCD should be cleared
 +;;  In:  MIOS_LCD_OPTION1 - contains the first LCD option given by MIOS_LCD_TypeSet
 +;;       ​MIOS_LCD_OPTION2 - contains the second LCD option given by MIOS_LCD_TypeSet
 +;;  Out: -
 +;; --------------------------------------------------------------------------
 +USER_LCD_Clear
 + movlw 0x01
 + call USER_LCD_Cmd
 + BIFSET MIOS_LCD_Y2_OFFSET,​ 7, BANKED, rgoto USER_LCD_Clear2
 + BIFSET MIOS_LCD_Y3_OFFSET,​ 7, BANKED, rgoto USER_LCD_Clear2
 + return
 +USER_LCD_Clear2
 + bsf MIOS_LCD_CURSOR_POS,​ 7, BANKED
 + movlw 0x01
 + call USER_LCD_Cmd
 + bcf MIOS_LCD_CURSOR_POS,​ 7, BANKED
 + return
 +
 +;; --------------------------------------------------------------------------
 +;;  This function is called by MIOS when the cursor should be changed
 +;;  In:  MIOS_LCD_OPTION1 - contains the first LCD option given by MIOS_LCD_TypeSet
 +;;       ​MIOS_LCD_OPTION2 - contains the second LCD option given by MIOS_LCD_TypeSet
 +;;       ​MIOS_GLCD_CURSOR_X - horizontal cursor position (for GLCDs)
 +;;       ​MIOS_GLCD_CURSOR_Y - vertical cursor position ​  (for GLCDs)
 +;;       ​MIOS_LCD_CURSOR_POS - character cursor position ​ (for CLCDs)
 +;;  Out: -
 +;; --------------------------------------------------------------------------
 +USER_LCD_CursorSet
 + SET_BSR MIOS_LCD_CURSOR_POS
 + movf MIOS_LCD_CURSOR_POS,​ W, BANKED
 + iorlw 0x80
 + rgoto USER_LCD_Cmd
 +
 +;; --------------------------------------------------------------------------
 +;;  This function is called by MIOS when a character should be print
 +;;  In:  WREG - character
 +;;       all other MIOS_*LCD_* registers
 +;;  Out: GLCDs should justify the X/Y cursor position
 +;; --------------------------------------------------------------------------
 +USER_LCD_PrintChar
 + rgoto USER_LCD_Data
 +
 +
 +;; --------------------------------------------------------------------------
 +;;  FUNCTION: USER_LCD_SpecialCharInit
 +;;  DESCRIPTION:​ see MIOS_CLCD_SpecialCharInit
 +;;  IN:  number of special character (0-7) in WREG
 +;;       ​pointer to special char pattern in TBLPTR (consists of 8
 +;;          entries for every character-line)
 +;;  OUT: TBLPTR has to be set to next table entry (TBLPTR+=8)
 +;; --------------------------------------------------------------------------
 +USER_LCD_SpecialCharInit
 + ;; transfer special character to display
 + swapf WREG,​ F
 + rrf WREG, W
 + andlw 0x38
 + iorlw 0x40
 + rcall USER_LCD_Cmd
 +
 + SET_BSR USER_LCD_SC_CTR
 + clrf USER_LCD_SC_CTR,​ BANKED
 +USER_LCD_SpecialCharInitLoop
 + tblrd*+
 + movf TABLAT,​ W
 + rcall USER_LCD_Data
 + incf USER_LCD_SC_CTR,​ F, BANKED
 + BIFCLR USER_LCD_SC_CTR,​ 3, BANKED, rgoto USER_LCD_SpecialCharInitLoop
 +
 + goto USER_LCD_CursorSet
 +</​file>​
pic18f4685_8bit_lcd_driver.txt ยท Last modified: 2007/04/10 00:06 (external edit)