Escuela Politécnica Nacional
Control con Microprocesadores
Inicialización de un LCD en assembler
Cristian Alexander Bonilla Gr1
Enunciado
Realizar la rutina de inicialización de un módulo LCD 16x2 en lenguaje ensamblador
Diagrama de flujo
Definir que pines del microcontrolador irán conectados al LCD
Definir las instrucciones a ser usadas, usando la tabla
de instrucciones del LCD
Inicializar el LCD
Escribir en la primera línea Hola C. Bonilla
Escribir en la segunda línea Control M. GR1
Fin
Escuela Politécnica Nacional
Simulación del programa
Se procedió a escribir Hola mas mi nombre, materia y paralelo, comprobando el correcto
funcionamiento del display LCD
Al presionar la interrupción 0
Al presionar la interrupción 1
Escuela Politécnica Nacional
y finalmente al presionar la interrupción externa 2
Programa hecho en Atmel Studio 7.0 en lenguaje C
;
; lcd_assembler.asm
;
; Created: 03/11/2018 [Link]
; Author : Cristian
;
;Se realiza el manejo a 4 bits (MSB) del LCD
;Como no se realizara lectura, solo escritura, el pin RW ira a tierra
;Y este pin no se tomara en cuenta durante la programación
//Frecuencia del oscilador principal
.equ fclk = 8000000
//Nombro pines que se conectan a Data (MSB) del LCD
.equ lcd_D7_port = PORTA // D7
.equ lcd_D7_bit = PORTA7
.equ lcd_D7_ddr = DDRA
Escuela Politécnica Nacional
.equ lcd_D6_port = PORTA // D6
.equ lcd_D6_bit = PORTA6
.equ lcd_D6_ddr = DDRA
.equ lcd_D5_port = PORTA // D5
.equ lcd_D5_bit = PORTA5
.equ lcd_D5_ddr = DDRA
.equ lcd_D4_port = PORTA // D4
.equ lcd_D4_bit = PORTA4
.equ lcd_D4_ddr = DDRA
//Nombro pines de configuracion del LCD
.equ lcd_E_port = PORTA // E
.equ lcd_E_bit = PORTA3
.equ lcd_E_ddr = DDRA
.equ lcd_RS_port = PORTA // RS
.equ lcd_RS_bit = PORTA2
.equ lcd_RS_ddr = DDRA
//Nombro las filas del LCD
.equ lcd_Fila1 = 0x00 // Fila 1
.equ lcd_Fila2 = 0x40 // Fila 2
//Lista de instrucciones para manejo del LCD
.equ lcd_Clear = 0b00000001 // Limpia la pantalla
.equ lcd_Home = 0b00000010 // Cursor en (0,0)
.equ lcd_EntryMode = 0b00000110 // Desplazamiento incremental (I/D) y mensaje estático
.equ lcd_DisplayOff = 0b00001000 // Apaga pantalla, apaga cursor y apaga parpadeo
.equ lcd_DisplayOn = 0b00001100 // Enciende pantalla , apaga cursor y apaga parpadeo
.equ lcd_FunctionReset = 0b00110000 // Reset del LCD
.equ lcd_FunctionSet4bit = 0b00101000 // Funcionamiento a 4 bits, 2 lineas y fuente de
puntos 5x7
.equ lcd_SetCursor = 0b10000000 // Ajusta la direccion de la DDRam (mueve cursor)
//Nombro registro r16 como tempo
.def tempo = r16
// Programa
.cseg
.org 0x00
rjmp inicio
.org 0x02
rjmp msg1
.org 0x04
rjmp msg2
.org 0x06
rjmp msg3
.org INT_VECTORS_SIZE
Nombre: .db "Hola C. Bonilla"
Materia: .db "Control M. GR1 "
Mensaje1: .db "Soy el mensaje 1"
Mensaje2: .db "Soy el mensaje 2"
Mensaje3: .db "Soy el mensaje 3"
Escuela Politécnica Nacional
MCL: .db " "
inicio:
//Inicializar puertos del LCD
//Datos como salida
sbi lcd_D7_ddr, lcd_D7_bit
sbi lcd_D6_ddr, lcd_D6_bit
sbi lcd_D5_ddr, lcd_D5_bit
sbi lcd_D4_ddr, lcd_D4_bit
//Pines de config como saida
sbi lcd_E_ddr, lcd_E_bit
sbi lcd_RS_ddr, lcd_RS_bit
//Inicializar stack
ldi tempo, high(ramend)
out sph, tempo
ldi tempo, low(ramend)
out spl, tempo
//Interrrupciones externas
ldi tempo, 0b00111111
sts eicra, tempo
ldi tempo, 0b00000111
out eimsk, tempo
//Inicializacion del LCD a 4 bits
rcall lcd_begin_4b
ldi zh, high(Nombre)
ldi zl, low(Nombre)
ldi tempo, lcd_Fila1
rcall lcd_write_string_4d
ldi zh, high(Materia)
ldi zl, low(Materia)
ldi tempo, lcd_Fila2
rcall lcd_write_string_4d
sei
principal:
rjmp principal
lcd_begin_4b:
ldi tempo, 100
rcall delayTx1ms
//Habilito RS y E
cbi lcd_RS_port, lcd_RS_bit
cbi lcd_E_port, lcd_E_bit
//Reseteo el LCD
ldi tempo, lcd_FunctionReset
rcall lcd_write_4
ldi tempo, 10
rcall delayTx1ms
/*ldi tempo, lcd_FunctionReset
rcall lcd_write_4
ldi tempo, 200
rcall delayTx1us
ldi tempo, lcd_FunctionReset
rcall lcd_write_4
ldi tempo, 200
Escuela Politécnica Nacional
rcall delayTx1us
//Coloco el LCD a 4bits*/
ldi tempo, lcd_FunctionSet4bit
rcall lcd_write_4
ldi tempo, 80
rcall delayTx1us
//Se escribe las instrucciones
ldi tempo, lcd_FunctionSet4bit
rcall lcd_write_instruction_4d
ldi tempo, 80
rcall delayTx1us
//Se apaga el Control de instrucciones
ldi tempo, lcd_DisplayOff
rcall lcd_write_instruction_4d
ldi tempo, 80
rcall delayTx1us
//Instruccion de limpiado de display
ldi tempo, lcd_Clear
rcall lcd_write_instruction_4d
ldi tempo, 4
rcall delayTx1ms
//Pongo en modo de escritura de instrucciones
ldi tempo, lcd_EntryMode
rcall lcd_write_instruction_4d
ldi tempo, 80
rcall delayTx1us
//Se enciende el control de instrucciones
ldi tempo, lcd_DisplayOn
rcall lcd_write_instruction_4d
ldi tempo, 80
rcall delayTx1us
ret
//Subrutina de escritura
lcd_write_string_4d:
push zl
push zh
lsl zl
rol zh
ori tempo, lcd_SetCursor
rcall lcd_write_instruction_4d
ldi tempo, 80
rcall delayTx1us
lcd_write_string_4d_01:
lpm tempo, z+
cpi tempo, 0
breq lcd_write_string_4d_02
rcall lcd_write_character_4d
ldi tempo, 80
rcall delayTx1us
rjmp lcd_write_string_4d_01
lcd_write_string_4d_02:
pop zh
pop zl
ret
//
lcd_write_character_4d:
sbi lcd_RS_port, lcd_RS_bit
cbi lcd_E_port, lcd_E_bit
Escuela Politécnica Nacional
rcall lcd_write_4
swap tempo
rcall lcd_write_4
ret
//
lcd_write_4:
sbi lcd_D7_port, lcd_D7_bit
sbrs tempo, 7
cbi lcd_D7_port, lcd_D7_bit
sbi lcd_D6_port, lcd_D6_bit
sbrs tempo, 6
cbi lcd_D6_port, lcd_D6_bit
sbi lcd_D5_port, lcd_D5_bit
sbrs tempo, 5
cbi lcd_D5_port, lcd_D5_bit
sbi lcd_D4_port, lcd_D4_bit
sbrs tempo, 4
cbi lcd_D4_port, lcd_D4_bit
sbi lcd_E_port, lcd_E_bit
call delay1uS
cbi lcd_E_port, lcd_E_bit
call delay1uS
ret
lcd_write_instruction_4d:
cbi lcd_RS_port, lcd_RS_bit
cbi lcd_E_port, lcd_E_bit
rcall lcd_write_4
swap tempo
rcall lcd_write_4
ret
delayTx1mS:
call delay1mS
dec tempo
brne delayTx1mS
ret
delay1mS:
push YL
push YH
ldi YL, low (((fclk/1000)-18)/4)
ldi YH, high(((fclk/1000)-18)/4)
delay1mS_01:
sbiw YH:YL, 1
brne delay1mS_01
pop YH
pop YL
ret
delayTx1uS:
call delay1uS
dec tempo
brne delayTx1uS
Escuela Politécnica Nacional
ret
delay1uS:
push tempo
pop tempo
push tempo
pop tempo
ret
msg1:
ldi zh, high(Mensaje1)
ldi zl, low(Mensaje1)
ldi tempo, lcd_Fila1
rcall lcd_write_string_4d
ldi zh, high(MCL)
ldi zl, low(MCL)
ldi tempo, lcd_Fila2
rcall lcd_write_string_4d
reti
msg2:
ldi zh, high(Mensaje2)
ldi zl, low(Mensaje2)
ldi tempo, lcd_Fila1
rcall lcd_write_string_4d
ldi zh, high(MCL)
ldi zl, low(MCL)
ldi tempo, lcd_Fila2
rcall lcd_write_string_4d
reti
msg3:
ldi zh, high(Mensaje3)
ldi zl, low(Mensaje3)
ldi tempo, lcd_Fila1
rcall lcd_write_string_4d
ldi zh, high(MCL)
ldi zl, low(MCL)
ldi tempo, lcd_Fila2
rcall lcd_write_string_4d
reti