Programa de visualización MCU LCD1602 (ensamblaje), no entiendo muchas cosas. Espero que los expertos puedan agregar comentarios para ayudarme a aprender.
; Demostración del controlador de pantalla LCD.
; El código de temporización supone un reloj de 1,2 MHz
;LCD registra direcciones
LCD_CMD_WR equ 0; Definición
LCD_DATA_WR equ 1
LCD_BUSY_RD equ 2
LCD_DATA_RD equ 3
;Comandos LCD
LCD_CLS equ 1
LCD_HOME equ 2
LCD_SETMODE equ 4
LCD_SETVISIBLE equ 8
LCD_SHIFT equ 16
LCD_SETFUNCTION equ 32
LCD_SETCGADDR equ 64
LCD_SETDDADDR equ 128
;Restablecer vector
org 0000h;Dirección de entrada de inicio del programa 0x00
jmp start; saltar al inicio
;Inicio del programa
org 0100h
string1a:db ' !! A M A Z I N G !! el contenido a mostrar.
db 0
string1b:db '!! ¡¡INCREÍBLE !! '
db 0
string2:db ' Un LM032L virtual. .. '
db 0
string3:db ' impulsado por un procesador virtual '
db 0
string4:db ' 8051 !'
db 0
start: mov A,#038h ;¿Por qué son 38h? Consulte el manual de datos 1602, el comando 38h
llame a wrcmd
bucle: mov A,#LCD_SETVISIBLE+6 ;Hacer visible la pantalla y el parpadeo:
llamar a wrcmd
mov R7,#2
loop2:
mov DPTR,#string1a
llamar a wrstr
mov DPTR,#200
llamar a wtms
mov A,#LCD_CLS ;Borrar pantalla
llamar a wrcmd
mov DPTR,#string1b
llamar a wrstr
mov DPTR, #200
llamar a wtms
mov A,#LCD_CLS ;Borrar pantalla
llamar a wrcmd
djnz R7,loop2
mov DPTR,#string1a
llamar a wrstr
mov DPTR,#400
llamar a wtms
mov A,#LCD_SETDDADDR +64
llamar a wrcmd
mov DPTR,#string2
llamar a wrslow
mov DPTR,#200
llamar a wtms
mov A,#LCD_CLS ;Borrar pantalla
llamar a wrcmd
mov DPTR,#string3
llamar a wrslow p>
mov A,#LCD_SETDDADDR+64
llamar a wrcmd
mov DPTR,#string4
llamar a wrslow
mov A, #LCD_SETVISIBLE+7 ;Muestra también el cursor parpadeante.
llamar a wrcmd
mov DPTR,#2000
llamar a wtms
mov A,#LCD_CLS ;Borrar pantalla
llamar a wrcmd
bucle jmp
;Subrutina para escribir una cadena terminada en nulo en DPTR en la RAM del programa. p>
wrstr: mov R0,#LCD_DATA_WR
wrstr1: clr A
movc A,@A+DPTR
jz wrstr2
movx @R0,A
llamar a wtbusy
inc DPTR
empujar DPL
empujar DPH p> p>
pop DPH
pop DPL
jmp wrstr1
wrstr2: ret
;Subrutina para escribir nulo Cadena terminada en DPTR en la RAM del programa Lentamente
wrslow: mov R0,#LCD_DATA_WR
wrslw1: clr A
movc A,@A+DPTR
jz wrslw2
movx @R0,A
llamar a wtbusy
inc DPTR
empujar DPL
empujar DPH
mov DPTR,#100
llamar a wtms
pop DPH
pop DPL
jmp wrslw1
wrslw2: ret
;Subrutina para escribir comando:
wrcmd: mov R0,#LCD_CMD_WR
movx @ R0, A
jmp wtbusy
;Subrutina para escribir carácter:
wrchar: mov R0,#LCD_DATA_WR
movx @R0 ,A
;Subrutina para esperar a que se despeje ocupado
wtbusy: mov R1,#LCD_BUSY_RD
movx A,@r1
jb ACC. 7,wtbusy
ret
;Esperar el número de segundos en A
wtsec: pulsar ACC
llamar a wtms p>
pop ACC
dec A
jnz wtsec
ret
;Esperar el número de milisegundos en DPTR p>
wtms: xrl DPL,#0FFh ;No se puede hacer DEC DPTR, así que haz el ciclo formando el complemento a 2
xrl DPH,#0FFh ;e incrementando en su lugar.
inc DPTR
wtms1: mov TL0,#09Ch ;100 ticks antes del desbordamiento = 1ms a 1.2MHz Reloj
mov TH0,#0FFh
mov TMOD ,# 1 ;Temporizador 0 modo 1
setb TCON.4 ;El temporizador 0 se ejecuta
wtms2: jnb TCON.5,wtms2
clr TCON.4 ; Temporizador 0 se detiene
clr TCON.5
inc DPTR
mov A,DPL
orl A,DPH
p>
jnz wtms1
ret
END