PIC单片机的LCD例程1
 
; LCD_F84.ASM
; LCD_RESET - provides a means for the user to manually reset the LCD
; - brings RA.0 (serial lead) low for 2.5 secs. During this
; time, the user should manually reset the LCD.
; - routine then clears the LCD and ouptuts ten dots.
; - LCD is then cleared again.
; - W and STATUS are saved.
; LCD_DEBUG
; - displays W content and the state of the Z and C flags on line 1.
; - prints value of location 40H as a character on line 2.
; - displays values of locations 10, 11, 12, 13 on line 3.
; - locations 14, 15, 16, 17 on line 4.
; - this is followed by a one second delay.
; - the W and STATUS registers are saved and restored in returning
; to the calling program.
;
; LCD_CHAR - displays character in W on LCD. W and STATUS are saved.
; LCD_VAL - converts value in W to two hex characters and displays on LCD.
;
; LCD_BCD_WORD - displays quantity in 41H and 42H as unsigned decimal
; quantity. Note, this is limited to 9999 decimal.
;PIC单片机学习网www.pic16.com
; LIST p=16f84
; #include <c:\mplab\p16f84.inc>
; __CONFIG 11h
RADIX HEX
CONSTANT _MAX_VAR=4FH
CONSTANT TX=0 ; PORTA, Bit 0

_SER_DATA EQU _MAX_VAR-0 ; 4F
_SER_LOOP EQU _MAX_VAR-1 ; 4E
_SER_TIME EQU _MAX_VAR-2 ; 4D

_TEMP1 EQU _MAX_VAR-3 ; 4C
_TEMP2 EQU _MAX_VAR-4 ; 4B

_H EQU _MAX_VAR-3 ; 4C
_L EQU _MAX_VAR-4 ; 4B

_TH EQU _MAX_VAR-5 ; 4A
_HU EQU _MAX_VAR-6 ; 49
_TE EQU _MAX_VAR-7 ; 48
_UN EQU _MAX_VAR-8 ; 47

_SAVE_W EQU _MAX_VAR-9 ; 46
_SAVE_STAT EQU _MAX_VAR-0A ; 45

_LOOP1 EQU _MAX_VAR-1 ; used for pace timing, same location as _SER_LOOP
_LOOP2 EQU _MAX_VAR-2 ; used for pace timing, same location as _SER_TIME

_N_MSEC EQU _MAX_VAR-0B ; 44
_N1 EQU _MAX_VAR-0C ; 43

ORG 300H

LCD_BCD_WORD: ; displays a natural binary word in locations 41 and 42
; in decimal.
MOVWF _SAVE_W ; save W and STATUS
SWAPF STATUS, W
MOVWF _SAVE_STAT
SWAPF _SAVE_STAT, F ; status saved in true form

MOVF 41H, W
MOVWF _H
MOVF 42H, W
MOVWF _L

CLRF _TH
CLRF _HU
CLRF _TE
CLRF _UN
_BCD_1:
MOVLW .1
SUBWF _L, F
BTFSC STATUS, C ; a borrow occurred
GOTO _INC_DEC
MOVLW .1
SUBWF _H, F
BTFSC STATUS, C
GOTO _INC_DEC

SWAPF _TH, W
IORWF _HU, W
CALL _LCD_VAL

SWAPF _TE, W
IORWF _UN, W
CALL _LCD_VAL

GOTO _RETURN

_INC_DEC:
CLRWDT
INCF _UN, F
MOVLW .10
SUBWF _UN, W
BTFSS STATUS, Z
GOTO _BCD_1

CLRF _UN

INCF _TE, F
MOVLW .10
SUBWF _TE, W
BTFSS STATUS, Z
GOTO _BCD_1

CLRF _TE

INCF _HU, F
MOVLW .10
SUBWF _HU, W
BTFSS STATUS, Z
GOTO _BCD_1

CLRF _HU

INCF _TH, F
GOTO _BCD_1

LCD_RESET:
MOVWF _SAVE_W ; save W and STATUS
SWAPF STATUS, W
MOVWF _SAVE_STAT
SWAPF _SAVE_STAT, F ; save in true form

BSF STATUS, RP0
BCF TRISA, 0
BCF STATUS, RP0

BCF PORTA, 0 ; output a zero to LCD

MOVLW .10
MOVWF _N1
_RESET_1:
MOVLW .250
MOVWF _N_MSEC
CALL _DELAY_N
DECFSZ _N1, F
GOTO _RESET_1

MOVLW 0CH
CALL _LCD_CHAR

MOVLW .10
MOVWF _N1
_RESET_2:
MOVLW "."
CALL _LCD_CHAR
DECFSZ _N1, F
GOTO _RESET_2

MOVLW .4 ; one second delay
MOVWF _N1

_RESET_3:
MOVLW .250
MOVWF _N_MSEC
CALL _DELAY_N
DECFSZ _N1, F
GOTO _RESET_3

MOVLW 0CH
CALL _LCD_CHAR

GOTO _RETURN

LCD_DELAY: ; delays number of msecs in W
MOVWF _SAVE_W ; save W and STATUS
SWAPF STATUS, W
MOVWF _SAVE_STAT
SWAPF _SAVE_STAT, F ; save in true form

MOVF _SAVE_W, W ; get W
MOVWF _N_MSEC
CALL _DELAY_N

GOTO _RETURN

LCD_DEBUG:
MOVWF _SAVE_W ; save W and STATUS
SWAPF STATUS, W
MOVWF _SAVE_STAT
SWAPF _SAVE_STAT, F

MOVLW 0CH ; clear the LCD
CALL _LCD_CHAR

MOVLW "W" ; W=
CALL _LCD_CHAR
MOVLW "="
CALL _LCD_CHAR
MOVF _SAVE_W, W ; display value of W in hex
CALL _LCD_VAL

