У вас в lcd_com перепутана очередность установки сигналов. В lcd_dat почти правильно. Вначале устанавливаются RS и RW,
пауза не менее 60нс,
затем устанавливается E,
затем устанавливаем данные,
пауза не менее 200нс, но так, чтобы общая длительность E в сост лог.1 была не менее 450нс.
сброс E,
здесь по идее нужна еще одна пауза, чтобы при следующем вызове нарастающий фронт E не был ранее 1мс от предыдущего. Правда за счет того, что ваша функция записи вызывается из другой эта пауза вполне может быть опциональной.
Даже если переставить команды вот так, то уже должно заработать.
void lcd_com( unsigned char p) // p - байт команды
// Функция записи команды в LCD
{
PORTE &= ~((1<<RS)|(1<<RW)); // RS = 0 (комада), RW = 0 (запись)
PORTE |= (1<<EN); // EN = 1 (начало записи команды в LCD)
PORTC = p; // вывод команды на шину DB0-7 LCD
DelayLong( 99); // длительность сигнала EN
PORTE &= ~(1<<EN); // EN = 0 (конец записи команды в LCD)
DelayLong( 199); // пауза для выполнения команды
}
void lcd_dat( unsigned char p) // p - байт данных
// Функция записи данных в LCD
{
PORTE |= (1<<RS); // RS=1, (данные + начало записи команды в LCD)
PORTE &= ~(1<<RW); // RW = 0 (запись)
PORTE |= (1<<EN); // EN = 1 (начало записи команды в LCD)
PORTC = p; // вывод команды на шину DB0-7 LCD
DelayLong( 99); // длительность сигнала EN
PORTE &= ~(1<<EN); // EN = 0 (конец записи команды в LCD)
DelayLong( 199); // пауза для выполнения команды
}
При подаче команд во время инициализации нужно либо читать флаг готовности (BUSY), либо делать паузы между командами не менее определенных (см. таблицу). Двойная инициализация ничего вам не даст.
void lcd_init()
// Функция инициализации LCD
{
DelayLong( 999); // пауза 4.5 V
lcd_com( 0x38); // команда (0x20) + 8 бит (0x10) + 2 строки (0x08) + 5х8 точек (0)
DelayLong( 999); // пауза для выполнения команды
lcd_com( 0x38); // команда (0x20) + 8 бит (0x10) + 2 строки (0x08) + 5х8 точек (0)
DelayLong( 999); // пауза для выполнения команды
lcd_com( 0x38); // команда (0x20) + 8 бит (0x10) + 2 строки (0x08) + 5х8 точек (0)
DelayLong( 999); // пауза для выполнения команды
lcd_com( 0x0F); // команда (0x08) + включить дисплей (0x04) + включить курсор (0x02) + курсор мигает (0x01)
DelayLong( 999); // пауза для выполнения команды
lcd_com( 0x01); // команда очистки экрана
DelayLong( 999); // пауза для выполнения команды
lcd_com( 0x07); // команда (0x04) + инкремент (0x02) + движим курсор (0)
DelayLong( 999); // пауза для выполнения команды
lcd_com( 0x14); // команда (0x10) + движим курсор (0) + вправо (0x04)
DelayLong( 999); // пауза для выполнения команды
}
Не знаю в каких единицах у вас задается длительность паузы, поставил так, как было у вас (самая длинная). После такой инициализации должен появиться мерцающий курсор.
При записи данных в тесте должно быть аналогично - либо перед записью данных (вызов lcd_dat) нужен анализ флага BUSY, либо вставляйте паузы между вызовами lcd_dat.
-
- Вставила ваши исправления. Ничего не изменилось. - Ксения(23.09.2013 03:16)