;******************************************************************
; *
; *
;******************************************************************
#include <p16f690.inc>
radix dec
__config _FCMEN_OFF& _IESO_OFF& _MCLRE_OFF& _WDT_OFF& _INTOSCIO
; _FCMEN_OFF ; -- fail safe clock monitor enable off
; _IESO_OFF ; -- int/ext switch over enable off
; _BOR_ON ; default, brown out reset on
; _CPD_OFF ; default, data eeprom protection off
; _CP_OFF ; default, program code protection off
; _MCLR_OFF ; -- use MCLR pin as digital input
; _PWRTE_OFF ; default, power up timer off
; _WDT_OFF ; -- watch dog timer off
; _INTOSCIO ; -- internal osc, OSC1 and OSC2 I/O
;
; variables
;
temp equ 0x20 ; Put LCD variable
delayhi equ 0x21 ; DelayCy() subsystem variable
;
; defines and constants
;
line1 equ 128+0 ; LCD "line 1" command
line2 equ 128+64 ; LCD "line 2" command
;******************************************************************
; K8LH DelayCy() subsystem macro generates four instructions *
;******************************************************************
radix dec
clock equ 4 ; 4, 8, 12, 16, 20 (MHz), etc.
usecs equ clock/4 ; cycles/microsecond multiplier
msecs equ clock/4*1000 ; cycles/millisecond multiplier
DelayCy macro delay ; 11..327690 cycle range
movlw high((delay-11)/5)+1
movwf delayhi
movlw low ((delay-11)/5)
call uDelay-((delay-11)%5)
endm
;******************************************************************
; reset vector *
;******************************************************************
org 0x000
v_reset
clrf STATUS ; force bank 0 and IRP = 0 |B0
goto Init ; |B0
;******************************************************************
; interrupt vector *
;******************************************************************
org 0x004
v_interrupt
retfie ;
;******************************************************************
; LCD "Put" subroutines (hardcoded for LCD D7..D4 on RC3..RC0, *
; LCD RS on RC4, and LCD E on RC7) *
;******************************************************************
PutCMD ; entry point for "cmd" data
clrc ; RS = 0 (command) |B0
skpnc ; |B0
PutDAT ; entry point for "dat" data
setc ; RS = 1 (data) |B0
movwf temp ; save WREG data byte |B0
swapf temp,W ; hi nybble in b3..b0 |B0
call PutNyb ; send left nybble |B0
movf temp,W ; lo nybble in b3..b0 |B0
call PutNyb ; send right nybble |B0
DelayCy(60*usecs) ; 60 usec delay |B0
return ; |B0
PutNyb
andlw 0x0F ; mask off left nybble |B0
skpnc ; C=0 (RS=0)? yes, skip, else |B0
iorlw b'00010000' ; set lcd RS bit (RC4) |B0
movwf PORTC ; assert D7..D4 & RS pins |B0
iorlw b'10000000' ; set lcd E bit (RC7) |B0
movwf PORTC ; E = 1 (strobe) |B0
xorlw b'10000000' ; clr lcd E bit (RC7) |B0
movwf PORTC ; E = 0 |B0
return ; |B0
;******************************************************************
; K8LH DelayCy() subsystem 16-bit uDelay(11..327690 cycle) sub' *
;******************************************************************
nop ; entry for (delay-11)%5 == 4 |B0
nop ; entry for (delay-11)%5 == 3 |B0
nop ; entry for (delay-11)%5 == 2 |B0
nop ; entry for (delay-11)%5 == 1 |B0
uDelay addlw -1 ; subtract 5 cycle loop time |B0
skpc ; borrow? no, skip, else |B0
decfsz delayhi,F ; done? yes, skip, else |B0
goto uDelay ; do another loop |B0
return ; |B0
;******************************************************************
; main init *
;******************************************************************
Init
bsf STATUS,RP1 ; bank 2 |B2
clrf ANSEL ; turn off analog pin functions |B2
clrf ANSELH ; |B2
bcf STATUS,RP1 ; bank 0 |B0
bsf STATUS,RP0 ; bank 1 |B1
; movlw b'01110000' ; setup INTOSC for 8-MHz |B1
; movwf OSCCON ; |B1
; btfss OSCCON,HTS ; osc stable? yes, skip, else |B1
; goto $-1 ; test again |B1
clrf TRISC ; RC7..RC0 all outputs |B1
movlw b'00001000' ; RA3 input, all others outputs |B1
movwf TRISA ; |B1
bcf STATUS,RP0 ; bank 0 |B0
clrf PORTA ; |B0
clrf PORTC ; |B0
[COLOR=Blue];
; HD44780 LCD 4-bit interface initialization procedure
;
DelayCy(30*msecs) ; delay 30-msecs after power up |B0
movlw 0x03 ; step 1, "function set" 8-bit |B0
call PutNyb ; write 4-bits only |B0
DelayCy(5*msecs) ; required 5-msec delay |B0
movlw 0x03 ; step 2, "function set" 8-bit |B0
call PutNyb ; write 4-bits only |B0
DelayCy(160*usecs) ; required 160-usec delay |B0
movlw 0x03 ; step 3, "function set" 8-bit |B0
call PutNyb ; write 4-bits only |B0
DelayCy(160*usecs) ; required 160-usec delay |B0
movlw 0x02 ; step 4, "function set" 4-bit |B0
call PutNyb ; write 4-bits only |B0
DelayCy(160*usecs) ; required 160-usec delay |B0
;
; now we're in 4-bit mode and can handle 8-bit transactions
;
movlw b'00101000' ; 4-bit, 2-lines, 5x7 font |B0
call PutCMD ; send "function set" command |B0
movlw b'00001000' ; display, cursor, blink all off |B0
call PutCMD ; send "display on/off" command |B0
movlw b'00000001' ; clear display (1.53-msecs) |B0
call PutCMD ; send "entry mode set" command |B0
DelayCy(1500*usecs) ; required 1.53-msec delay |B0
movlw b'00000110' ; cursor inc, shift off |B0
call PutCMD ; send "entry mode set" command |B0
movlw b'00001100' ; display on, leave cursor off |B0
call PutCMD ; send "display on/off" command |B0
[/COLOR]
;******************************************************************
; main loop *
;******************************************************************
Loop
movlw line1+0 ; line 1, tab 0 |B0
call PutCMD ; |B0
movlw 'H' ; send "Hello World" to LCD |B0
call PutDAT ; |B0
movlw 'e' ; |B0
call PutDAT ; |B0
movlw 'l' ; |B0
call PutDAT ; |B0
movlw 'l' ; |B0
call PutDAT ; |B0
movlw 'o' ; |B0
call PutDAT ; |B0
movlw ' ' ; |B0
call PutDAT ; |B0
movlw 'W' ; |B0
call PutDAT ; |B0
movlw 'o' ; |B0
call PutDAT ; |B0
movlw 'r' ; |B0
call PutDAT ; |B0
movlw 'l' ; |B0
call PutDAT ; |B0
movlw 'd' ; |B0
call PutDAT ; |B0
;
goto $ ; loop forever |B0
;******************************************************************
end
Nigel, what LCD did you use, or what LCD's has any one else used for this code?
Mike, thanks for your reply but I am only using a 2 port pic, it looks a mamoth job to change your code to work on 2 port pic.
;Initialise LCD
LCD_Init
[COLOR=Red]movlw 0x02 ; Set 4 bit mode
call LCD_Nyb ; <---[/COLOR]
movlw 0x28 ;Set display shift
call LCD_Cmd
movlw 0x06 ;Set display character mode
call LCD_Cmd
movlw 0x0d ;Set display on/off and cursor command
call LCD_Cmd
call LCD_Clr ;clear display
retlw 0x00
; command set routine
LCD_Cmd
movwf templcd
swapf templcd,w ;send upper nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bcf LCD_PORT,LCD_RS ;RS line to 0
call Pulse_e ;Pulse the E line high
movf templcd,w ;send lower nibble
[COLOR=Red]LCD_Nyb[/COLOR]
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bcf LCD_PORT,LCD_RS ;RS line to 0
call Pulse_e ;Pulse the E line high
call Delay5
retlw 0x00
Well I've never heard of any such changes required, nor seen any datasheets which specify that - including the datasheet for the module in question linked above. But I hope it works.
Perhaps someone could show a way of using or modifying nigels software showing or explaining how an initilisation is carried out in the software.
Thanks for all your help.
It appears that this may be a common problem erienced by others using nigels software, i have seen others on forums and this forum experiencing similar issues.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?