Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
05/04/06 12:24
Read: times


 
#115560 - I'm feeling generous
Responding to: ???'s previous message
I normally don't reward people that don't search! I'm feeling generous today. Simply stating '51 and lcd doesn't necesarily give us enough information. The code for lcds is timing critical and is normally written for a particular variant and speed cpu.

This code is good for a 12 clock cpu up to around 22MHz or a 6 clock cpu at 11MHz.




[pre]
$mod52
;
rom equ 0000h
;
; R/W on lcd connects to 0V
; the contrast pin needs to have a pot of around 10k connected to it.
; adjust the pot so that you get a black line in the display before initialisation
; then adjust for best contrast when operating. The value is usually fairly close to 0V
; the lcd is connected in 4 bit mode and we use delays rather than poll for busy status
; from the lcd. Therefore we use only 6 port pins
;
LCD_D0 equ P1.0 ;connects to lcd data 4
LCD_D1 equ P1.1 ; 5
LCD_D2 equ P1.2 ; 6
LCD_D3 equ P1.3 ; 7
LCD_DEN equ P1.4
LCD_RS equ P1.5

;
; internal ram vars
;
stack equ 60h


;
;
; Start of rom vectors
;
org rom
ljmp begin
; org rom+3h
; ljmp int0_isr ;no external int 0
; org rom+bh
; ljmp timer0_isr ;no timer 0 int
; org rom+13h
; ljmp int1_isr ;no external int 1
; org rom+1bh
; ljmp timer1_isr ;no timer 1 ints
; org rom+23h
; ljmp serial_isr ;no serial ints
;
;
; Start of code
;
;
org rom+40h
;
; init the serial port & timers
;
begin:
mov sp,#stack ;load stack ptr
;
; clear mem & init vars
;
mov r0,#01h ;->ram
clr a
mem_clr1:
mov @r0,a ;clear loc'n
inc r0 ;++->
cjne r0,#80h,mem_clr1 ;end?
;
; init the lcd display
;
acall lcd_init
;
; log on message
;
mov a,#0
acall lcd_locate_cursor
mov dptr,#logon_msg
acall lcd_pstring
the_end:
sjmp the_end

logon_msg:
db 'Hello world',0 ;the '0' is the end of the string
;-----------------------------------------------------------------------------
;
;
; DPTR -> zero terminated string. writes the string to the serial port
;
;
;-----------------------------------------------------------------------------
pstring:
clr a
movc a,@a+dptr
jz ps_x
acall pchar
inc dptr
sjmp pstring
ps_x:
ret
;-----------------------------------------------------------------------------
;
;
; send A out the serial port
;
;
;-----------------------------------------------------------------------------
pchar:
clr scon.1
mov sbuf,a
pc_1:
jnb scon.1,pc_1
ret
;-----------------------------------------------------------------------------
;
; print hex in A
;
;-----------------------------------------------------------------------------
phex:
push acc
swap a
acall l_hex
pop acc
l_hex:
anl a,#0fh
add a,#30h
cjne a,#3Ah,lh_1
lh_1:
jc lh_2 ;if a<=$39
add a,#7
lh_2:
acall pchar
ret
;----------------------------------------------------------------------------
;
;
; print messages on the lcd display.
; Dptr-> message in rom terminated by 00h
;
;
;----------------------------------------------------------------------------
lcd_pstring:
clr a
movc a,@a+dptr
jz lcdp_2
call lcd_data_wr
inc dptr
sjmp lcd_pstring
lcdp_2:
ret
;----------------------------------------------------------------------------
;
;
; Print hex value in A to the lcd display
;
;
;----------------------------------------------------------------------------
lcd_phex:
push acc
swap a
call hex
pop acc
hex:
anl a,#0fh
add a,#30h
cjne a,#3ah,hex_1
hex_1:
jc hex_2
add a,#7
hex_2:
call lcd_data_wr
ret
;----------------------------------------------------------------------------
;
;
; Print packed bcd value in A to the lcd display
;
;
;----------------------------------------------------------------------------
pbcd:
push acc
swap a
anl a,#0fh
add a,#'0'
call lcd_data_wr
pop acc
anl a,#0fh
add a,#'0'
jmp lcd_data_wr
;----------------------------------------------------------------------------
;
;
; print the bcd number in R5:R4:R3 as leading zero supressed
; decimal number on the lcd display
;
;
;----------------------------------------------------------------------------
print_bcd:
clr f0 ;supress flag==0
mov a,r5
acall bcd
mov a,r4
swap a
acall bcd
mov a,r4
acall bcd
mov a,r3
swap a
acall bcd
setb f0 ;always display the last zero
mov a,r3
acall bcd
ret
;
; convert value in A to ascii and display with leading zero supress
;
bcd:
anl a,#0fh
jnz bcd_1
jb f0,bcd_1
mov a,#' '
acall lcd_data_wr
ret
bcd_1:
setb f0
add a,#'0'
acall lcd_data_wr
ret

acall lcd_data_wr
;----------------------------------------------------------------------------
;
;
; initialise the lcd display
;
;
;----------------------------------------------------------------------------
lcd_init:
clr LCD_RS
clr LCD_DEN
mov a,#0
acall write_nibble
;
; delay 2mS
;
; mov a,#20 ; 20 * 100uS =2mS
mov a,#150 ; delay 15mS for startup
call delay


