winnie 发表于 2009-5-6 10:07:12

以汇编语言写的PIC16Fxxx 的LCD驱动程序

以汇编语言写的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
                #include <p16f877.inc>      
;
; 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
                globalSendCmd
                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
页: [1]
查看完整版本: 以汇编语言写的PIC16Fxxx 的LCD驱动程序