182 lines
No EOL
4.6 KiB
PHP
182 lines
No EOL
4.6 KiB
PHP
;*************************************************************************
|
|
; Ziver Koc 1 september 2007 PIC 16F648A to HD44780 LCD
|
|
;
|
|
; ; LCD control lines
|
|
; #define LCD_RS 0 ; 0 = Command, 1 = Data
|
|
; #define LCD_RW 1 ; 0 = Write, 1 = Read
|
|
; #define LCD_E 2 ; 1 to send data
|
|
; #define LCD_D4 3 ; 4 data lines
|
|
; #define LCD_D5 4
|
|
; #define LCD_D6 5
|
|
; #define LCD_D7 6
|
|
;
|
|
; ; Registers we will be using
|
|
; #define R_DEL1 0x20 ; Delay register
|
|
; #define R_DEL2 0x21 ; Delay register
|
|
; #define R_WDATA_TMP1 0x22
|
|
; #define R_WDATA_TMP2 0x23
|
|
; #define R_SEND_W_TMP 0x24
|
|
;
|
|
;*************************************************************************
|
|
CONSTANT FUNCTSET81 = b'00110000' ; 8-bit mode, 1 lines
|
|
CONSTANT FUNCTSET82 = b'00111000' ; 8-bit mode, 2 lines
|
|
CONSTANT FUNCTSET41 = b'00100000' ; 4-bit mode, 1 lines
|
|
CONSTANT FUNCTSET42 = b'00101000' ; 4-bit mode, 2 lines
|
|
CONSTANT DDZERO = b'10000000' ; WRITE 0 to DDRAM
|
|
|
|
CONSTANT LCDSH = b'00000110'
|
|
|
|
;Commands for working with LCD display
|
|
CONSTANT LCDCLR = b'00000001' ;Clear display, cursor home
|
|
CONSTANT LCDCH = b'00000010' ;Cursor home
|
|
CONSTANT LCDCL = b'00001000' ;Move cursor to the left
|
|
CONSTANT LCDCR = b'00001010' ;Move cursor to the right
|
|
CONSTANT LCDSL = b'00011000' ;Move the content of display to the left
|
|
CONSTANT LCDSR = b'00011100' ;Move the content of display to the right
|
|
CONSTANT LCDCOU = b'00001110' ;Turn on visible underline cursor
|
|
CONSTANT LCDCOB = b'00001111' ;Turn on visible blinking-block cursor
|
|
CONSTANT LCDCONT = b'00001100' ;Make cursor invisible
|
|
CONSTANT LCDL1 = b'10000000' ;Select line 1
|
|
CONSTANT LCDL2 = b'11000000' ;Select line 2
|
|
|
|
;*************************************************************************
|
|
;
|
|
;
|
|
;*************************************************************************
|
|
|
|
LCD_init macro
|
|
; Begin the LCD initialisation
|
|
; Power up timer should give delay, but do it anyway
|
|
movlw 0x14
|
|
call delay
|
|
|
|
; Send the command to select 4-bit mode first
|
|
bcf PORTB, LCD_RS
|
|
bcf PORTB, LCD_RW
|
|
movlw 0x02 ; Still in 8-bit, so appears as 0x20 to LCD
|
|
call LCD_data
|
|
call LCD_pulse_e
|
|
|
|
; Should now be in 4-bit mode - send init
|
|
LCD_cmd FUNCTSET42
|
|
LCD_cmd LCDCOU
|
|
LCD_cmd LCDSH
|
|
endm
|
|
|
|
;*************************************************************************
|
|
;
|
|
;
|
|
;*************************************************************************
|
|
|
|
LCD_cmd macro lcddata
|
|
bcf PORTB, LCD_RS ; Command mode
|
|
movlw lcddata ; Send cmd
|
|
call LCD_SendW
|
|
bsf PORTB, LCD_RS ; Data mode
|
|
call delay_1ms ; Takes a couple of ms
|
|
endm
|
|
|
|
LCD_printC macro lcddata
|
|
movlw lcddata
|
|
call LCD_SendW
|
|
endm
|
|
|
|
|
|
LCD_println macro select, text ;This macro prints text parameter of up to
|
|
;24 characters from the current cursor
|
|
local Message ;position
|
|
local Start
|
|
local Exit
|
|
local i=0
|
|
goto Start
|
|
dt text ;Form a lookup table from parameters
|
|
dt 0
|
|
Start
|
|
if select==1
|
|
LCD_cmd LCDL1
|
|
else
|
|
if select==2
|
|
LCD_cmd LCDL2
|
|
endif
|
|
endif
|
|
while i<24 ;Conditional program translation - repeat 24x
|
|
call Message+1 ;Read lookup table and store value to W
|
|
addlw 0
|
|
bz Exit ;until it reads zero
|
|
call LCD_data ;Call the routine that prints W on LCD
|
|
i=i+1
|
|
endw
|
|
Exit
|
|
endm
|
|
;*************************************************************************
|
|
;
|
|
;
|
|
;*************************************************************************
|
|
|
|
LCD_SendW:
|
|
movwf R_SEND_W_TMP
|
|
swapf R_SEND_W_TMP, F
|
|
movlw 0x0F
|
|
andwf R_SEND_W_TMP, W
|
|
call LCD_data
|
|
call LCD_pulse_e
|
|
|
|
swapf R_SEND_W_TMP, F
|
|
movlw 0x0F
|
|
andwf R_SEND_W_TMP, W
|
|
call LCD_data
|
|
call LCD_pulse_e
|
|
return
|
|
|
|
LCD_data:
|
|
movwf R_WDATA_TMP1
|
|
movf PORTB, W
|
|
movwf R_WDATA_TMP2
|
|
bcf R_WDATA_TMP2, LCD_D4
|
|
bcf R_WDATA_TMP2, LCD_D5
|
|
bcf R_WDATA_TMP2, LCD_D6
|
|
bcf R_WDATA_TMP2, LCD_D7
|
|
btfsc R_WDATA_TMP1, 0
|
|
bsf R_WDATA_TMP2, LCD_D4
|
|
btfsc R_WDATA_TMP1, 1
|
|
bsf R_WDATA_TMP2, LCD_D5
|
|
btfsc R_WDATA_TMP1, 2
|
|
bsf R_WDATA_TMP2, LCD_D6
|
|
btfsc R_WDATA_TMP1, 3
|
|
bsf R_WDATA_TMP2, LCD_D7
|
|
movf R_WDATA_TMP2, W
|
|
movwf PORTB
|
|
|
|
return
|
|
|
|
LCD_pulse_e
|
|
bsf PORTB, LCD_E
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
bcf PORTB, LCD_E
|
|
call delay_1ms
|
|
call delay_1ms
|
|
return
|
|
|
|
; Calls the delay_1ms routine the number of times specified by
|
|
; the W register.
|
|
delay
|
|
movwf R_DEL2
|
|
delay_loop
|
|
call delay_1ms
|
|
decfsz R_DEL2, F
|
|
goto delay_loop
|
|
return
|
|
|
|
; When called gives a delay of about 1000 cycles, or 1ms at 4Mhz
|
|
; before the next instruction is executed.
|
|
delay_1ms
|
|
movlw d'248'
|
|
movwf R_DEL1
|
|
delay_1ms_loop
|
|
nop
|
|
decfsz R_DEL1, F
|
|
goto delay_1ms_loop
|
|
return |