MOVLW " "
CALL _LCD_CHAR

MOVLW "Z" ; Z=
CALL _LCD_CHAR
MOVLW "="
CALL _LCD_CHAR

BTFSS _SAVE_STAT, Z
MOVLW "0"
BTFSC _SAVE_STAT, Z
MOVLW "1"

CALL _LCD_CHAR ; display either a zero or one

MOVLW " "
CALL _LCD_CHAR

MOVLW "C" ; C=
CALL _LCD_CHAR
MOVLW "="
CALL _LCD_CHAR

BTFSS _SAVE_STAT, C
MOVLW "0"
BTFSC _SAVE_STAT, C
MOVLW "1"
CALL _LCD_CHAR ; display either a zero or a one

MOVLW 0DH ; go to second line
CALL _LCD_CHAR
MOVLW 0AH
CALL _LCD_CHAR

MOVF 40H, W ; display location 40H as a char
CALL _LCD_CHAR

MOVLW 0DH ; go to third line
CALL _LCD_CHAR
MOVLW 0AH
CALL _LCD_CHAR

MOVLW 10H ; initialize pointer to RAM location 10
MOVWF FSR

MOVLW .4 ; four values on line
MOVWF _N1
_DEBUG_1:
MOVF INDF, W
CALL _LCD_VAL ; display values in loc 10, 11, 12, 13
INCF FSR, F
MOVLW " "
CALL _LCD_CHAR
DECFSZ _N1, F
GOTO _DEBUG_1

MOVLW 0DH ; go to 4th line
CALL _LCD_CHAR
MOVLW 0AH
CALL _LCD_CHAR

MOVLW .4 ; same for 14, 15, 16 and 17
MOVWF _N1
_DEBUG_2:
MOVF INDF, W
CALL _LCD_VAL
MOVLW " "
CALL _LCD_CHAR
INCF FSR, F
DECFSZ _N1, F
GOTO _DEBUG_2

MOVLW .250
MOVWF _N_MSEC

CALL _DELAY_N ; 250 msecs
CALL _DELAY_N

CALL _DELAY_N
CALL _DELAY_N

GOTO _RETURN

LCD_VAL: ; converts byte in W to two characters and outputs
MOVWF _SAVE_W ; save W and STATUS
SWAPF STATUS, W
MOVWF _SAVE_STAT
SWAPF _SAVE_STAT, F ; save it in true form

MOVF _SAVE_W, W ; get back W
_LCD_VAL:
MOVWF _TEMP1 ; save a copy of W
MOVF PCLATH, W
MOVWF _TEMP2 ; save PCLATH

MOVLW .3 ; page 3
MOVWF PCLATH

SWAPF _TEMP1, W ; high nibble now in lo nibble of W
ANDLW 0FH ;
CALL _HEX_LOOK
CALL _SEROUT

MOVF _TEMP1, W
ANDLW 0FH
CALL _HEX_LOOK
CALL _SEROUT

MOVF _TEMP2, W
MOVWF PCLATH ; previous value of PCLATH
GOTO _RETURN

_HEX_LOOK:
ADDWF PCL, F
DT "0", "1", "2", "3", "4", "5", "6", "7"
DT "8", "9", "A", "B", "C", "D", "E", "F"

LCD_CHAR: ; outputs character in W to LCD
MOVWF _SAVE_W ; save W and STATUS
SWAPF STATUS, W
MOVWF _SAVE_STAT
SWAPF _SAVE_STAT, F ; save in true form

MOVF _SAVE_W, W ; get back W
_LCD_CHAR:
CALL _SEROUT
MOVLW .10
MOVWF _N_MSEC
CALL _DELAY_N
GOTO _RETURN

_SEROUT: ; transmits content of W at 9600 Baud

MOVWF _SER_DATA

BSF STATUS, RP0 ; make TX bit an output
BCF TRISA, TX ;
BCF STATUS, RP0
BCF PORTA, TX ; set to stop bit

MOVLW .255
MOVWF _SER_TIME ; be sure stop bit has been high present
_SEROUT1: ; for some time
DECFSZ _SER_TIME, F
GOTO _SEROUT1

MOVLW .9
MOVWF _SER_LOOP

BCF STATUS, C ; set C to 0, start bit

_SEROUT2:
BTFSC STATUS, C
BCF PORTA, TX ; send a one
BTFSS STATUS, C
BSF PORTA, TX ; or a zero

MOVLW .31
MOVWF _SER_TIME ; one bit delay. 104 usecs at 9600 baud
_SEROUT3:
DECFSZ _SER_TIME, F
GOTO _SEROUT3

;NOP ; CHANGE

RRF _SER_DATA, F ; least sign bit now in C
DECFSZ _SER_LOOP, F ; does not affect status
GOTO _SEROUT2 ; next character

BCF PORTA, TX ; send stop bit

RETURN

_DELAY_N: ; delays number of msecs specified in _N_MSEC
MOVF _N_MSEC, W
MOVWF _LOOP1
_DELAY_1:
MOVLW .247 ; close to 1.0 msec delay when set to .247
MOVWF _LOOP2
_DELAY_2:

CLRWDT
DECFSZ _LOOP2, F ; decrement and leave result in LOOP2
; skip next statement if zero
GOTO _DELAY_2
DECFSZ _LOOP1, F
GOTO _DELAY_1
RETURN

_RETURN:
SWAPF _SAVE_STAT, W
MOVWF _TEMP2
SWAPF _TEMP2, W
MOVWF STATUS
SWAPF _SAVE_W, W ; get back W without altering STATUS
MOVWF _TEMP2
SWAPF _TEMP2, W

RETURN


-------------PIC单片机学习网www.pic16.com-----------