mov a,#03h
acall write_nibble
nop
nop
setb LCD_DEN
nop
nop
nop
nop
nop
nop
clr LCD_DEN
;
; delay 1mS
;
mov a,#50 ; 10 * 100uS =1mS
call delay
setb LCD_DEN
nop
nop
nop
nop
nop
nop
nop
clr LCD_DEN
;
; delay 1mS
;
mov a,#50 ; 10 * 100uS =1mS
call delay
setb LCD_DEN
nop
nop
nop
nop
clr LCD_DEN
;
; delay 1mS
;
mov a,#10 ; 10 * 100uS =1mS
call delay
mov a,#02h
acall write_nibble
nop
setb LCD_DEN
nop
nop
nop
nop
clr LCD_DEN
;
; delay 1mS
;
mov a,#10 ; 10 * 100uS =1mS
call delay
mov a,#2ch ; 2 line mode
call lcd_comm_wr ; write lcd command
;
; delay 1mS
;
mov a,#10 ; 10 * 100uS =1mS
call delay
mov a,#0ch ; display on,cursor off
call lcd_comm_wr ; write lcd command
;
; delay 1mS
;
mov a,#10 ; 10 * 100uS =1mS
call delay
mov a,#06h ; auto inc,shift right
call lcd_comm_wr ; write lcd command
mov a,#10 ; 10 * 100uS =1mS
call delay
mov a,#01h
call lcd_comm_wr ; clear the display
;
; delay 1mS
;
mov a,#18 ; 18 * 100uS =1.8mS
call delay
ret
;----------------------------------------------------------------------------
;
; Locate the lcd cursor. lcd_comm_wr routine must follow below!
; Cursor position in A
; zaps: A,B
;
;
;----------------------------------------------------------------------------
lcd_locate_cursor:
cjne a,#16,lc_1
lc_1:
jc lc_2 ; if location < 16 (line #1)
add a,#30h ; else add offset for 2nd line
lc_2:
setb acc.7 ; set bit 7 for locate cursor cmd
;----------------------------------------------------------------------------
;
;
; send a command to the lcd display. command in A
; Zaps: A,B
;
;----------------------------------------------------------------------------
lcd_comm_wr:
mov b,a ;save the command
swap a
anl a,#0fh ;get hi nibble
acall write_nibble
clr LCD_RS
nop
nop
setb LCD_DEN
nop
nop
nop
nop
clr LCD_DEN
mov a,b ;get cmd again
anl a,#0fh ;mask for low nibble
acall write_nibble
nop
setb LCD_DEN
nop
nop
nop
nop
nop
nop
nop
clr LCD_DEN
;
; delay for lcd controller
;
mov b,#200 ;at least 40uS
lcw_1:
djnz b,lcw_1 ;waste some time
mov b,#100 ;at least 40uS
lcw_2:
djnz b,lcw_2 ;waste some time
ret
;******************************************************************************
;
;
; send data to the lcd display. command in A
; zaps: A,B
;
;
;******************************************************************************
lcd_data_wr:
mov b,a ;save the data
swap a
anl a,#0fh ;get hi nibble
acall write_nibble
setb LCD_RS
nop
nop
nop
setb LCD_DEN
nop
nop
nop
nop
nop
clr LCD_DEN
mov a,b ;get data again
anl a,#0fh ;mask for low nibble
acall write_nibble
nop
nop
nop
setb LCD_DEN
nop
nop
nop
nop
nop
nop
nop
clr LCD_DEN
;
; delay for lcd controller
;
mov b,#200 ;at least 40uS
ldrw_1:
djnz b,ldrw_1 ;waste some time
mov b,#100 ;at least 40uS
ldrw_2:
djnz b,ldrw_2 ;waste some time
ret

;----------------------------------------------------------------------------
;
;write nibble
; writes nibble (lower 4 bits)of A to the lcd data pins
; zaps: Carry flag
;
;----------------------------------------------------------------------------
write_nibble:
mov c,acc.0
mov LCD_D0,c
mov c,acc.1
mov LCD_D1,c
mov c,acc.2
mov LCD_D2,c
mov c,acc.3
mov LCD_D3,c
ret
;----------------------------------------------------------------------------
;
;
; Delay routine. A has # of 100 microseconds to delay
; zaps: A,B
;
;
;----------------------------------------------------------------------------
delay:
mov b,#80 ;for ds80c320 (50 for normal)
dly_1:
djnz b,dly_1
djnz acc,delay
ret

end
[/pre]


List of 9 messages in thread
TopicAuthorDate
LCD interface            01/01/70 00:00      
   Didn't Search First            01/01/70 00:00      
      I'm feeling generous            01/01/70 00:00      
         Where is lh_2 defined in phex routing?            01/01/70 00:00      
            Maybe it's a test...?            01/01/70 00:00      
               Finger trubble methinks            01/01/70 00:00      
                  Walso be there            01/01/70 00:00      
                     lh_2 Found. Sorry for confusion.            01/01/70 00:00      
   LCD FAQs            01/01/70 00:00      

Back to Subject List