Jag hr skrivit ihop en kodsnutt för att hantera lcd displayer.
Kunna flytta cursor, skriva ut, skriva ut värdet i W som hex osv.
Den fungerar även om den kanske inte är så snygg...
Dock, jag skulle vilja ha den "relocatable", för att enkelt kunna använda rutinerna i andra projekt.
Dock har jag inte lyckats förstå alla detaljer i hur man gör detta.
Jag har suttit med manualen för MPLAB IDE och tillhörande linker, men icke.
Så, har någon en enkel förklaring till vad som ska ändras?
Koden är gjord för en 16F628A.
Tyvärr verkar alla tabuleringar försvinna, koden ser bättre ut i MPlab...
Detta är koden i absolute mode, som fungerar:
Kod: Markera allt
; FOR PIC16F628A
; WDT OFF
; CODE PROTECT OFF
; CLOCK Internal 4MHz
; INSTRUCTION CLOCK
; FUNCTION testing LCD
list p=16F628A
;********** PIC SYSTEM REGISTER FILE EQUATES **********
porta equ 05h
portb equ 06h
status equ 03h
cmcon equ 1Fh
trisa equ 85h ; bank 1
trisb equ 86h ; bank 1
#define c status,0 ; carry bit
#define z status,2 ; zero bit
#define E porta,0 ; Control line E
#define RW porta,1 ; Control line R/W
#define RS porta,2 ; Control line RS
#define rp0 status,5 ; Page swap bit
#define rp1 status,6 ; Page swap bit
cblock 20h
count_reg
short_del
long_del
save_w
save_stat
temp1
temp2
endc
; ************************* macro's **********************
page1 macro
bsf rp0 ; change to page 1
bcf rp1
endm
page0 macro
bcf rp0 ; change to page 0
bcf rp1
endm
org 0
goto start
;**************** Interrupt handler *************************
org 4 ; Interrupt vector
goto start
;**************** subroutines *********************
pulse_e bsf E
nop
bcf E
retlw 0
;shortdelay decfsz short_del
; goto shortdelay
; retlw 0
;longdelay call shortdelay
; decfsz long_del
; goto longdelay
; retlw 0
functionset bcf RS
bcf RW
movlw b'00111000'
movwf portb
call pulse_e
call busywait ;shortdelay
retlw 0
displayon bcf RS
bcf RW
movlw 0Fh
movwf portb
call pulse_e
call busywait ;shortdelay
clrf count_reg
retlw 0
;lcd_clr bcf RS
; bcf RW
; movlw b'00000001'
; movwf portb
; call pulse_e
; call busywait
; clrf count_reg
; retlw 0
lcd_line1 bcf RS
bcf RW
movlw b'10000000'
movwf portb
call pulse_e
call busywait
clrf count_reg
retlw 0
lcd_line2 bcf RS
bcf RW
; movlw 40h
movlw b'11000000'
movwf portb
call pulse_e
call busywait
clrf count_reg
retlw 0
setadress bcf RS
bcf RW
movlw b'10001000'
movwf portb
call pulse_e
call busywait
clrf count_reg
retlw 0
curs_home bcf RS
bcf RW
movlw b'00000010'
movwf portb
call pulse_e
call busywait
clrf count_reg
retlw 0
text addwf 02h,f
retlw 'H'
retlw 'E'
retlw 'L'
retlw 'L'
retlw 'O'
message movf count_reg,w
call text
bsf RS
bcf RW
movwf portb
call pulse_e
call busywait ;shortdelay
incf count_reg,w
xorlw 05h
btfsc z
retlw 0
incf count_reg,f
goto message
lcd_char bsf RS ; lcd_char puts value in W on lcd
bcf RW
movwf portb
call pulse_e
call busywait
retlw 0
lcd_val ; converts byte in W to two characters and outputs
MOVWF save_w ; save W and STATUS
SWAPF status, w
MOVWF save_stat
MOVF save_w, w ; get back W
MOVWF temp1 ; save a copy
SWAPF temp1, w ; high nibble now in lo nibble of W
ANDLW 0FH ;
MOVWF temp2 ; copy to TEMP2
SUBLW .9 ; W = 9 - TEMP2
BTFSS c ; TEMP2 > 9
GOTO _ALPHA_HI
_NUMERIC_HI
MOVF temp2, W ; get the original nibble
ADDLW '0' ; add character 0
GOTO _OUT_1_DIG_HI
_ALPHA_HI
MOVF temp2, W
ADDLW '0'+7 ; for 'A', 'B', 'C', 'D', 'E' and 'F'
_OUT_1_DIG_HI
CALL lcd_char
; now the lower nibble
MOVF temp1, W ; low nibble now in lo nibble of W
ANDLW 0FH ;
MOVWF temp2 ; copy to TEMP2
SUBLW .9 ; W = 9 - TEMP2
BTFSS c ; TEMP2 > 9
GOTO _ALPHA_LO
_NUMERIC_LO
MOVF temp2, W ; get the original nibble
ADDLW '0' ; add character 0
GOTO _OUT_1_DIG_LO
_ALPHA_LO
MOVF temp2, W
ADDLW '0'+7 ; for 'A', 'B', 'C', 'D', 'E' and 'F'
_OUT_1_DIG_LO
CALL lcd_char
SWAPF save_stat, W ; restore STATUS
MOVWF status
SWAPF save_w, F ; get back W without altering STATUS
SWAPF save_w, W
retlw 0
busywait page1
movlw b'11111111' ; Set port b to inputs
movwf trisb
page0 ; Done!
bcf RS
bsf RW
nop
busyread bsf E
nop
rlf portb,w
bcf E
nop
nop
btfsc c
goto busyread
page1
movlw b'00000000' ; Set port b to output
movwf trisb ; Done!
page0
retlw 0
start
clrf short_del
clrf long_del
clrf count_reg
clrf porta
movlw 0x07 ; Set all inputs on port a to digital I/O
movwf cmcon ; Done!
clrf portb
page1
clrf trisb
movlw b'11111000'
movwf trisa ; Set pins 0-2 on port a to outputs
page0
call busywait ; longdelay
call functionset
call displayon
call curs_home
call lcd_line1
call message
call setadress
call message
call lcd_line2
movlw b'01001000'
call lcd_val
; call message
loop goto loop ; Hang forever
end