Tutoriales

Curso Básico AVR AT90S1200 - Página 2


Programa de control de una LCD 16x2

Ahora les dejo un programa más avanzado, en el que se hace uso de una LCD 16x2 y en ella se muestra un conteo de 0 a 9 usando el AVR.

Antes de seguir les hago una recomendación, siempre trabajen registros desde el número 16 hasta el 31, ya que estos pueden ser trabajados con direccionamiento inmediato. Luego les diré que onda con los otros del 0 al 15.

En el programa se ven instrucciones nuevas:

LDI R16,$38
Esta instrucción carga de modo inmediato el valor hexa 38 en el registro 16. Si quisieran cargar el dato decimal 10, sólo pongan:

LDI R16,10
MOV R16,R20
Aquí el valor del R20 pasa al R16.

CPI R20,$3a
Hace una comparación inmediata mediante una resta: R20 - 3A. Esto levanta banderas en el registro STATUS.

BRNE loop
Branch if Not Equal. Brinca si no es igual, es decir, si Z=0; en ese caso se va a loop.

CBI PORTD,0
Clear Bit, pone a cero un bit de algún registro de entrada/salida. En este caso pone a cero el bit cero.

Es importante que CBI y SBI sólo se usen en registros de entrada/salida que estén en el rango de 00 a 1F, ya que en los demás no funcionan. Para modificar el contenido de los demás, sería conveniente usar un LDI a algún registro y luego un OUT hacia el registro e/s.

Bueno, pues les dejo el código:
--------------------------------------------------------
;MigSantiago
;Contador de 0-9 en LCD de 16x2
;RB0-RB7 son DB0-DB7
;RD0 es RS
;RD1 es E
;R20 conteo ASCII
;R17,18,19 Subrutinas tiempo
 
.org 0000
.include "1200def.inc"
 
;Establece E/S
SER R16
OUT DDRB,R16 ;portb salida
OUT DDRD,R16 ;portd salida
RCALL unseg ;espera inicio de LCD 1seg
 
;Configura LCD
LDI R16,$38
RCALL instru ;8-bit,2 líneas, 5x7
LDI R16,$0e
RCALL instru ;D=1,C=1,B=0
LDI R16,$06
RCALL instru ;incremento, no desplaza texto
LDI R16,$01
RCALL instru ;limpia LCD
 
;Escritura de 0-9
cero: LDI R20,$30 ;cero en ASCII
loop: MOV R16,R20 ;prepara conteo ASCII a mandar
RCALL dato ;manda ASCII a LCD
RCALL unseg ;espera 1 seg
LDI R16,$80 ;va a home
RCALL instru
INC R20
CPI R20,$3a ;si es 3a se va a cero
BRNE loop
RJMP cero
 
;Subrutina: instrucción a LCD
instru: CBI PORTD,0 ;RS=0
RJMP envio
;Subrutina: dato a LCD
dato: SBI PORTD,0 ;RS=1
RJMP envio
;Subrutina: envía dato o inst a LCD
envio: SBI PORTD,1 ;E=1
OUT PORTB,R16 ;Saca R16 por B
RCALL dosms ;espera 2ms escritura
CBI PORTD,1 ;E=0
RCALL dosms ;espera proceso
RET
 
;Subrutina de 2ms
; 8000 cycles:
; -----------------------------
; delaying 7998 cycles:
dosms: ldi R17, $1f
WGLOOP0: ldi R18, $55
WGLOOP1: dec R18
brne WGLOOP1
dec R17
brne WGLOOP0
; -----------------------------
; delaying 2 cycles:
nop
ret
; =============================
 
;Subrutina de 1seg
; 4000000 cycles:
; -----------------------------
; delaying 3999996 cycles:
unseg: ldi R17, $24
WGLOOP3: ldi R18, $BC
WGLOOP4: ldi R19, $C4
WGLOOP5: dec R19
brne WGLOOP5
dec R18
brne WGLOOP4
dec R17
brne WGLOOP3
; -----------------------------
; delaying 3 cycles:
ldi R17, $01
WGLOOP6: dec R17
brne WGLOOP6
; -----------------------------
; delaying 1 cycle:
ret
; =============================

--------------------------------------------------------