TODOPIC
Otros Microcontroladores / Dispositivos programables => Microcontroladores 8 bits => Mensaje iniciado por: Satenhu en 10 de Mayo de 2009, 04:02:16
-
Hola a toda la comunidad!
Soy nuevo en este foro y también estoy empezando con la programación de AVR.
Antes de empezar les agradezco de antemano toda la ayuda que me puedan ofrecer y de igual forma tratare de ayudar en lo que pueda.
Pues veran, tengo el siguiente problema.
Yo programo un ATMEGA8 con AVRStudio en lenguaje assembler. En los últimos días he estado intentando programar un LCD de 16x2 pero hasta el momento solo me enciende y por más que vario el contraste no logro que me aparezca el texto.
Aquí dejo el programa:
;------------------------------- INICIO DE PROGRAMA
.include "m8def.inc"
.def temp = r16
.def argument = r17
.def return = r18
.equ DDRLCD = DDRD
.equ PORTLCD = PORTD
.equ PINLCD = PIND
.equ LCD_RS = 1
.equ LCD_E = 3
.equ LCD_RW = 2
.equ BF = 3
.org 0x00
rjmp reset
reset:
ldi temp,low(RAMEND)
nop
nop
cbi PORTLCD,LCD_E
cbi PORTLCD,LCD_RS
in temp,DDRLCD
cbr temp,0b11110000
out DDRLCD,temp
ret
LCD8bits:
in temp,DDRLCD
sbr temp,0b11110000
out DDRLCD,temp
in temp,PORTLCD
cbr temp,0b11110000
cbr argument,0b00001111
or temp,argument
out PORTLCD,temp
sbi PORTLCD,LCD_E
nop
nop
nop
cbi PORTLCD,LCD_E
in temp,DDRLCD
cbr temp,0b11110000
out DDRLCD,temp
ret
LCD_command:
push argument
in temp,DDRLCD
sbr temp,0b11110000
out DDRLCD,temp
in temp,PORTLCD
cbr temp,0b11111110
cbr argument,0b00001111
or temp,argument
out PORTLCD,temp
sbi PORTLCD,LCD_E
nop
nop
nop
cbi PORTLCD,LCD_E
pop argument
cbr temp,0b11110000
swap argument
cbr argument,0b00001111
or temp,argument
out PORTLCD,temp
sbi PORTLCD,LCD_E
nop
nop
nop
cbi PORTLCD,LCD_E
in temp,DDRLCD
cbr temp,0b11110000
out DDRLCD,temp
ret
LCD_getaddr:
in temp,DDRLCD
andi temp, 0b00001111
out DDRLCD,temp
cbi PORTLCD,LCD_RS
sbi PORTLCD,LCD_RW
sbi PORTLCD,LCD_E
nop
in temp,PINLCD
andi temp,0b11110000
mov return,temp
cbi PORTLCD,LCD_E
nop
nop
sbi PORTLCD,LCD_E
nop
in temp,PINLCD
andi temp,0b11110000
swap temp
or return,temp
cbi PORTLCD,LCD_E
cbi PORTLCD,LCD_RW
ret
LCD_wait:
rcall LCD_getaddr
andi return,0x80
brne LCD_wait
ret
LCD_delay:
clr r4
LCD_delay_outer:
clr r5
LCD_delay_inner:
dec r5
brne LCD_delay_inner
dec r4
brne LCD_delay_outer
ret
LCD_inicia:
ldi temp,0b00001111
out DDRLCD,temp
rcall LCD_delay
ldi argument,0x20
rcall LCD8bits
rcall LCD_wait
ldi argument,0x28
rcall LCD_command
rcall LCD_wait
ldi argument,0x0C
rcall LCD_command
rcall LCD_wait
ldi argument,0x01
rcall LCD_command
rcall LCD_wait
ldi argument,0x06
rcall LCD_command
ret
texto0:
.db "BIENVENIDO",0
texto1:
.db "Sistemas",0
;------------------------------- FIN DE PROGRAMA
Al cargarlo en el AVR, no me presenta errores el software por lo que estoy casi seguro de que la falla no esta en el programa sino en el LCD.
No se mucho sobre LCD y solo elabore el programa de acuerdo a la funcion de los 16 pines del LCD.
Si me pudieran rayudar con mi problema les agradeceria mucho.
De igual forma si pueden brindarme información sobre los AVR y LCD se los agradeceria.
En fin es todo por el momento.
GRACIAS
-
Hola Satenhu! Y Bienvenido a nuestros Foro Todopic!!!
no soy un experto en Assembler ya que yo uso Avr Bascom , deberia poner el esquema de como conecta el LCD, aqui tambien te dejo un link http://www.avrbeginners.net/interfacing/44780_lcd/m8_lcd_4bit.asm tambien deberia poner tu codigo mas claro y definir al principio la conecion del LCD y tambien lo que hace el programa, aparte creo que los registros de Atmega8 no va con ese programa, lee el datasheet.
Saludos
-
Hola stk500!
Aquí pongo el diagrama de conexión y algo de lo que hace el programa, lo que quiero que haga el programa es que muestre el letrero "BIENVENIDOS", "ASistemas".
Repito que soy nuevo en los AVR y sobretodo en los LCD ya que hasta hace poco maneje PIC, más sin embargo ya tengo algo de experiencia con el AVRStudio.
El programa lo fui construyendo con la ayuda de un profesor que me esta ayudando con un proyecto, pero ya que el no es mi maestro titular y solo lo veo de vez en cuando, no se hasta que punto este bien el programa o mi conexión del LCD.
De cualquier forma ya revise el link que me pusiste y creo que me puede servir y pues lo que pongo del programa es lo que entiendo de su funcionamiento.
En fin muchas gracias por tu pronta respuesta y si me pudieras ayudar con mi programa te estaria muy agradecido.
Probare con el link que me recomiendas y aunque preferiria páginas en español (Que se que no hay mucha), mientras este en ingles no tengo mucho inconveniente.
Hasta pronto!
-
;------------------------------- INICIO DE PROGRAMA
.include "m8def.inc"
.def temp = r16
.def argument = r17 ;definicion de registros
.def return = r18
.equ DDRLCD = DDRD ;definicion de constantes
.equ PORTLCD = PORTD
.equ PINLCD = PIND
.equ LCD_RS = 1
.equ LCD_E = 3
.equ LCD_RW = 2
.equ BF = 3
.org 0x00 ;vector de interrupciones
rjmp reset ;reset
reset:
ldi temp,low(RAMEND) ;stack pointer
nop
nop
cbi PORTLCD,LCD_E
cbi PORTLCD,LCD_RS
in temp,DDRLCD
cbr temp,0b11110000 ;líneas de datos son entradas
out DDRLCD,temp
ret
LCD8bits: ;Inicializar el LCD
in temp,DDRLCD
sbr temp,0b11110000
out DDRLCD,temp
in temp,PORTLCD
cbr temp,0b11110000
cbr argument,0b00001111
or temp,argument
out PORTLCD,temp
sbi PORTLCD,LCD_E
nop
nop
nop
cbi PORTLCD,LCD_E
in temp,DDRLCD
cbr temp,0b11110000
out DDRLCD,temp
ret
LCD_command: ;Rs en bajo, indica que es un comando
push argument
in temp,DDRLCD
sbr temp,0b11110000
out DDRLCD,temp
in temp,PORTLCD
cbr temp,0b11111110
cbr argument,0b00001111
or temp,argument
out PORTLCD,temp
sbi PORTLCD,LCD_E
nop
nop
nop
cbi PORTLCD,LCD_E
pop argument
cbr temp,0b11110000
swap argument
cbr argument,0b00001111
or temp,argument
out PORTLCD,temp
sbi PORTLCD,LCD_E
nop
nop
nop
cbi PORTLCD,LCD_E
in temp,DDRLCD
cbr temp,0b11110000
out DDRLCD,temp
ret
LCD_getaddr:
in temp,DDRLCD
andi temp, 0b00001111
out DDRLCD,temp
cbi PORTLCD,LCD_RS
sbi PORTLCD,LCD_RW
sbi PORTLCD,LCD_E
nop
in temp,PINLCD
andi temp,0b11110000
mov return,temp
cbi PORTLCD,LCD_E
nop
nop
sbi PORTLCD,LCD_E
nop
in temp,PINLCD
andi temp,0b11110000
swap temp
or return,temp
cbi PORTLCD,LCD_E
cbi PORTLCD,LCD_RW
ret
LCD_wait: ;leer direccion y BF hasta que BF este en 0
rcall LCD_getaddr ;llamar rutina para tener el estado de BF
andi return,0x80 ;revisar si BF esta en bajo
brne LCD_wait ;si no esta en bajo continuar esperando
ret
LCD_delay: ;retraso para inicio de LCD
clr r4
LCD_delay_outer:
clr r5
LCD_delay_inner:
dec r5
brne LCD_delay_inner
dec r4
brne LCD_delay_outer
ret
LCD_inicia:
ldi temp,0b00001111
out DDRLCD,temp
rcall LCD_delay
ldi argument,0x20 ;Peticion de modo 4-bits al LCD
rcall LCD8bits ;esta en modo de 8-bits al recibir este comando
rcall LCD_wait
ldi argument,0x28 ;Peticion para 2 líneas,5*7 font, modo de 4 bits
rcall LCD_command
rcall LCD_wait
ldi argument,0x0C ;display on, cursor off, blinking off
rcall LCD_command
rcall LCD_wait
ldi argument,0x01 ;clear display, cursor -> home
rcall LCD_command
rcall LCD_wait
ldi argument,0x06 ;auto-n cursor
rcall LCD_command
ret
texto0:
.db "BIENVENIDOS",0
texto1:
.db "Sistemas",0
;------------------------------- FIN DE PROGRAMA
[im(http://)
-
Diag. de conexion
-
Hola amigo!
pues como te comente no soy un experto en Assembler, pero tengo la impresion que tiene problema con los Fuse ya que tu usa los pines RXD y TXD tambien el Timer0 y Timer1, asi que revisa el datasheet para eso de los Fuse. el link que te puse lo comprendo mejor que tu programa, y es una aplicacion del atmega8, asi que mejor estudiatelo.
Saludos
-
Te paso un ejemplo de conexión en 4 bit y 8 bit, incluye el codigo fuente para que lo puedas pobar.
Yo me inicié en el LCD con este ejemplo y anda barbaro.
http://winavr.scienceprog.com/example-avr-projects/avr-gcc-4-bit-and-8-bit-lcd-library.html (http://winavr.scienceprog.com/example-avr-projects/avr-gcc-4-bit-and-8-bit-lcd-library.html)
Esperamos nos cuentes los resultados.
Hasta pronto.
-
hola
pongan diagramas de conexiones estaria muy bien para hacer esos proyectos.
estan muy buena su informacion que postean
-
Hola satenhu!
Mira, yo no programo en assembler, pero vos posibles problemas.
Segun el diagrama, la conexion esta preparada para manejarlo con 4bits
y en tu codigo lo estas inicializando a 8bits si mal no percibo.
LCD8bits: ;Inicializar el LCD
in temp,DDRLCD
sbr temp,0b11110000
out DDRLCD,temp
in temp,PORTLCD
cbr temp,0b11110000
cbr argument,0b00001111
or temp,argument
out PORTLCD,temp
sbi PORTLCD,LCD_E
nop
nop
nop
cbi PORTLCD,LCD_E
in temp,DDRLCD
cbr temp,0b11110000
out DDRLCD,temp
ret
Otra cosa que veo en la inicializacion, es que no estas haciendo retardos para mantener en alto el pin E.
Dale una duracion de al menos 400us. Los tiempos de ejecucion en AVR son hasta 4 veces mas rapidos que en los PICs
Para los LCDs standards, en la inicializacion, tenes que darle al menos 100ms de espera para el comando de modo de uso (8/4 bits)
Y me parece que en esa rutina de inicializacion le faltan comandos.
Yo por ejemplo, ejecuto los siguientes comandos para inicializar un LCD. (programado en C)
LCDCommand(LCD_4B); //0x20
_delay_ms(100); //Init delay required
LCDCommand(LCD_4B_2L_5X7); //0x28
LCDWaitReady();
LCDCommand(LCD_DISPLAY_OFF); //0x08
LCDWaitReady();
LCDCommand(LCD_CLEAR); //0x01
LCDWaitReady();
LCDCommand(LCD_ENTRY_MODE); //0x06
LCDWaitReady();
LCDCommand(LCD_HOME); //0x02
LCDWaitReady();
LCDCommand(LCD_DISPLAY_ON); //0x0C
LCDWaitReady();
_delay_ms(100); //Init delay required
La funcion LCDWaitReady() lee el pint D7 del LCD para saber si termino la ejecucion.
Esa es una secuencia de comando para inicilizarlo en modo 4bits.
Saludos!