Actualmente estoy escribiendo un programa para ATmega32 MCU y tengo problemas con la pantalla LCD que no funciona.
Probado con varios MCU ATmega32, así como con varios módulos LCD compatibles con HD44780 (uno de ellos es DEM 16216 SGH enlace )
Probado con el método init descrito en la hoja de datos y en el actual. La pantalla se pone en blanco después de init (o muestra bloques si se ajusta el contraste) y no ocurre nada más.
ATmega32 se está ejecutando en un reloj interno de 1MHz
Fuente de alimentación de 5V
Los pines PORTC están conectados a los puertos de datos de LCD (PC0-DB0 ... PC7-DB7)
Pin E conectado a PD0, RW - PD1, RS - PD2
Todas las conexiones se han probado varias veces y no parece haber problemas.
archivo main.c
#ifndef F_CPU
#define F_CPU 1000000UL
#endif
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>
#include "lcd.h"
int i = 0;
int main (void)
{
lcd_init();
while(1)
{
lcd_goto_xy(2, 0);
lcd_character('H');
lcd_character('e');
lcd_character('l');
lcd_character('l');
lcd_character('o');
}
}
archivo lcd.h
#ifndef LCD_H
#define LCD_H
#ifndef F_CPU
#define F_CPU 1000000UL
#endif
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>
#define lcd_datadir DDRC
#define lcd_data PORTC
#define lcd_dataread PINC
#define lcd_controldir DDRD
#define lcd_control PORTD
#define lcd_e PD0
#define lcd_rw PD1
#define lcd_rs PD2
unsigned char lcd_row[2] = {0, 40};
void lcd_toggle_e (void) {
lcd_control |= (1<<lcd_e);
asm volatile ("NOP");
asm volatile ("NOP");
lcd_control &= ~(1<<lcd_e);
}
void lcd_check_if_busy (void) {
lcd_datadir = 0x00;
lcd_control &= ~(1<<lcd_rs);
lcd_control |= (1<<lcd_rw);
while (lcd_data >= 0x80) {
}
lcd_datadir = 0xFF;
}
void lcd_command (unsigned char command) {
lcd_check_if_busy();
lcd_control &= ~(1<<lcd_rs);
lcd_control &= ~(1<<lcd_rw);
lcd_data = command;
lcd_toggle_e();
lcd_data = 0;
}
void lcd_character (unsigned char letter) {
lcd_check_if_busy();
lcd_control |= (1<<lcd_rs);
lcd_control &= ~(1<<lcd_rw);
lcd_data = letter;
lcd_toggle_e();
lcd_data = 0;
}
void lcd_goto_xy (uint8_t x, uint8_t y) {
lcd_command(0x80 + lcd_row[y] + x);
}
void lcd_init(void) {
lcd_datadir = 0xFF;
lcd_controldir |= 0x07;
lcd_control = 0x00;
for (int power_up_time = 0; power_up_time<10; power_up_time++) {
_delay_ms(10);
}
lcd_data = 0x30;
lcd_toggle_e();
_delay_ms(10);
lcd_data = 0x30;
lcd_toggle_e();
_delay_ms(2);
lcd_data = 0x30;
lcd_toggle_e();
_delay_ms(2);
lcd_command(38);
lcd_command(08);
lcd_command(01);
lcd_command(06);
lcd_command(0F); // display, cursor, blink on
}
#endif
Cualquier apreciación o ayuda es apreciada.