Проблемма в следующем.
На экране после инициализации ничего не отображается, ни в графическом, ни в текстовом режиме.
Теперь описание системы.
MCU SiLabs F130 (сейчас тактовая системной шины 25МГц, проверял и на 100МГц)
ЖКИ WinStar WG128128
Стоит преобразователь уровней 74ALVC164245 для подключения ЖКИ.
ЖКИ поключен на шину данных через преобразователь уровня.
Два младших бита адреса A0 и A1 заведены соответственно (через преобразователь уровней) на RS и R/W экрана.
Разрешающий вход E экрана заведен через схему ИЛИ-НЕ с WR и RD управления внешней памятью. Так же этот строб зависит от состояния CS экрана (если CS в 0, то состояние E мняется, иначе состояние E = 0).
Вход RES управляется напрямую (т.е. с порта, не отображен в адресном пространстве).
CS вход управляется с дешифратора адреса через инвертор (выход дешифратора с адресов A21,A20,A19 равным трем 111. Т.е. 7 выход, если счет вести от 0) и далее на преобразователь уровней.
Направление выходов порта шины данных, преобразователя уровней, управляется от сигнала RD системной шины.
Состояние выходов преобразователя уровней управляется от сигнала CS.
18 нога ЖКИ не подключена (подтягивание ее к питанию положительного эфекта не дало).
Проверил всю эту шину осцилографом в разных режимах. Данные и стробы появляются когда нужно и именно в том состоянии, в котором их установили. Стробы правильной полярности. Все это смотрел прямо на ЖКИ (т.е. проверил соединительный шлейф на обрыв или КЗ). Экран при включении питания отображает черную полосу (вроде как живой).
Процесс инициализации происходит следующим образом
Код
LCD_led=0; // выключаем подсветку
// сброс ЖКИ
LCD_RESET=1;
i=0;do{}while (--i); // пауза
LCD_RESET=0;
i=0;do{}while (--i); // пауза
LCD_RESET=1;
// устанавливаем режим работы
// дисплей включен, мастер, символ мигает, курсор видим, внутренний знакогенератор
// Текстовый режим
write_byte(Mode_control,(byte)(DYSP_ON_OFF|M_Slave|(Blink)|(Cursor)&(~Mode)&(~Ext_CG)),0);
// регистр высоты знаков
// Vp=16, Hp=8
write_byte(Char_pitch,(byte)((0x0F<<4)|0x07),0);
// регистр количества знаков
// N(128 Òî÷åê)/Hp = 16
write_byte(Number_char,0x0F,0);
// регистр скважности дисплея
// Nx (1/Nx)
//MAX_ROW=128
write_byte(Time_div,MAX_ROW-1,0);
// регистр установки позиции курсора в символе
// Cp. Условие Cp<=Hp
write_byte(Cursor_pos,0x0F,0);
// регистр установки начальной позиции отображения на дисплее
write_byte(Start_adr_L,0x00,0);
write_byte(Start_adr_H,0x00,0);
// регистр установки начальной позиции (курсора на экране)
write_byte(Set_cursor_l,0x00,0);
write_byte(Set_cursor_h,0x00,0);
// Процедура записи данных dat р регистр reg
// при установленом бите cycle не производится проверка флага busy (нужно для потоковой записи)
// возвращает 1 в случае ошибки
bit write_byte(byte reg, dat, bit cycle)
{
byte i;
if (!cycle)
{
i=0xFF;
do{ }while((--i) && (REG_RD&0x80));
if (!i)
return(1); // ошибка выполнения команды(прошел таймаут)
}
REG_WR=reg; // устанавливаем регистр
DATA_WR=(byte)dat; // записываем данные
return (0);
}
// сброс ЖКИ
LCD_RESET=1;
i=0;do{}while (--i); // пауза
LCD_RESET=0;
i=0;do{}while (--i); // пауза
LCD_RESET=1;
// устанавливаем режим работы
// дисплей включен, мастер, символ мигает, курсор видим, внутренний знакогенератор
// Текстовый режим
write_byte(Mode_control,(byte)(DYSP_ON_OFF|M_Slave|(Blink)|(Cursor)&(~Mode)&(~Ext_CG)),0);
// регистр высоты знаков
// Vp=16, Hp=8
write_byte(Char_pitch,(byte)((0x0F<<4)|0x07),0);
// регистр количества знаков
// N(128 Òî÷åê)/Hp = 16
write_byte(Number_char,0x0F,0);
// регистр скважности дисплея
// Nx (1/Nx)
//MAX_ROW=128
write_byte(Time_div,MAX_ROW-1,0);
// регистр установки позиции курсора в символе
// Cp. Условие Cp<=Hp
write_byte(Cursor_pos,0x0F,0);
// регистр установки начальной позиции отображения на дисплее
write_byte(Start_adr_L,0x00,0);
write_byte(Start_adr_H,0x00,0);
// регистр установки начальной позиции (курсора на экране)
write_byte(Set_cursor_l,0x00,0);
write_byte(Set_cursor_h,0x00,0);
// Процедура записи данных dat р регистр reg
// при установленом бите cycle не производится проверка флага busy (нужно для потоковой записи)
// возвращает 1 в случае ошибки
bit write_byte(byte reg, dat, bit cycle)
{
byte i;
if (!cycle)
{
i=0xFF;
do{ }while((--i) && (REG_RD&0x80));
if (!i)
return(1); // ошибка выполнения команды(прошел таймаут)
}
REG_WR=reg; // устанавливаем регистр
DATA_WR=(byte)dat; // записываем данные
return (0);
}
Некоторые определения
Код
#define MAX_COL 128 // количество столбцов
#define MAX_ROW 128 // количество строк
byte far REG_WR _at_ 0x3F0100; // регистр записи
byte far REG_RD _at_ 0x3F0300; // регистр чтения
byte far DATA_WR _at_ 0x3F0000; // запись данных
byte far DATA_RD _at_ 0x3F0200; // чтение данных
sbit LCD_RESET = P1^4; // управление сбросом
sbit LCD_led = P1^5; // управленеи подсветкой. 0-выкл
// регистры управления LCD
#define Mode_control 0x00 // режим
#define Char_pitch 0x01 // высота знаков
#define Number_char 0x02 // количество точек в символе
#define Time_div 0x03 // скважность дисплея
#define Cursor_pos 0x04 // Cp - позиция курсора в символе. Условие Cp<=Hp
#define Start_adr_L 0x08 // Адрес ОЗУ с которого будет отображатся инфа
#define Start_adr_H 0x09 //
#define Set_cursor_l 0x0A // Установка курсора
#define Set_cursor_h 0x0B //
#define Write_data 0x0C // запись данных на экран
#define Read_data 0x0D // чтение данных с экрана
#define Clear_bit 0x0E // очистить бит
#define Set_bit 0x0F // установить бит
// Биты регистра Mode_control
#define DYSP_ON_OFF 0x20 // Управлени дисплеем вкл/выкл
#define M_Slave 0x10 // ведущий/ведомый
#define Blink 0x08 // мигание курсором
#define Cursor 0x04 // курсор
#define Mode 0x02 // режим работы (граф/текст)
#define Ext_CG 0x01 // внешний/внутренний CG
#define MAX_ROW 128 // количество строк
byte far REG_WR _at_ 0x3F0100; // регистр записи
byte far REG_RD _at_ 0x3F0300; // регистр чтения
byte far DATA_WR _at_ 0x3F0000; // запись данных
byte far DATA_RD _at_ 0x3F0200; // чтение данных
sbit LCD_RESET = P1^4; // управление сбросом
sbit LCD_led = P1^5; // управленеи подсветкой. 0-выкл
// регистры управления LCD
#define Mode_control 0x00 // режим
#define Char_pitch 0x01 // высота знаков
#define Number_char 0x02 // количество точек в символе
#define Time_div 0x03 // скважность дисплея
#define Cursor_pos 0x04 // Cp - позиция курсора в символе. Условие Cp<=Hp
#define Start_adr_L 0x08 // Адрес ОЗУ с которого будет отображатся инфа
#define Start_adr_H 0x09 //
#define Set_cursor_l 0x0A // Установка курсора
#define Set_cursor_h 0x0B //
#define Write_data 0x0C // запись данных на экран
#define Read_data 0x0D // чтение данных с экрана
#define Clear_bit 0x0E // очистить бит
#define Set_bit 0x0F // установить бит
// Биты регистра Mode_control
#define DYSP_ON_OFF 0x20 // Управлени дисплеем вкл/выкл
#define M_Slave 0x10 // ведущий/ведомый
#define Blink 0x08 // мигание курсором
#define Cursor 0x04 // курсор
#define Mode 0x02 // режим работы (граф/текст)
#define Ext_CG 0x01 // внешний/внутренний CG
После первой посылки в дисплей на экране полоса исчезает.
Но больше ничего не отображается. Т.е. после инициализации ни в текстовом режиме ни в графическом ничего, из того что я туда выплевываю, не отображается.
Причем вроде как в буфере экрана данные мои находятся. Так как я произвел (для проверки) сначала запись в цикле следующих байт 0x55 и 0xAA (запись производил с проверкой флага busy). А затем в другом цикле я их благополучно вычитал из дисплея. Но ни в текстовом режиме, ни в графическом значения этих байт (в текстовом соответствующие символы, в графическом точки) не отобразились на экране.
ПОМОГИТЕ. То ли дисплей не рабочий, то ли я совсем туплю.
Может есть кто в Санкт-Петербурге, хотелось бы проверить этот дисплей в рабочей системе (так сказать убедится, что дисплей точно жив).
С уважением, Андрей.