Разобрав это добро я стал обладателем трех ЖК дисплеев и трех чековых принтеров.
Как подключить дисплей к Ардуино? На плате ЖК дисплея было обнаружено несколько надписей.
5104219-01, 251 12, 251-Т2. Использована микросхема Holtek HT1621B, datasheet был скачан и изучен. К сожалению, тип используемого ЖКИ так и не был опознан.
Прозвонив тестером выводы (6 выводов)) я определил их назначение:
1) Data
2) WR
3) CS
4) неизвестно*
5) Gnd
6) Vdd (+5 v)
* — подключены резисторы, конденсаторы, поскольку мне нужно было, я и не разбирался глубоко.
Я использовал готовые процедуры для работы с портами HT1621 из Ардуино.
Микросхема HT1621 128 ячеек для ЖКИ, которые организованы следующим образом 32×4 bits, в памяти это 16 байт. В моем ЖКИ были подключены выводы Com0, Com1, Com2 и все сегменты 0-31.
Для определения какой адрес и какой бит отвечает за какой сегмент была написана простая программа, которая перебирает все адреса и все биты. Результаты были записаны в электронную таблицу для последующего анализа. Вот так выглядит заполненная таблица.
Теперь стало ясно, как управлять дисплеем. Так, например, чтобы включить сегменты B и C в первой позиции (самая левая) нужно изменить биты D5 и D6 на 1 по адресу 0x05, остальные биты должны быть оставлены без изменений, поскольку они повлияют на другие позиции.
Если обратить внимание на таблицу, можно увидеть, что для отображения какой — либо цифры нужно поменять несколько битов в нескольких байтах. Эту задачу я решил следующим образом. Были подготовлены несколько таблиц:
- HT1681_Address(72 байта), HT_1681_Value(72 байта)
- b7SegDsp(10 байт)
- HT1681_Screen(16 байт)
HT1681_Address(72 байта), HT_1681_Value(72 байта) эти две таблицы связаны между собой следующим образом — вторая таблица представляет собой маску (для OR) для установки соответствующего бита в 1, причем первые девять байтов отвечают за сегменты A,B,C,D,E,F,G + десятичную точку + вернее «подчеркивание» первого знакоместа, следующие девять — за сегменты второго знакоместа, и так далее. Первая таблица — представляет собой адреса, которые соответствуют второй таблице. Для понимания внизу приведена иллюстрация.
// HT1681_Segments 1A 1B 1C 1D 1E 1F 1G 1DP 1Up ..... 8A 8B 8C 8D 8E 8F 8G 8DP 8Up const byte HT1681_Address[]= { 0x04,0x05,0x05,0x04,0x04,0x04,0x04,0x05,0x0E, 0x06,0x06,0x06,0x06,0x05,0x05,0x06,0x06,0x04, 0x07,0x08,0x08,0x07,0x07,0x07,0x07,0x08,0x05, 0x09,0x09,0x09,0x09,0x08,0x08,0x09,0x09,0x07, 0x0A,0x0B,0x0B,0x0A,0x0A,0x0A,0x0A,0x0B,0x08, 0x0C,0x0C,0x0C,0x0C,0x0B,0x0B,0x0C,0x0C,0x0A, 0x0D,0x0E,0x0E,0x0D,0x0D,0x0D,0x0D,0x0E,0x0B, 0x0F,0x0F,0x0F,0x0F,0x0E,0x0E,0x0F,0x0F,0x0D }; const byte HT_1681_Value[]= { 0x04,0x40,0x20,0x08,0x20,0x40,0x02,0x80,0x08, 0x40,0x04,0x02,0x80,0x02,0x04,0x20,0x08,0x80, 0x04,0x40,0x20,0x08,0x20,0x40,0x02,0x80,0x08, 0x40,0x04,0x02,0x80,0x02,0x04,0x20,0x08,0x80, 0x04,0x40,0x20,0x08,0x20,0x40,0x02,0x80,0x08, 0x40,0x04,0x02,0x80,0x02,0x04,0x20,0x08,0x80, 0x04,0x40,0x20,0x08,0x20,0x40,0x02,0x80,0x08, 0x40,0x04,0x02,0x80,0x02,0x04,0x20,0x08,0x80 };
b7SegDsp(10 байт) Эта таблица кодирует какие сегменты должны включаться для отображения числа.Первый байт — это кодирование числа 0, последний байт кодирует 9. Старшие семь бит D7-D1 кодируют сегменты A-G, младший D0 — не используется, я его установил в 0, кроме того, это экономит одну операцию битового сдвига влево — я использую маску 0x80 для проверки бита.
HT1681_Screen(16 байт) просто видеопамять, все 16 байтов. Вначале рендерится все в память, а затем все копируется в HT1621.
Ниже код, который выполняет рендеринг в HT1681_Screen, который потом просто выводится в память микросхемы для отображения.
// 0<=bPos<=7 - в какой позиции написать число bNum. // Если нужна десятичная точка - то lDecimalPoint=1 // Если нужно верхнее "подчеркивание" - то lUpperLine=1 void HT1681_Display(byte bPos, byte bNum, byte lDecimalPoint, byte lUpperLine) { byte i, bCheckByte, bAddr, bValue; bCheckByte=b7SegDsp[bNum]; // получаем маску - какие сегменты мы должны включить for(i=bPos*9;i<=bPos*9+6;i++) // поскольку сегментов 7 штук { if ( (bCheckByte & 0x80) == 0x80) // если старший сегмент =1 то должны { bAddr=HT1681_Address[i]; // определить конкретный байт bValue=HT_1681_Value[i]; // и определить конкретную маску HT1681_Screen[bAddr] = (HT1681_Screen[bAddr] | bValue); // выполним операцию OR для включения соответствующего бита в 1 }; bCheckByte=bCheckByte << 0x01; // сдвигаем весь байт влево } if (lDecimalPoint==1) // отдельно отрабатываем десятичную точку { bAddr = HT1681_Address[(bPos*9)+7]; bValue = HT_1681_Value[(bPos*9)+7]; HT1681_Screen[bAddr] = (HT1681_Screen[bAddr] | bValue); }; if (lUpperLine==1) // отдельно отрабатываем верхнее подчеркивание { bAddr = HT1681_Address[(bPos*9)+8]; bValue = HT_1681_Value[(bPos*9)+8]; HT1681_Screen[bAddr] = (HT1681_Screen[bAddr] | bValue); }; }
// использованы наработки из http://arduino.ru/forum/programmirovanie/ht1621 // http://arduino.ru/forum/programmirovanie/ht1621#comment-76371 #define sbi(x, y) (x |= (1 << y)) /*set Register x of y*/ #define cbi(x, y) (x &= ~(1 <
Источник