Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Quito, Ecuador
imaurisio@hotmail.com
1) Familiarizar al estudiante con el manejo de los E: señal de activación del módulo LCD:
E=0 Módulo desconectado.
displays de cristal líquido (LCD) y las técnicas de barrido
E=1 Módulo conectado.
y decodificación de teclados.
D0-D7: bus de datos bi-direccional. Por medio de
II. CONSULTA estas líneas se realiza la transferencia de información
entre el módulo LCD y el sistema informático que lo
Consultar acerca del display de cristal líquido: gestiona.
E. Set de Instrucciones.
1) 1 dipswitch.
2) 1 decodificador de teclado MM74C922.
Salidas:
1) 2 leds.
2) 1 sirena.
READ DATA FROM CG/DDRAM (RD): “Lee Dato 3) 1 LCD.
desde CG/DDRAM”
Recursos: los recursos usados del microcontrolador
son:
1) Reset manual.
2) Interrupción externa INT0.
3) Puertos digitales.
4) Memoria EEPROM.
F. Características eléctricas.
IV. JUSTIFICACIÓN DEL
Consumo muy reducido de potencia: alrededor de MICROCONTROLADOR A UTILIZAR
7.5mW.
Se eligió al microcontrolador ATMEGA 164P para la
Voltaje de alimentación: 5V. realización de la práctica porque presentaba el suficiente
número de pines para poder implementar el presente
Pin 15 (ánodo de la retroiluminación) : R + 5V. sistema microprocesado. También debido a que poseía
Pin 16 (cátodo de la retroiluminación): GND. todos los recursos para resolver fácilmente el problema.
.cseg
.org 0x0000
inicio:
;se configuran los puertos
ldi tempo,0b00000000
out ddrb,tempo
Fig. 5 Diagrama de flujo del programa. out ddrd,tempo
ldi tempo,0b00000011
VI. REFERENCIAS out ddra,tempo ;puerto a para realizar el
control del LCD
[1] “LCD AVR Pantalla LCD 2x16 con el AVR - ldi tempo,0b11111111
MICROCONTROLADORES.” [Online]. Available: out ddrc,tempo ;puerto c para el bus de
http://microcontroladores-mrelberni.com/lcd-avr/. datos de direcciones del LCD
[Accessed: 30-Nov-2016]. out portb,tempo
out portd,tempo
[2] “LCD Programming Example using ‘C.’” [Online]. ldi tempo,0b11111100
Available: out porta,tempo
http://web.alfredstate.edu/weimandn/programming/lcd/A ldi tempo,0b00000000
Tmega328/LCD_code_gcc_4d.html. [Accessed: 30-Nov- out portc,tempo
2016].
;se configura el pull-up
in tempo,mcucr
[3] “Manejo de display LCD” [Online]. Available:
andi tempo,0b11101111
http://www.bolanosdj.com.ar/SOBRELCD/TEORIALCD
out mcucr,tempo
V1.pdf [Accessed: 30-Nov-2016].
;se configura el stack pointer
[4] “ALPHANUMERIC LCD DISPLAY (16 X 2)” ldi tempo,high(ramend)
[Online]. Available: out sph,tempo
http://www.picaxe.com/docs/LED008.pdf [Accessed: 30- ldi tempo,low(ramend)
Nov-2016]. out spl,tempo
sei
;se configura (inicializa) el LCD. Para esto rcall retardo
se han utilizado los pdf "Instrucciones LCD
(Ingles)" y "Display LCD" (especialmente la ;PASO 4
tabla que esta cbi porta,0 ;se deshabilita el lcd
;en la pagina 10 del primer pdf) que estan ldi tempo,0x38 ;(0b00111000) se envia por
en la carpeta de "Control con Micros". tercera vez la primera instruccion
;Tambien se ha cumplido con el siguiente out portc,tempo
orden estipulado para inicializar el LCD: sbi porta,0 ;se habilita el display
; Deshabilitar display ldi aux,1 ;este valor sera cargado al ocr2a
; Colocar instruccion en la subrutina "retardo" para hacer un
; Habilitar display retardo mayor a 40us, mas precisamente de
; Retardo 64us
; Deshabilitar display rcall retardo
; Colocar instruccion
; Habilitar display ;Los pasos del 1 al 4 sirven para resetear
; Retardo el LCD
; Deshabilitar display
; .... y asi sucesivamente ;PASO 5
cbi porta,0 ;se deshabilita el lcd
; <<< INICIO INICIALIZACION LCD >>> ldi tempo,0x38 ;(0b00111000) se envia por
;al momento que se alimenta el display se cuarta vez la primera instruccion
debe realizar un retardo mayor a 15ms por out portc,tempo
eso se usan estas 4 primeras lineas de sbi porta,0 ;se habilita el display
codigo ldi aux,1 ;este valor sera cargado al ocr2a
;PASO 1 en la subrutina "retardo" para hacer un
ldi aux,255 ;@ - este valor sera cargado al retardo mayor a 40us, mas precisamente de
ocr2a en la subrutina "retardo" para hacer 64us
un retardo mayor a 15ms, mas precisamente de rcall retardo
8.192ms
rcall retardo ;Con la primera instruccion (Function set -
ldi aux,255 ;este valor sera cargado al Establece funcion) 0x38 (0b00111000) se
ocr2a en la subrutina "retardo" para hacer configura lo siguiente:
un retardo mayor a 15ms, mas precisamente de ; 001: function set
8.192ms ; 1: bus de datos de 8 bits
rcall retardo ;& - las lineas que van desde ; 1: se usan las dos lineas del LCD
@ hasta & sirven para hacer un retardo de ; 0: se usan caracteres de 5x7 puntos
16.384ms es decir mayor a 15ms ; 00: no importa el valor de estos bits
;PASO 2 ;PASO 6
cbi porta,0 ;se deshabilita el display. Solo cbi porta,0 ;se deshabilita el lcd
cuando esta habilitado se puede comunicar ldi tempo,0x06 ;(0b00000110) se envia la
con el segunda instruccion
cbi porta,1 ;se selecciona el registro de out portc,tempo
instrucciones sbi porta,0 ;se habilita el display
ldi tempo,0x38 ;(0b00111000) se envia por ldi aux,1 ;este valor sera cargado al ocr2a
primera vez la primera instruccion en la subrutina "retardo" para hacer un
out portc,tempo retardo mayor a 40us, mas precisamente de
sbi porta,0 ;se habilita el display 64us
ldi aux,132 ;este valor sera cargado al rcall retardo
ocr2a en la subrutina "retardo" para hacer
un retardo mayor a 4.1ms, mas precisamente ;Con la segunda instruccion (Entry mode set
de 4.256ms - Establece modo entrada) 0x06 (0b00000110)
rcall retardo se configura lo siguiente:
; 000001: entry mode set
;PASO 3 ; 1: al AC (address counter) se incrementa
cbi porta,0 ;se deshabilita el lcd en 1 después de escribir o leer cada
ldi tempo,0x38 ;(0b00111000) se envia por carácter en/de la DDRAM o CGRAM.
segunda vez la primera instruccion ; 0: no se desplaza el display
out portc,tempo
sbi porta,0 ;se habilita el display ;PASO 7
ldi aux,3 ;este valor sera cargado al ocr2a cbi porta,0 ;se deshabilita el lcd
en la subrutina "retardo" para hacer un ldi tempo,0x0E ;(0b00001110) se envia la
retardo mayor a 100us, mas precisamente de tercera instruccion
128us out portc,tempo
sbi porta,0 ;se habilita el display
ldi aux,1 ;este valor sera cargado al ocr2a lazo:
en la subrutina "retardo" para hacer un ;De aqui en adelante se realiza el codigo
retardo mayor a 40us, mas precisamente de para mostrar los mensajes por el LCD y los
64us retardos seran de 40us
rcall retardo cbi porta,0 ;se deshabilita el lcd
rcall linea_1
;Con la tercera instruccion (Display ON/OFF ldi zl,low(tabla_1<<1) ;se apunta al primer
control - Control de encendido/apagado del elemento de la tabla 1
display) 0x0E (0b00001110) se configura lo ldi zh,high(tabla_1<<1)
siguiente: cbi porta,0 ;se deshabilita el display
; 00001: display ON/OFF control rcall escritura
; 1: se habilita el display cbi porta,0 ;se deshabilita el lcd
; 1: se habilita el cursor (se muestra en rcall linea_2
la posición especificada por el AC) ldi zl,low(tabla_2<<1) ;se apunta al primer
; 0: funcion de parpadeo deshabilitada (el elemento de la tabla 2
caracter que se encuentra en la posición del ldi zh,high(tabla_2<<1)
cursor no parpadea) cbi porta,0 ;se deshabilita el display
rcall escritura
;PASO 8 cbi porta,0 ;se deshabilita el lcd
cbi porta,0 ;se deshabilita el lcd ldi tempo,0x01 ;(0b00000001) se utiliza la
ldi tempo,0x01 ;(0b00000001) se envia la instruccion Clear display para limpiar el
cuarta instruccion display
out portc,tempo out portc,tempo
sbi porta,0 ;se habilita el lcd sbi porta,0 ;se habilita el lcd
ldi aux,53 ;este valor sera cargado al ocr2a ldi aux,53 ;este valor sera cargado al ocr2a
en la subrutina "retardo" para hacer un en la subrutina "retardo" para hacer un
retardo mayor a 1.64ms, mas precisamente de retardo mayor a 1.64ms, mas precisamente de
1.728ms 1.728ms
rcall retardo rcall retardo
rcall retardo_dos
;Con la cuarta instruccion (Clear display - rjmp lazo
Limpiar display) 0x01 (0b00000001) se
configura lo siguiente: linea_1:
; 00000001: limpiar display push R16
in R16,sreg
;La quinta instruccion (Set DDRAM address - push R16
Establece direccion DDRAM) sirve para cbi porta,1 ;se selecciona el registro de
manejar las direcciones del AC es decir para instrucciones
mostrar ldi R16,0x80 ;(0b10000000) se utiliza la
;algun dato en la primera linea o en la instruccion set DDRAM address para mostrar
segunda linea del display. Para displays de dato en la primera linea
2 líneas (N=1) la direccion (ADD) puede ir out portc,R16
de sbi porta,0 ;se habilita el display
;0×00 a 0×27 para la primera línea y de 0×40 ldi aux,1 ;este valor sera cargado al ocr2a
a 0×67 para la segunda línea. Entonces: en la subrutina "retardo" para hacer un
; si se escribe 0x80 (0b10000000) se retardo mayor a 40us, mas precisamente de
configura lo siguiente: 64us
;1: set DDRAM address rcall retardo
;0000000 son los 7 bits restantes (0×00): se pop R16
carga el AC con esta dirección (7 bits), con out sreg,R16
lo se muestra algun dato desde la primera pop R16
linea ret
; si se escribe 0xC0 (0b11000000) se
configura lo siguiente: linea_2:
;1: set DDRAM address push R16
;1000000 son los 7 bits restantes (0×40): se in R16,sreg
carga el AC con esta dirección (7 bits), con push R16
lo se muestra algun dato desde la segunda cbi porta,1 ;se selecciona el registro de
linea instrucciones
;Entonces esta instruccion se la usara mas ldi R16,0xC0 ;(0b11000000) se utiliza la
abajo instruccion set DDRAM address para mostrar
dato en la segunda linea
; <<< FIN INICIALIZACION LCD >>> out portc,R16
sbi porta,0 ;se habilita el display ;se usa el timmer 2 para realizar los
ldi aux,1 ;este valor sera cargado al ocr2a retardos: se hace que este cuente hasta
en la subrutina "retardo" para hacer un cuando exista una igualdad entre el tcnt2 y
retardo mayor a 40us, mas precisamente de el valor fijado en el ocr2a
64us ;Cuando esto ocurra se sale de la subrutina
rcall retardo de retardo. No se usa ninguna interrupcion
pop R16 del timer
out sreg,R16 push R16
pop R16 in R16,sreg
ret push R16
sts ocr2a,aux ;se pone el valor tope hasta
limpiar_lcd: el cual debe contar el timer
cbi porta,1 ;se selecciona el registro de clr aux
instrucciones sts tcnt2,aux ;se limpia el registro del
ldi tempo,0b00000001 contador/timer
out portc,tempo ;se limpia el display ldi aux,0b00000000
sbi porta,0 ;se habilita el lcd sts tccr2a,aux ;modo normal (los
ldi aux,52 ;retardo de alrededor 40us comparadores OC2A y OC2B desconectados),
rcall retardo modo normal del timer
cbi porta,0 ;se deshabilita el lcd ldi aux,0b00000110 ;no se fuerzan las
sbi porta,1 salidas, modo normal del timer, preescalador
ret de 256. Tambien se puede poner esta
instruccion: ldi aux,(1<<cs22)|(1<<cs21)
escritura: sts tccr2b,aux
push R16 ldi aux,0b00000010 ;se limpia la bandera
in R16,sreg OCF2A de la comparacion entre el timer 2 y
push R16 el OCR2A. Tambien se puede poner esta
sbi porta,1 ;se selecciona el registro de instruccion: (1<<ocf2a)
datos out tifr2,aux
mostrar: ldi tempo,0b00000000
lpm R16,z+ sts assr,tempo ;se trabaja en modo sincrono
cpi R16,'.' ;se verifica si se ha terminado (reloj principal de 8MHz)
de mostrar toda la oracion lazo_retardo:
breq salir ;en este lazo se espera hasta que se
out portc,R16 ;se envia el codigo (dato) de produzca una igualdad entre el tcnt2 y el
cada letra al LCD valor fijado en el ocr2a
sbi porta,0 ;se habilita el display in aux,tifr2
ldi aux,1 ;este valor sera cargado al ocr2a sbrs aux,ocf2a ;se salta una linea de codigo
en la subrutina "retardo" para hacer un cuando la bandera ocf2a se ponga en 1L, es
retardo mayor a 40us, mas precisamente de decir cuando haya ocurrido la igualdad entre
64us el tcnt2 y el valor fijado en el ocr2a
rcall retardo rjmp lazo_retardo
cbi porta,0 ;se deshabilita el display ldi aux,0b00000000
rjmp mostrar sts tccr2b,aux ;no se fuerzan las salidas,
salir: modo normal del timer, no preescalador (se
pop R16 detiene el timer)
out sreg,R16 pop R16
pop R16 out sreg,R16
ret pop R16
ret
;Para la subrutina "retardo" se usa reloj de
8MHz (1CM=0.125us) y preescalador de 256 retardo_dos:
;Para saber el valor de retardo realizado, ;este retardo sirve para no ver que el
hacer: cursor no se este movimiendo continuamente
; se obtiene el valor contado por el timer por el LCD
(#CM): cuenta=(#CM)=(ocr2a+1)*256 push R16
; se hace regla de tres: 1CM ---> in R16,sreg
0.125us push R16
; cuenta ---> ? push R17
?=valor de retardo push R18
realizado=(cuenta*0.125us)/1CM ldi R16,255
repite_barrido_uno:
retardo: ldi R17,255
repite_barrido_dos:
ldi R18,255 //esto para poder ver
repite_barrido_tres: datos numéricos en el LCD
dec R18 #include <stdio.h> //otra manera de ver
brne repite_barrido_tres datos de tipo entero y cualquier otro tipo
dec R17 es por medio de esta librería
brne repite_barrido_dos #include "lcd.h" //libreria para poder
dec R16 utilizar el LCD. Tener presente que dicha
brne repite_barrido_uno libreria solo trabaja para enviar los datos
pop R18 y
pop R17 //caracteres al LCD con 4
pop R16 bits, se puede elegir entre el nible alto o
out sreg,R16 el nible bajo del bus de datos del LCD.
pop R16 //Por eso es que
ret se conecto el LCD de la manera que esta en
la simulacion en Proteus
;el punto colocado en las tablas sirve para
saber cuando ya se ha mostrado todo el texto //se definen funciones
de cada tabla void config_puertos(void);
tabla_1: void EEPROM_write(unsigned int uiAddress,
.db " Hola Mauricio ." unsigned char var); //subrutina (funcion)
para escribir la memoria EEPROM
tabla_2: unsigned char EEPROM_read(unsigned int
.db " Anchitipan ." uiAddress); //subrutina (funcion) para leer
la memoria EEPROM
void ingresar_clave(void);
void comprobar_clave(void);
if(menu_circular==1) opcion=2;
{ }
if else
(bajar==0) if(bajar==3)
{ {
_delay_ms(200); _delay_ms(200);
opcion=0; opcion=3;
} }
else else
if(bajar==1) if(bajar==4)
{ {
_delay_ms(200); _delay_ms(200);
opcion=4; lcd_puts("ON led verde"); //se
} muestra el mensaje
else
if(bajar==5) _delay_ms(200);
{
opcion=5;
lcd_clrscr(); //se borra o limpia la }
pantalla y el cursor se lo coloca en la else
primera fila y primera columna if(subir==2)
{
lcd_puts("Leer dipswitch"); //se
muestra el mensaje lcd_clrscr(); //se borra o limpia la
pantalla y el cursor se lo coloca en la
lcd_gotoxy(0,1); //se situa el cursor primera fila y primera columna
en la columna 1 y fila 2
lcd_puts("> Leer dipswitch"); //se
lcd_puts("> Activar sirena"); //se muestra el mensaje
muestra el mensaje
lcd_gotoxy(0,1); //se situa el cursor
_delay_ms(200); en la columna 1 y fila 2
if(menu_circular==2) opcion=4;
{ }
if else
(subir==0) if(subir==3)
{ {
_delay_ms(200); _delay_ms(200);
opcion=0; opcion=3;
} }
else else
if(subir==1) if(subir==4)
{ {