Как подключить LCD экран от кассового аппарата ЭКР-2102 к Ардуино

Как-то просматривая объявления на OLX, я наткнулся на распродажу старой электроники по очень низким ценам, в итоге было куплено три кассовых аппарата и один модем (на разбор с целью пополнения запасов). Цена вопроса 1500 тенге — примерно 250 рублей.

Как подключить LCD экран от кассового аппарата ЭКР-2102 к Ардуино

Разобрав это добро я стал обладателем трех ЖК дисплеев и трех чековых принтеров.

Как подключить дисплей к Ардуино? На плате ЖК дисплея было обнаружено несколько надписей.
5104219-01, 251 12, 251-Т2. Использована микросхема Holtek HT1621B, datasheet был скачан и изучен. К сожалению, тип используемого ЖКИ так и не был опознан.

Прозвонив тестером выводы (6 выводов)) я определил их назначение:

1) Data
2) WR
3) CS
4) неизвестно*
5) Gnd
6) Vdd (+5 v)
* — подключены резисторы, конденсаторы, поскольку мне нужно было, я и не разбирался глубоко.

image

Я использовал готовые процедуры для работы с портами HT1621 из Ардуино.

Микросхема HT1621 128 ячеек для ЖКИ, которые организованы следующим образом 32×4 bits, в памяти это 16 байт. В моем ЖКИ были подключены выводы Com0, Com1, Com2 и все сегменты 0-31.

Для определения какой адрес и какой бит отвечает за какой сегмент была написана простая программа, которая перебирает все адреса и все биты. Результаты были записаны в электронную таблицу для последующего анализа. Вот так выглядит заполненная таблица.

image

Теперь стало ясно, как управлять дисплеем. Так, например, чтобы включить сегменты B и C в первой позиции (самая левая) нужно изменить биты D5 и D6 на 1 по адресу 0x05, остальные биты должны быть оставлены без изменений, поскольку они повлияют на другие позиции.

Если обратить внимание на таблицу, можно увидеть, что для отображения какой — либо цифры нужно поменять несколько битов в нескольких байтах. Эту задачу я решил следующим образом. Были подготовлены несколько таблиц:

  1. HT1681_Address(72 байта), HT_1681_Value(72 байта)
  2. b7SegDsp(10 байт)
  3. 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);   }; } 

Под спойлером выложен весь код для Arduino

// использованы наработки из 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 <

Видео работы программы

 
Источник

Читайте также