📄 lcd.inc
字号:
;---------------------------------------------------------------;
; ;
;#INCLUDE <LCD_klq.INC> ;
; ;
;; Defines for I/O ports that provide LCD data & control ;
; ;
;LCD_DATA equ PORTB ;
;LCD_CNTL equ PORTB ;
; ;
;RS equ 5 ; RS=PORTB,5 ;
;E equ 4 ;
; ;
;===============================================================;
;
;************************************************
;* LCD.INC *
;* is A modification of Microchip's *
;* sample program of workshop MCU201 *
;* The original program information *
;* is as the followings *
;************************************************
;* MCU201 Workshop *
;* Written by: Rodger Richey *
;* Principal Applications Engr. *
;* Microchip Technology Inc. *
;* Date: 1 April 1999 *
;* Revision: 1 *
;************************************************
;* Contains subroutines to control an external *
;* lcd panel in 4-bit mode. These routines *
;* were designed specifically for the panel on *
;* the MCU201 workshop demo board, but should *
;* work with other LCDs with a HD44780 type *
;* controller. *
;* Routines include: *
;* - InitLCD to initialize the LCD panel *
;* - putcLCD to write a character to LCD *
;* - SendCmd to write a command to LCD *
;* - clrLCD to clear the LCD display *
;* - L1homeLCD to return cursor to line 1 home*
;* - L2homeLCD to return cursor to line 2 home*
;************************************************
;
; define commands
;
; LCD Module commands
DISP_ON EQU 0x00C ; Display on
DISP_ON_C EQU 0x00E ; Display on, Cursor on
DISP_ON_B EQU 0x00F ; Display on, Cursor on, Blink cursor
DISP_OFF EQU 0x008 ; Display off
CLR_DISP EQU 0x001 ; Clear the Display
ENTRY_INC EQU 0x006 ;
ENTRY_INC_S EQU 0x007 ;
ENTRY_DEC EQU 0x004 ;
ENTRY_DEC_S EQU 0x005 ;
DD_RAM_ADDR EQU 0x080 ; Least Significant 7-bit are for address
DD_RAM_UL EQU 0x080 ; Upper Left coner of the Display
;
; define RAM
;
CBLOCK
Byte_LCD, Count, Count1, Count2, Posit_LCD, SystemFlag1
Byte, Byte1
ENDC
;
;
PUT_STRING MACRO STR_NO
movlw STR_NO-Msg1
call Message
ENDM
SET_CURSOR MACRO CUR_X,CUR_Y
movlw 0x80 + ((0x40*CUR_Y)+CUR_X)
call SendCmd
ENDM
;
;*******************************************************************
;* The LCD Module Subroutines *
;* Command sequence for 2 lines of 5x16 characters *
;*******************************************************************
InitLCD
bcf STATUS,RP0 ; Bank 0
bcf STATUS,RP1
clrf LCD_DATA ; Clear LCD data & control bits
bsf STATUS,RP0 ; Bank 1
movlw 0xc0 ; Initialize inputs/outputs for LCD
movwf LCD_DATA
btfsc PCON,NOT_POR ; Check to see if POR reset or other
goto InitLCDEnd
bcf STATUS,RP0 ; If POR reset occured, full init LCD
call LongDelay
movlw 0x02 ; Init for 4-bit interface
movwf LCD_DATA
bsf LCD_CNTL, E
bcf LCD_CNTL, E
call LongDelay
movlw b'00101000'
call SendCmd
movlw DISP_ON ; Turn display on
call SendCmd
movlw ENTRY_INC ; Configure cursor movement
call SendCmd
movlw DD_RAM_ADDR ; Set writes for display memory
call SendCmd
InitLCDEnd ; Always clear the LCD and set
bcf STATUS,RP0 ; the POR bit when exiting
call clrLCD
bsf STATUS,RP0
bsf PCON,NOT_POR
bcf STATUS,RP0
return
;*******************************************************************
;*SendChar - Sends character to LCD *
;*This routine splits the character into the upper and lower *
;*nibbles and sends them to the LCD, upper nibble first. *
;*******************************************************************
putcLCD
movwf Byte_LCD ; Save WREG in Byte variable
call Delay
swapf Byte_LCD,W ; Write upper nibble first
andlw 0x0f
movwf LCD_DATA
bsf LCD_CNTL, RS ; Set for data
bsf LCD_CNTL, E ; Clock nibble into LCD
bcf LCD_CNTL, E
movf Byte_LCD,W ; Write lower nibble last
andlw 0x0f
movwf LCD_DATA
bsf LCD_CNTL, RS ; Set for data
bsf LCD_CNTL, E ; Clock nibble into LCD
bcf LCD_CNTL, E
incf Posit_LCD ; move cursor right 1 position
return
;*******************************************************************
;* putDIGIT - put one digit (0 ~ F) *
;*******************************************************************
;
putDIGIT:
banksel Byte
bsf SystemFlag1,0 ; set Toggle bit for only oen digit!!
andlw 0x0f
goto Hex_Loop
;-------------------------------------------------------------------------------
;-- To put the HEX value to LCD Display ,,
;-- High nibble first than Low nibble
;-------------------------------------------------------------------------------
PutHexLCD
putHexLCD:
banksel Byte
bcf SystemFlag1,0 ; Clear Toggle bit !!
movwf Byte ; Save W Register !!
swapf Byte,W ; High nibble first !!
Hex_Loop
bcf SystemFlag1,1
andlw 0x0f ; Mask Bit 4 to 7
movwf Byte1
sublw .09
btfsc STATUS,C ; If W less than A (C=1) --> only add 30h
goto Add_W_30A
Add_W_37A
movlw 0x37
goto Show_High_Nibble
Add_W_30A
movlw 0x30
Show_High_Nibble
addwf Byte1,F ; The correct ASCII code for this char !!
call Delay
swapf Byte1,W ; Write upper nibble first
Write_LCD_Bus
andlw 0x0f
movwf LCD_DATA
bsf LCD_CNTL, RS ; Set for data
bsf LCD_CNTL, E ; Clock nibble into LCD
bcf LCD_CNTL, E
btfsc SystemFlag1,1
goto Test_Char_Finish
movf Byte1,W ; Write lower nibble last
bsf SystemFlag1,1
goto Write_LCD_Bus
Test_Char_Finish:
btfsc SystemFlag1,0
return ; If Toggle bit already be set to 1
; Otherwise !!
movf Byte,W ; Save to another Buffer -->
andlw 0x0f ; Mask Bit 4 to 7
bsf SystemFlag1,0
goto Hex_Loop ; Show next Char. -------->
SetCurLCD
return
;*******************************************************************
;* SendCmd - Sends command to LCD *
;* This routine splits the command into the upper and lower *
;* nibbles and sends them to the LCD, upper nibble first. *
;*******************************************************************
SendCmd
movwf Byte_LCD ; Save WREG in Byte variable
call Delay
swapf Byte_LCD,W ; Send upper nibble first
andlw 0x0f
movwf LCD_DATA
bcf LCD_CNTL,RS ; Clear for command
bsf LCD_CNTL,E ; Clock nibble into LCD
bcf LCD_CNTL,E
movf Byte_LCD,W ; Write lower nibble last
andlw 0x0f
movwf LCD_DATA
bcf LCD_CNTL,RS ; Clear for command
bsf LCD_CNTL,E ; Clock nibble into LCD
bcf LCD_CNTL,E
return
;*******************************************************************
;* clrLCD - Clear the contents of the LCD *
;*******************************************************************
clrLCD
movlw CLR_DISP ; Send the command to clear display
call SendCmd
return
;*******************************************************************
;* curonLCD - turn on cursor of the LCD *
;*******************************************************************
curonLCD
movlw DISP_ON_C ; Send the command to turn on cursor
call SendCmd
return
;*******************************************************************
;* curblkLCD - turn on and blink cursor of the LCD *
;*******************************************************************
curblkLCD
movlw DISP_ON_B ; Send the command to turn on and blink cursor
call SendCmd
return
;*******************************************************************
;* curoffLCD - turn off cursor of the LCD *
;*******************************************************************
curoffLCD
movlw DISP_ON ; Send the command to turn off cursor
call SendCmd
return
;*******************************************************************
;* movcurLCD - move cursor right for w position *
;*******************************************************************
movcurLCD
addwf Posit_LCD ; Send the command to turn off cursor
movf Posit_LCD,w
call SendCmd
return
;*******************************************************************
;* L1homeLCD - Moves the cursor to home position on Line 1 *
;*******************************************************************
L1homeLCD
movlw DD_RAM_ADDR|0x00 ; Send command to move cursor to
movwf Posit_LCD ; home position on line 1
call SendCmd
return
;*******************************************************************
;* L2homeLCD - Moves the cursor to home position on Line 2 *
;*******************************************************************
L2homeLCD
movlw DD_RAM_ADDR|0x40 ; Send command to move cursor to
movwf Posit_LCD ; home position on line 2
call SendCmd
return
;*******************************************************************
;* Delay - Generic LCD delay *
;* Since the microcontroller can not read the busy flag of the *
;* LCD, a specific delay needs to be executed between writes to *
;* the LCD. *
;*******************************************************************
Delay ; 2 cycles for call
clrf Count ; 1 cycle to clear counter variable
movlw 0x04
movwf Count1 ; ((256*3)-1)*4 ( modified for 16MHz )
Dloop
decfsz Count,f ; These two instructions provide a
goto Dloop ; (256 * 3) -1 cycle count
decfsz Count1
goto Dloop
return ; 2 cycles for return
;*******************************************************************
;* LongDelay - Generic long LCD delay *
;* POR delay for the LCD panel. *
;*******************************************************************
LongDelay
clrf Count
clrf Count1
;;; movlw 0x03
movlw .12 ; modified for 16MHz
movwf Count2
LDloop
decfsz Count,f
goto LDloop
decfsz Count1,f
goto LDloop
decfsz Count2,f
goto LDloop
return
;
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -