zutil-asm/lcd.inc
2008-11-14 16:38:36 +00:00

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