PIC16Fxxx的LCD驅動程序(適用于HD44780兼容的驅動器)
;************************************************
;* LCD.ASM????????????????????????????????????? *
;************************************************
;* 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*
;*?? - PutHexLCD to write a HEX Code to LCD???? *
;*?? - Hex2ASCII to convert 4 bits to ASCII Code*
;************************************************
;
? list p=16f877
? #i nclude
;
; Defines for I/O ports that provide LCD data & control
; PORTB.0 - PORTB.3 are Data Pins for LCD Module
; PORTB.4 is E Control Signal for LCD
; PORTB.5 is RS Control Signal for LCD
; PORTC.2 is BackLight Control pin for LCD Module
;
? global InitLCD
? global putcLCD
? global clrLCD
? global L1homeLCD
? global L2homeLCD
? global? SendCmd
? global PutHexLCD
? global Hex2ASCII
;
LCD_DATA equ PORTB
LCD_CNTL equ PORTB
; Defines for I/O pins that provide LCD control
RS? equ 5
E? equ 4
; 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
;
; Directs linker to provide 4 variables in GPR memory
? UDATA
Byte? RES 1
Byte1? RES 1
Count? RES 1
Count1? RES 1
W_BUFR? RES 1
Hex_Bfr?? RES 1
;
PROG1? CODE?
;*******************************************************************
;* The LCD Module Subroutines????????????????????????????????????? *
;* Command sequence for 2 lines of 5x16 characters???????????????? *
;*******************************************************************
InitLCD
? BANKSEL TRISB
? movlw 0xc0? ; Initialize inputs/outputs for LCD
? movwf TRISB
? BANKSEL LCD_DATA
? clrf LCD_DATA ; Clear LCD data & control bits
;
? movlw .50? ; Power=On delay 50mS
? Call? Delay_MS
;
? movlw?? 0x02? ; Init for 4-bit interface
? call Send_4bit
? movlw .10? ;? Delay 10 mS
? Call? Delay_MS
;
? movlw b'00000011' ; Fully Initial LCD module
? call Send_4bit ; Sent '0011' data 4 time
? movlw .5? ; Delay 5mS
? Call? Delay_MS
? movlw b'00000011'
? call Send_4bit
? call Delay_1MS ; Delay 1mS
?? movlw b'00000011'
?? call Send_4bit
?? movlw b'00000010'
?? call Send_4bit
;
? movlw b'00101000' ; Set 2 lines & 5 x 7 dots
? call SendCmd
? movlw DISP_ON? ; Turn display on (0x0C)
? call SendCmd
? movlw ENTRY_INC ; Configure cursor movement
? call SendCmd
? movlw DD_RAM_ADDR ; Set writes for display memory
? call SendCmd
? 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
? banksel Byte
? movwf Byte? ; Save WREG in Byte variable
? call Delay_1MS
? swapf Byte,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,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
? return
;
;*********************************************************************
;*????? To put the HEX value to LCD Display ,,
;*????? High nibble first than Low nibble
;*????? Input : W Reg.
;*********************************************************************
PutHexLCD
? banksel W_BUFR
? movwf W_BUFR? ; Save W Register !!
? swapf W_BUFR,W? ; High nibble first !!
? call Hex2ASCII
? call putcLCD
;
? movf W_BUFR,W
? call Hex2ASCII
? call putcLCD
? return
;
;******************************************************************
;*?????? Convert a low nibble to ASCII code
;*?????? Input : W Reg.
;*?????? Output: W Reg.
;******************************************************************
Hex2ASCII
? andlw 0x0f? ; Mask Bit 4 to 7
? movwf Hex_Bfr
? sublw .09
? btfsc STATUS,C ; If W less than A (C=1) --> only add 30h
? goto Add_W_30?
Add_W_37 movlw 0x37
? goto Hex_cont
Add_W_30 movlw 0x30
Hex_cont addwf Hex_Bfr,W ; The correct ASCII code for this char !!
?? 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
? banksel Byte
? movwf Byte? ; Save WREG in Byte variable
? call Delay_1MS
? swapf Byte,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,W? ; Write lower nibble last
Send_4bit 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
;
;*******************************************************************
;* L1homeLCD - Moves the cursor to home position on Line 1???????? *
;*******************************************************************
L1homeLCD
? movlw DD_RAM_ADDR|0x00 ; Send command to move cursor to
? call SendCmd?? ; home position on line 1
? return
;*******************************************************************
;* L2homeLCD - Moves the cursor to home position on Line 2???????? *
;*******************************************************************
L2homeLCD
? movlw DD_RAM_ADDR|0x28 ; Send command to move cursor to
? call SendCmd?? ; home position on line 2
? return
;*******************************************************************
;* Delay - Generic LCD delay? (1.024mS @ 4MHz)???????????????????? *
;* 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_1MS??? ; 2 cycles for call
? clrf Count? ; 1 cycle to clear counter variable
Dloop
? nop
? decfsz Count,F? ; These two instructions provide a
? goto Dloop? ; (256 * 3) -1 cycle count
? return?? ; 2 cycles for return
;
;*******************************************************************
;*?????? Delay - 1mS base delay??????? *
;*?????? input : W Reg.??????????????????????????????????????????? *
;*???????????????????????????????????????????????????????????????? *
;*******************************************************************
Delay_MS
? movwf Count1
;
DLop1? call Delay_1MS
? decfsz Count1,F
? goto DLop1
? return
;
? END
評論
查看更多