Дисплей 16х1 от ККМ "Элвес Микро"

svm
Offline
Зарегистрирован: 06.11.2016

vladimir_62 пишет:

отлично, что взялись. не беда - завалим железку.

Что-то пока не поддается, вроде с даташитом разобрался , но не взлетела.

Напмсал отдельно три команды  инициализацию и включение звука. Запустил их по кругу, чтобы посмотреть что отправляется от МК к дисплею. Пришлось из DS138 сделать псевдо трехканальный осциллограф, чтобы совместить три осциллограммы. Благо сигнал цифровой и можно обойтись 4 резисторами. Но просмотр картинки ничего не дал, вроде все логично и даташиту не противоречит. Есть несколько вариантов:

1. Не хватает команд для инициализации

2. Не те тайминги

3. Что-то не догоняю, и посылаю не то

Вот фото с экрана осциллографа, и немного дополнительной информации:

Вы у себя не сможете проверить минимальный набор команд для проверки?

vladimir_62
Offline
Зарегистрирован: 18.01.2019

как будто все ровно.

давайте так попробуем:

out_cmd (0x0C);  - не обяз
out_cmd (0x18);  - не обяз
out_cmd (0xE3); - не обяз
 
out_cmd (0x01); - обязательно
out_cmd (0x03); - обязательно
out_cmd (0x29); - обязательно
out_cmd (0x88);
вот картинка из отладчика.

 

svm
Offline
Зарегистрирован: 06.11.2016

Не хочет, прбовал еще вставлять 18Н, вроде как выбор тактового генератора. У Вас в отладчике между пунктирными линиями сетки 10 мкс? А то у меня клоки по 40 мкс, может здесь собака порылась? Попробую еще библиотеку поправить.

vladimir_62
Offline
Зарегистрирован: 18.01.2019

после подачи питания есть задержка ?

svm
Offline
Зарегистрирован: 06.11.2016

Сейчас 200 мс перед инициализацией и по 10 между всеми командами. Правда в процессе перетыкания проводов случайно загорелась верхняя половина разрядов, и все. Дальше тишина. Другая модификация индикатора намного проще.

vladimir_62
Offline
Зарегистрирован: 18.01.2019

это значит тайминги надо крутить немного

пробовать чуть влево двинуть clock после смены данных

svm
Offline
Зарегистрирован: 06.11.2016

А у Вас в анализаторе, показывает реальное время? И по подключению: верхний канал идет на 3 ногу индикатора, средний на 3 и нижний на 7 ?

vladimir_62
Offline
Зарегистрирован: 18.01.2019

3 - ddat; 4 - dclk; 7 - dres.  сверху вниз. время реальное

оставил только инициализацию 

out_cmd (0x01)
out_cmd (0x03)
out_cmd (0x88); // on led

 

 

vladimir_62
Offline
Зарегистрирован: 18.01.2019

если все резисторы одинаковые - почему уровень на данных такой низкий  относительно других.

vladimir_62
Offline
Зарегистрирован: 18.01.2019

уроните все в 0 и поставьте прямо перед /cs небольшую задержку. 

svm
Offline
Зарегистрирован: 06.11.2016

vladimir_62 пишет:

если все резисторы одинаковые - почему уровень на данных такой низкий  относительно других.

Резисторы специально разные, чтобы каналы по уровню отличались, а то их можно перепутать. Кроме того по самому всокому (CS) происходит синхронизация ослика.

svm
Offline
Зарегистрирован: 06.11.2016

vladimir_62 пишет:

 

оставил только инициализацию 

out_cmd (0x01)
out_cmd (0x03)
out_cmd (0x88); // on led

 

и с ней заводится?

vladimir_62
Offline
Зарегистрирован: 18.01.2019

да

svm
Offline
Зарегистрирован: 06.11.2016

Какова цена деления временной шкалы? Или длительность клока. Попробую тупо подогнать под Вашу картинку.

vladimir_62
Offline
Зарегистрирован: 18.01.2019

растянул картинку.

цена = 2 us; t clk=1.4

 

svm
Offline
Зарегистрирован: 06.11.2016

Спасбо.  Да анализатор это вещь. После часа примерной подгонки картинки с него и ослика железка завелась.

Причем оказалось ,что от длительности ничего не зависит. Начинает работать от 1 мкс и скорее всего дальше ограничено разумными пределами. 

vladimir_62
Offline
Зарегистрирован: 18.01.2019

поздравляю. коллективный разум побеждает.

вот интересно как у Вас будут работать первые левые 2 разряда в совместной жизни.

svm
Offline
Зарегистрирован: 06.11.2016

Владимир,  у тебя не сохранилась таблица соответствия адресов и сегментов, а то что-то грустно искать методом тыка. И в твоей программе массивы разрядов, что куда идет?

vladimir_62
Offline
Зарегистрирован: 18.01.2019

у меня это все на бумажке. там черт ногу сломит. могу скан скинуть.

адрес и данные, соответствующие  сегменту в элементах массива, причем в том виде, в каком можно отправлять в дисплей.

arr1 - это правые 5 разрядов со смещением 20h

wr_Data(8, m1&0x1F, 0x200,m);

void wr_Data(uint8_t pos, uint8_t val, uint16_t mask,uint8_t s)
{.....

else

//=========================
{
for (i = 0; i < 3; i++)
{
cs(0,1); m1=mask; //0x200 = 10bit adr(6)+data(4) 
SendBit(0x05,3,0,0x4);//cmd 101,3 bit,>>
for (i1 = 0; i1 < 10; i1++)
{
if(i==2){d=(arr1[val][i]+0x10-0x10*s);}else{d=arr1[val][i] +0x20*s;}
if(d&m1) {ddat1;} else {ddat0;}; delay(2);dclk1;delay(5);dclk0;delay(5);m1>>=1;
}
cs(1,1);
}

попробуйте это воспроизвести.

svm
Offline
Зарегистрирован: 06.11.2016

Ок! Бумажек, я сегодня много извел, и чувствую- это надолго. Попрбую пойти по Вашему пути. А то времени не хватает. Живу-то в деревне.

vladimir_62
Offline
Зарегистрирован: 18.01.2019

еще точек нет в массивах. у нижних точек : правые 5 (data,adr) 4.19d... 4.12d первые 2 = 4.0 и 4.3

svm
Offline
Зарегистрирован: 06.11.2016

Пока вопросов больше нее, буду разбираться.

vladimir_62
Offline
Зарегистрирован: 18.01.2019
svm
Offline
Зарегистрирован: 06.11.2016

Ок! Но это на досуге. Просидел часа полтора, тупо тыкая кнопкой изменения адреса, и записывая результат в тетрадку в линейку (в клеточку не оказалось). Для пяти левых разрядов проблем нет. С точками тоже. Там все просто. Данные для левых сегментов имеют два варианта без точки и с точкой. И если нужна точка перед этим разрядом, то данные посылаемые в ячейку памяти увеличиваем на два, и все. С первыми тремя разрядами пока не разбирался. Пока приведу в порядок бумажки, а то и забыть, что там намулевано недолго.

                                   Вот окультурил адреса и данные по последним 5 разрядам:

А это три первых:

Вроде все решаемо, только подумать немного. По этим картинкам достаточно легко рисовать символы. Конечно памяти, которой у ардуинки и так немнрго, откусит. Но с другой стороны если дисплеи можно взять за бутылку пива, то игра стоит свеч.

А насчет первых трех разрядов, можно сказать только одно - те кто их проектировал, явно курили что-то крутое.

vladimir_62
Offline
Зарегистрирован: 18.01.2019

с первыми 3-я согласен (озвучивал ранее), особенно первые 2 - шедевр. в остальном примерно все одинаково как у меня, вот только где в данных 1 разряд (d0), т.е. ddat

d3 d2 d1 d0 =0001

первые три  - напрашивается идея использовать бы "чтение-модификация-запись", но нет вывода RD. возможно он есть в одном из 2-х неиспользуемых выводах дисплея...

другой вариант - образ памяти индикатора размещать в памяти процессора, с ней манипулировать как душе угодно и все сливать в дисплей одной командой с начальным адресом "0". инкремент адреса дисплей умеет делать сам.  

svm
Offline
Зарегистрирован: 06.11.2016

Он никакой роли не играет, если я посылаю в ячейку памяти "0" или "1", результат одинаков - все сегменты гаснут. То-же эффект если "2" и "3", загораются сегменты согласно картинкам. Вот пример вывода цифр .

Первый параметр - адрес ячейки, второй - данные. Третий -всегда еденица, он указывает сколько раз отослать данные (для чего-то был в исходной бибпиотеке, позже вырежу).

Правда текст для ардуино ИДЕ, но он элементарный и там все понятно. Написан тупо в лоб.

//===========================================   
   ht.clear_all();


                                                 
   //           2 -> 1 разряд                           
   ht.write_c(9,14,1);//  центр. сегменты                
   ht.write_c(10,8,1);//  правые сегменты                
   ht.write_c(11,6,1);//   левые сегменты                 

   //           3 -> 2 разряд
  
   ht.write_c(8,14,1);//  центр. сегменты
   ht.write_c(12,12,1);//  правые сегменты
   //ht.write_c(13,12,1);//   левые сегменты

 //             4 -> 3 разряд
  
   ht.write_c(7,4,1);//  центр. сегменты
   ht.write_c(14,12,1);//  правые сегменты
   ht.write_c(15,8,1);//   левые сегменты
   
 //             5 -> 4 разряд
  
   ht.write_c(6,14,1);//  центр. сегменты
   ht.write_c(16,4,1);//  правые сегменты
   ht.write_c(17,8,1);//   левые сегменты   
   
 //             6 -> 5 разряд
  
   ht.write_c(5,14,1);//  центр. сегменты
   ht.write_c(18,4,1);//  правые сегменты
   ht.write_c(19,12,1);//   левые сегменты  
   
// ++++++++++++++++++++++++++++++   три младших разряда   ++++++++++++++++++++++++++++++++++++   
//             0 -> 6 разряд 
  
   ht.write_c(20,14,1);//
   ht.write_c(4,10,1);//
   ht.write_c(3,4,1);//
   delay (500);     
//             1 -> 6 разряд
  
   ht.write_c(20,6,1);//
   ht.write_c(4,0,1);//
   ht.write_c(3,0,1);//
   delay (500);    
//             2 -> 6 разряд 
  
   ht.write_c(20,12,1);//
   ht.write_c(3,4,1);//
   ht.write_c(4,6,1);//   
    delay (500);    
//             3 -> 6 разряд 
  
   ht.write_c(20,14,1);//
   ht.write_c(4,6,1);//
   ht.write_c(3,0,1);//
    delay (500);
//             4 -> 6 разряд 
  
   ht.write_c(20,6,1);//
   ht.write_c(4,12,1);//
   ht.write_c(3,0,1);//
    delay (500);     
//             5 -> 6 разряд 
  
   ht.write_c(20,10,1);//
   ht.write_c(4,14,1);//
   ht.write_c(3,0,1);//
    delay (500);     
//             6 -> 6 разряд 
  
   ht.write_c(20,10,1);//
   ht.write_c(4,14,1);//
   ht.write_c(3,4,1);//
   delay (500);
//             7 -> 6 разряд 
  
   ht.write_c(20,14,1);//
   ht.write_c(4,0,1);//
   ht.write_c(3,0,1);//
      delay (500);

//             8 -> 6 разряд 
  
   ht.write_c(20,14,1);//
   ht.write_c(4,14,1);//
   ht.write_c(3,4,1);//
   delay (500);
//             9 -> 6 разряд 
  
   ht.write_c(20,14,1);//
   ht.write_c(4,14,1);//
   ht.write_c(3,0,1);//
   delay (500);

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


//             0 -> 7 разряд 
  
   ht.write_c(2,14,1);//
   ht.write_c(1,10,1);//
   ht.write_c(0,4,1);//
   delay (500);     
//             1 -> 7 разряд
  
   ht.write_c(2,6,1);//
   ht.write_c(1,0,1);//
   ht.write_c(0,0,1);//
   delay (500);    
//             2 -> 7 разряд 
  
   ht.write_c(2,12,1);//
   ht.write_c(1,6,1);//
   ht.write_c(0,4,1);//   
    delay (500);    
//             3 -> 7 разряд 
  
   ht.write_c(2,14,1);//
   ht.write_c(1,6,1);//
   ht.write_c(0,0,1);//
    delay (500);
//             4 -> 7 разряд 
  
   ht.write_c(2,6,1);//
   ht.write_c(1,12,1);//
   ht.write_c(0,0,1);//
    delay (500);     
//             5 -> 7 разряд 
  
   ht.write_c(2,10,1);//
   ht.write_c(1,14,1);//
   ht.write_c(0,0,1);//
    delay (500);     
//             6 -> 7 разряд 
  
   ht.write_c(2,10,1);//
   ht.write_c(1,14,1);//
   ht.write_c(0,4,1);//
   delay (500);
//             7 -> 7 разряд 
  
   ht.write_c(2,14,1);//
   ht.write_c(1,0,1);//
   ht.write_c(0,0,1);//
      delay (500);

//             8 -> 7 разряд 
  
   ht.write_c(2,14,1);//
   ht.write_c(1,14,1);//
   ht.write_c(0,4,1);//
   delay (500);
//             9 -> 7 разряд 
  
   ht.write_c(2,14,1);//
   ht.write_c(1,14,1);//
   ht.write_c(0,0,1);//
   delay (500);    
*/
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//             8 -> 7 разряд 
  
   ht.write_c(2,14,1);//
   ht.write_c(1,14,1);//
   ht.write_c(0,4,1);//
delay (1000);
//             0 -> 8 разряд 
  
   ht.write_c(22,0,1);//
   ht.write_c(21,2,1);//
   ht.write_c(0,8,1);//
   delay (500);     
//             1 -> 8 разряд
  
   ht.write_c(22,0,1);//
   ht.write_c(21,2,1);//
   ht.write_c(0,8,1);//
   delay (500);    
//             2 -> 8 разряд 
  
   ht.write_c(22,6,1);//
   ht.write_c(21,12,1);//
   ht.write_c(0,8,1);//   
    delay (500);    
//             3 -> 8 разряд 
  
   ht.write_c(22,2,1);//
   ht.write_c(21,14,1);//
   ht.write_c(0,8,1);//
    delay (500);
//             4 -> 8 разряд 
  
   ht.write_c(22,8,1);//
   ht.write_c(21,6,1);//
   ht.write_c(0,8,1);//
    delay (500);     
//             5 -> 7 разряд 
  
   ht.write_c(22,10,1);//
   ht.write_c(21,14,1);//
   ht.write_c(0,0,1);//
    delay (500);     
//             6 -> 8 разряд 
  
   ht.write_c(22,14,1);//
   ht.write_c(21,14,1);//
   ht.write_c(0,1,1);//

   delay (500);
//             7 -> 8 разряд 
  
   ht.write_c(22,0,1);//
   ht.write_c(21,10,1);//
   ht.write_c(0,8,1);//
      delay (500);

//             8 -> 8 разряд 
  
   ht.write_c(22,14,1);//
   ht.write_c(21,14,1);//
   ht.write_c(0,8,1);//
   delay (500);
//             9 -> 8 разряд 
  
   ht.write_c(22,10,1);//
   ht.write_c(21,14,1);//
   ht.write_c(0,8,1);//
   delay (500);       





   }// конец

На дисплей выводит цифры 6543.2 в последние разряды. Во 2 и 3  разрядах цифры меняются от 0 до 9. В первом от 1 до 9 (ноль не реализуем), но если в цифре 1 разряда присутствует верхний правый сегмент, то он затирает нижний левый сегмент второго разряда. Это по моему непреодолимо.

 

 

vladimir_62
Offline
Зарегистрирован: 18.01.2019

" но если в цифре 1 разряда присутствует верхний правый сегмент, то он затирает нижний левый сегмент второго разряда. Это по моему непреодолимо."

- у меня также. значит все верно. я думал где ошибся.

но 2-й и 3-й разряды можно использовать с индивидуальной адресацией

svm
Offline
Зарегистрирован: 06.11.2016

vladimir_62 пишет:

но 2-й и 3-й разряды можно использовать с индивидуальной адресацией

Они и так работают нормально. А как это индивидуально? Я и так отсылаю данные прямо в ОЗУ микросхемы , по адресам от 0 до 22. Пытался засылать в оставшиеся 8 - никакого эффекта. Правда что-то происходит когда меняю эти параметры:

 //Set to 2,3 or 4 connected COM lines
      BIAS_HALF_2_COM  = 0b00100000, /*!< Use 1/2 bias and 2 commons. */
      BIAS_HALF_3_COM  = 0b00100100, /*!< Use 1/2 bias and 3 commons. */
      BIAS_HALF_4_COM  = 0b00101000, /*!< Use 1/2 bias and 4 commons. */
      BIAS_THIRD_2_COM = 0b00100001, /*!< Use 1/3 bias and 2 commons. */
      BIAS_THIRD_3_COM = 0b00100101, /*!< Use 1/3 bias and 3 commons. */
      BIAS_THIRD_4_COM = 0b00101001, /*!< Use 1/3 bias and 4 commons. */

Что-то меняется, но не врубился. Скорее всего это для дисплеев с другой организацией разрядов и сегментов.

 

vladimir_62
Offline
Зарегистрирован: 18.01.2019

com - это общие сегменты, объединенные в группы (у каждого индикатора по своему). т.е. можно какието группы включать/отключать.

bias регулирует степень возбуждения кристаллов, или по простому их ориентацию, для возможности использования дисплея под разыными углами обзора, в основном 30 град. покрутите биты и увидите, что контрастность изображения меняется в зависимости от угла обзора.  

svm
Offline
Зарегистрирован: 06.11.2016

vladimir_62 пишет:

bias регулирует степень возбуждения кристаллов, или по простому их ориентацию, для возможности использования дисплея под разыными углами обзора, в основном 30 град. покрутите биты и увидите, что контрастность изображения меняется в зависимости от угла обзора.  

Повидимому, не только. В некоторых режимах отображаются только нижние  и центральные сегменты. Что-то там еще  есть, но в даташите не нашел. Хотя это скорее всего влияние СОМ. Вовсяком случае даже в таком виде, нелохой дисплей и применение ему можно найти.

vladimir_62
Offline
Зарегистрирован: 18.01.2019

вот русскоязычное описание аналогичного модуля на 1621

https://drive.google.com/open?id=125D72dwxCkgDJ4_wLUqpqscj3Y1kkB0r

svm
Offline
Зарегистрирован: 06.11.2016

vladimir_62 пишет:

вот русскоязычное описание аналогичного модуля на 1621

https://drive.google.com/open?id=125D72dwxCkgDJ4_wLUqpqscj3Y1kkB0r

 Если бы этот даташит был сначала, большинство вопросов - бы отпало. Расписано для школьников младших классов и на одном листе. Ну ладно, думать иногда тоже полезно. Да и язык неплохо-бы изучить, но наверное уже не суждено. 

Я думаю вопрос закрыт. 

Electr0
Offline
Зарегистрирован: 24.06.2019

svm, имеется такой же дисплей, у вас остались наработки по данному дисплею для ардуино?

svm
Offline
Зарегистрирован: 06.11.2016

Electr0 пишет:
svm, имеется такой же дисплей, у вас остались наработки по данному дисплею для ардуино?

Есть несколько наработок для дисплеев от ККМ :  Штриховские, для старых и новых Элвесов и ЭКРок. Посмотрю уточню. Правда написаны достаточно грубо, т.к. писал для того чтобы разобраться с их работой. Но в принципе работать можно (правда без изысков). Думал довести до ума и потом выложить. Но если нужно могу и в таком виде. Но дорабатывать пока не собираюсь.

Electr0
Offline
Зарегистрирован: 24.06.2019

да было бы круто), тоже есть парочка от касс, один на cd4015bcm благодаря вашему примеру завел (спасибо, кстати очень помогли), а вот этот не понимаю, мне бы пример как завести его, а дальше от него плясать уже можно самостоятельно тем кому это нужно

svm
Offline
Зарегистрирован: 06.11.2016

Сейчас пороюсь в архивах и выложу каждый дисплей отдельным постом

svm
Offline
Зарегистрирован: 06.11.2016

Для начала самый простой на CD4015. Схему легко найти в интернете ищете elmk_circuits.pdf

Вот пример вольтметра измеряющего напряжение питания ардуино. Оба файла кладете в одну папку.

Скетч вольтметра:

/*
 * Распайка индикатора на CD4015 со стороны индикатора первая нога левая
 * 1 - DRES        ->D5
 * 2 - ACCLO  красный светодиод
 * 3 - CHARGE зеленый светодиод
 * 4 - DCLK        ->D6
 * 5 - DDAT        ->D7
 * 6 - NC
 * 7 - UCC 5V
 * 8 - UCC 5V
 * 9 - GND
 * 10- GND
 */

#include "nanopins2.h"
boolean flash = false;
byte pt;
long rez;
byte simv_razr[8];// массив разрядов индикатора
byte simv[16]={//         знакогенератор
B00111111, //0                _____
B00100001, //1               | D1  |
B10011011, //2           D2  |     | D0
B10110011, //3               |_____|
B10100101, //4               | D7  |                
B10110110, //5           D3  |     | D5
B10111110, //6               |_____| o D6
B00100011, //7                 D4
B10111111, //8
B10110111, //9
B00000000, //пусто
B00111101, //U
B10011000, //c
B10010000, //=
B00111000, //v 
};
void setup()
{ 
D5_Out;D6_Out;D7_Out;
}
 
//**************************************************************************
void loop()
{
 rez=readVcc();
  rez_mass();                 //преобразуем число в массив символов разрядов индикатора
                              // Добавляем в массив надписи "Ucc=   v"
  simv_razr[7]=11;            // "U"
  simv_razr[6]=12;            // "c"
  simv_razr[5]=12;            // "c"
  simv_razr[4]=13;            // "="
  simv_razr[0]=14;            // "v"
  
  Chow_disp(3);               //вывод на дисплей точка отделяет 3 знака
  delay(1000);                //период обновления информации  
}

//**************************   Процедуры  *************************************   
void Chow_disp(byte pt){                     //pt - положение точки
  byte r;
  D5_High;D5_Low;                            // Сброс регистров
  flash=!flash;
  for (byte i = 7; i <255; i--) {
  if ( flash){r= simv[simv_razr[(i)]];if (i==pt)r=r+64;}  //Реверс полярности сегментов
  if (!flash){r=~simv[simv_razr[(i)]];if (i==pt)r=r-64;}  //Реверс полярности сегментов
  writeBits(r); }
  delay(1);  
}



void writeBits(byte data)                    // запись символа в дисплей
{ byte i;
  for ( i = 0; i < 8; i++, data<<=1) {
  if (data & 0x80)D7_High;else D7_Low;
  D6_High; D6_Low;} // строб
}

//*************** измерение напряжения питания ардуино (опорное 1.1 В) *********************************************************

long readVcc() {
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);  delay(2);
  ADCSRA |= _BV(ADSC);
  while (bit_is_set(ADCSRA,ADSC));
  uint8_t low = ADCL;uint8_t high = ADCH;
  long rez = (high<<8) | low;
  rez = (1.1 * 1023*1000) / rez;
  return rez;
}

 //************ преобразуем число в массив символов разрядов индикатора *******************
void rez_mass()
{
simv_razr[0]=(rez%10);
simv_razr[1]=(rez%100/10);if(rez<10)simv_razr[1]=10;
simv_razr[2]=(rez%1000/100);if(rez<100)simv_razr[2]=10;
simv_razr[3]=(rez%10000/1000);if(rez<1000)simv_razr[3]=10;
simv_razr[4]=(rez%100000/10000);if(rez<10000)simv_razr[4]=10;
simv_razr[5]=(rez%1000000/100000);if(rez<100000)simv_razr[5]=10;
simv_razr[6]=(rez%10000000/1000000);if(rez<1000000)simv_razr[6]=10;
simv_razr[7]=(rez%100000000/10000000);if(rez<100000000)simv_razr[7]=10;
}

Быстрое управление портами  Файл  nanopins2.h

#ifndef NANOPINS2_H
#define NANOPINS2_H
//****************INPUT PINS*************
#define D0_In DDRD &=B11111110
#define D1_In DDRD &=B11111101
#define D2_In DDRD &=B11111011
#define D3_In DDRD &=B11110111
#define D4_In DDRD &=B11101111
#define D5_In DDRD &=B11011111
#define D6_In DDRD &=B10111111
#define D7_In DDRD &=B01111111
 
#define D8_In DDRB &= B11111110
#define D9_In DDRB &= B11111101
#define D10_In DDRB &=B11111011
#define D11_In DDRB &=B11110111
#define D12_In DDRB &=B11101111
#define D13_In DDRB &=B11011111

#define D14_In DDRC &=B11111110
#define D15_In DDRC &=B11111101
#define D16_In DDRC &=B11111011
#define D17_In DDRC &=B11110111
#define D18_In DDRC &=B11101111
#define D19_In DDRC &=B11011111

//***************Output Pins*************
#define MotorA0 DDRD |=B00010000
#define MotorA1 DDRD |=B00100000
#define MotorB0 DDRD |=B01000000
#define MotorB1 DDRD |=B10000000
  
#define D0_Out DDRD |=B00000001
#define D1_Out DDRD |=B00000010
#define D2_Out DDRD |=B00000100
#define D3_Out DDRD |=B00001000
#define D4_Out DDRD |=B00010000
#define D5_Out DDRD |=B00100000
#define D6_Out DDRD |=B01000000
#define D7_Out DDRD |=B10000000

#define D8_Out DDRB |= B00000001
#define D9_Out DDRB |= B00000010
#define D10_Out DDRB |=B00000100
#define D11_Out DDRB |=B10001000
#define D12_Out DDRB |=B00010000
#define D13_Out DDRB |=B00100000

#define D14_Out DDRC |=B00000001
#define D15_Out DDRC |=B00000010
#define D16_Out DDRC |=B00000100
#define D17_Out DDRC |=B00001000
#define D18_Out DDRC |=B00010000
#define D19_Out DDRC |=B00100000

//***************Status High Pins*************
#define D0_High PORTD |=B00000001
#define D1_High PORTD |=B00000010
#define D2_High PORTD |=B00000100
#define D3_High PORTD |=B00001000
#define D4_High PORTD |=B00010000
#define D5_High PORTD |=B00100000
#define D6_High PORTD |=B01000000
#define D7_High PORTD |=B10000000

#define D8_High PORTB |=B00000001
#define D9_High PORTB |=B00000010
#define D10_High PORTB|=B00000100
#define D11_High PORTB|=B00001000   
#define D12_High PORTB|=B00010000
#define D13_High PORTB|=B00100000

#define D14_High PORTC |=B00000001
#define D15_High PORTC |=B00000010
#define D16_High PORTC |=B00000100
#define D17_High PORTC |=B00001000
#define D18_High PORTC |=B00010000
#define D19_High PORTC |=B00100000

//***************Status Low Pins*************
#define D0_Low PORTD &= B11111110
#define D1_Low PORTD &= B11111101
#define D2_Low PORTD &= B11111011
#define D3_Low PORTD &= B11110111  
#define D4_Low PORTD &= B11101111  
#define D5_Low PORTD &= B11011111 
#define D6_Low PORTD &= B10111111 
#define D7_Low PORTD &= B01111111 

#define D8_Low PORTB &= B11111110 
#define D9_Low PORTB &= B11111101 
#define D10_Low PORTB &=B11111011 
#define D11_Low PORTB &=B11110111 
#define D12_Low PORTB &=B11101111 
#define D13_Low PORTB &=B11011111 

#define D14_Low PORTC &= B11111110  
#define D15_Low PORTC &= B11111101 
#define D16_Low PORTC &= B11111011 
#define D17_Low PORTC &= B11110111
#define D18_Low PORTC &= B11101111
#define D19_ PORTC &= B11011111

//**************Invers Status Pins*************
#define D0_Inv PORTD ^=B00000001
#define D1_Inv PORTD ^=B00000010
#define D2_Inv PORTD ^=B00000100
#define D3_Inv PORTD ^=B00001000
#define D4_Inv PORTD ^=B00010000
#define D5_Inv PORTD ^=B00100000
#define D6_Inv PORTD ^=B01000000
#define D7_Inv PORTD ^=B10000000

#define D8_Inv PORTB ^=B00000001
#define D9_Inv PORTB ^=B00000010
#define D10_Inv PORTB^=B00000100
#define D11_Inv PORTB^=B00001000
#define D12_Inv PORTB^=B00010000
#define D13_Inv PORTB^=B00100000

#define D14_Inv PORTC ^=B00000001
#define D15_Inv PORTC ^=B00000010
#define D16_Inv PORTC ^=B00000100
#define D17_Inv PORTC ^=B00001000
#define D18_Inv PORTC ^=B00010000
#define D19_Inv PORTC ^=B00100000

//**************READ Status Pins HICH*************
#define D0_RH PIND & B00000001
#define D1_RH PIND & B00000010
#define D2_RH PIND & B00000100
#define D3_RH PIND & B00001000
#define D4_RH PIND & B00010000
#define D5_RH PIND & B00100000
#define D6_RH PIND & B01000000
#define D7_RH PIND & B10000000

#define D8_RH PINB & B00000001
#define D9_RH PINB & B00000010
#define D10_RH PINB & B00000100
#define D11_RH PINB & B00001000
#define D12_RH PINB & B00010000
#define D13_RH PINB & B00100000

#define D14_RH PINC & B00000001
#define D15_RH PINC & B00000010
#define D16_RH PINC & B00000100
#define D17_RH PINC & B00001000
#define D18_RH PINC & B00010000
#define D19_RH PINC & B00100000

//**************READ Status Pins LOW*************
#define D0_RL !(PIND & B00000001)
#define D1_RL !(PIND & B00000010)
#define D2_RL !(PIND & B00000100)
#define D3_RL !(PIND & B00001000)
#define D4_RL !(PIND & B00010000)
#define D5_RL !(PIND & B00100000)
#define D6_RL !(PIND & B01000000)
#define D7_RL !(PIND & B10000000)

#define D8_RL !(PINB & B00000001)
#define D9_RL !(PINB & B00000010 )
#define D10_RL !(PINB & B00000100)
#define D11_RL !(PINB & B00001000)
#define D12_RL !(PINB & B00010000)
#define D13_RL !(PINB & B00100000)

#define D14_RL !(PINC & B00000001)
#define D15_RL !(PINC & B00000010)
#define D16_RL !(PINC & B00000100)
#define D17_RL !(PINC & B00001000)
#define D18_RL !(PINC & B00010000)
#define D19_RL !(PINC & B00100000)

#endif //NANOPINS2_H

Дисплей имеет некоторую особенность, если долго не обновлять информацию, то символы плавно исчезают. Чтобы этого не было в строках 64,65 меняется полярность на сегментах. В спец. микросхемах это происходит на аппаратном уровне. А здесь приходится программно.

svm
Offline
Зарегистрирован: 06.11.2016

Следующий тоже от "Элвес Микро", но более современный на HT1621 (как раз такой,как в начале темы)

Здесь используется допиленная библиотека от HT1621. Два ее файла тоже нужно положить в одну папку со скетчем или в папку с библиотеками, изменив вызов библиотеки. Этот дисплей имеет подсветку и может издавать звуки 1 и 2 кГц. Недостаток - невоэможно полноценно использовать крайний левый разряд, в теме это обсуждалось. Первый сктч кажется просто выводит цифры и значки на дисплей, не помню:

/*  Распайка индикатора STC030801DLGY-E-LM от ККМ "ЭЛВЕС-МИКРО"
 *1  Gnd                              Команды библиотеки
 *2  +5 V                             begin()       инициализация
 *3  Ddat                             clear_all()   очистка дисплея
 *4  Clk                              Ton_2()       звук 2 кГц 200 мс
 *5  CHARGE   зеленый светодиод       Ton_2()       звук 4 кГц 200 мс            
 *6  ACCLO    красный светодиод       Light_ON()      включить подсветку
 *7  DRes                             Light_OFF()     выключить подсветку 
 *8  +5 V                             OUT(a,b,c,d)    выести в позицию а,
 *9  NC                               число b, запятая отделяет с разрядов
 *10 NC                               d 4 или 2 - двоеточие */
#include "ELVES.h"
ELVES tablo(5,6,7); // DDAT,CLK,DRES   согласно схемы ККМ "ЭЛВЕС-МИКРО"
byte dot,dd;
long rez;
byte simv_razr[8];// массив разрядов индикатора
void setup() {

  tablo.begin();
  tablo.Light_ON();
  tablo.Ton_2();
  tablo.clear_all();
}

void loop()
 { 
  rez=1234567;
  dot=3;                    //положение десятичной точки
  dd=2;                     //положение двоеточия (2 или 4)
  rez_mass();               //преобразуем число в массив символов разрядов индикатора
 
  Chow_disp();              //вывод на дисплей
  delay (1000);
  }

//****************************************************************************************

void Chow_disp()       //                вывод на дисплей массива индикатора 
{
   
      for (byte j=0;j<7;j++){
      tablo.OUT(j,(simv_razr[j]),dot,dd);} 
}
 
//****************************************************************************************

//************ преобразуем число в массив символов разрядов индикатора *******************
void rez_mass()
{
simv_razr[0]=(rez%10);
simv_razr[1]=(rez%100/10);
simv_razr[2]=(rez%1000/100);
simv_razr[3]=(rez%10000/1000);
simv_razr[4]=(rez%100000/10000);
simv_razr[5]=(rez%1000000/100000);
simv_razr[6]=(rez%10000000/1000000);
simv_razr[7]=(rez%100000000/10000000);
}
//****************************************************************************************
 /* 
  {
  // ТЕСТ ДИСПЛЕЯ
   tablo.clear_all(); 
  
  for (j=0;j<8;j++){for (i=0;i<10;i++)
  
  {tablo.OUT(j,i,5);delay (150);}}
   
    delay (100);
    }
 */

Файлы библиотеки: ELVES.h и ELVES.cpp



#ifndef _ELVES_h
#define _ELVES_h

#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#define TAKE_CS()    digitalWrite(_CS_pin, LOW)
#define RELEASE_CS() digitalWrite(_CS_pin, HIGH)

class ELVES {
  private:
    uint8_t _DATA_pin;
    uint8_t _RW_pin;
    uint8_t _CS_pin;

  protected:

  public:

    enum Modes : uint8_t {
      COMMAND_MODE = 0b1000, /*!< This is used for sending standard commands. */
      WRITE_MODE = 0b1010, /*!< This instructs the ELVES to prepare for writing the internal RAM. */
      };

    ELVES(uint8_t DATApin, uint8_t RWpin, uint8_t CSpin) : _CS_pin(CSpin), _DATA_pin(DATApin), _RW_pin(RWpin) {};
   
    void begin(void);
  // Очистить память
    void clear_all();
// зажечь в разряде (razr) цифру (dat) , запятая отделяет (dot) последних знаков,dd двоеточие
void OUT(int razr,int dat,int dot,int dd);
   
    void Ton_2();
    void Ton_4();
    void Light_ON();
    void Light_OFF();
        
   // последовательность битов (в количестве (сnt)) отсылается по текущему адресу 
    void writeBits(uint8_t data, uint8_t cnt);
    
    // посылает ID команды (CS не контролируется
    void sendCommand(uint8_t cmd);
    
    //по адресу (address)запись байта (data)
    void write(uint8_t address, uint8_t data);
      
    //по адресу (address)запись байта (data) по (cnt) последовательным адресам.
    void write_c(uint8_t address, uint8_t data, uint8_t cnt);   
   
    //с адреса (address)запись (cnt) байтов (data) 
    void write(uint8_t address, uint8_t *data, uint8_t cnt);
 };   
#endif
#include "ELVES.h"

byte pos[8][3]={
11,9,10,    //   0 разряд
13,8,12,    //
15,7,14,    //
17,6,16,    //
19,5,18,    //
3,4,20,     //   5
0,1, 2,     //   6
22,21,0     //   7 разряд
};
byte simv[30][3]={// знакогенератор 1-х пяти разрядов
12,10,12,   //0
0,0,12,     //1
4,14,8,     //2
0,14,12,    //3
8,4,12,     //4
8,14,4,     //5
12,14,4,    //6
0,8,12,     //7
12,14,12,   //8
8,14,12,    //9  
//  5-6 разряды
4,10,14,    //0
0,0,6,      //1
4,6,12,     //2
0,6,14,     //3
0,12,6,     //4
0,14,10,    //5
4,14,10,    //6
0,0,14,     //7
4,14,14,    //8
0,14,14,    //9

//     7 разряд
8,12,8,     //0 неполноценный болше похож на значек градуса
0,2,8,      //1
6,12,8,     //2
2,14,8,     //3
8,6,8,      //4
10,14,0,    //5
14,14,0,    //6
0,10,8,     //7
14,14,8,    //8
10,14,8,    //9
};

void ELVES::begin()
{
  pinMode(_DATA_pin, OUTPUT);
  pinMode(_RW_pin, OUTPUT);
  pinMode(_CS_pin, OUTPUT);
  digitalWrite(_CS_pin, HIGH);
  digitalWrite(_RW_pin, HIGH);
  digitalWrite(_DATA_pin, HIGH);
  sendCommand(0b00011000);//RC256K
  sendCommand(0b00101000);//BIAS_THIRD_3_COM
  sendCommand(0b00000001);//SYS_EN
  delay (250);
  sendCommand(3);//LCD_ON
 }

void ELVES::writeBits(uint8_t data, uint8_t cnt)
{
  for (register uint8_t i = 0; i < cnt; i++, data <<= 1)
  {
  pinMode(_DATA_pin, OUTPUT);
  digitalWrite(_RW_pin, LOW);
   delayMicroseconds(25);//  после клика

    switch (cnt)
    {
      case 4:
        digitalWrite(_DATA_pin, data & 0x8 ? HIGH : LOW);
        break;
      case 5:
        digitalWrite(_DATA_pin, data & 0x10 ? HIGH : LOW);
        break;
      case 8:
        digitalWrite(_DATA_pin, data & 0x80 ? HIGH : LOW);
        break;
    }
     delayMicroseconds(25);// Длительность данных
    digitalWrite(_RW_pin, HIGH);
     delayMicroseconds(25); // длительность клика
  }
}

void ELVES::sendCommand(uint8_t cmd)
{
  TAKE_CS();
   digitalWrite(_DATA_pin, HIGH);
   delayMicroseconds(25);//
   digitalWrite(_RW_pin, HIGH);//
   delayMicroseconds(25);//
   digitalWrite(_RW_pin, LOW);//
   digitalWrite(_DATA_pin, LOW);

   delayMicroseconds(25);//
   digitalWrite(_RW_pin, HIGH);//
   delayMicroseconds(25);//
   digitalWrite(_RW_pin, LOW);//

   delayMicroseconds(25);//
   digitalWrite(_RW_pin, HIGH);//
   delayMicroseconds(25);//
   digitalWrite(_RW_pin, LOW);//
   
  ELVES::writeBits(cmd, 8);
  digitalWrite(_RW_pin, LOW);
  delayMicroseconds(25);//
  digitalWrite(_RW_pin, HIGH);//
  delayMicroseconds(25);//
  digitalWrite(_RW_pin, LOW);//

  delayMicroseconds(25);//
  RELEASE_CS();
  delayMicroseconds(25);
}
void ELVES::write(uint8_t address, uint8_t data)
{
  TAKE_CS();
  ELVES::writeBits(WRITE_MODE, 4);
  ELVES::writeBits(address, 5);
  ELVES::writeBits(data, 4);
                 digitalWrite(_RW_pin, LOW);
                  delayMicroseconds(25);
                 digitalWrite(_DATA_pin, LOW);
  RELEASE_CS();
                  delayMicroseconds(25);
}

void ELVES::write_c(uint8_t address, uint8_t data, uint8_t cnt)
{
  TAKE_CS();
  ELVES::writeBits(WRITE_MODE, 4);
  ELVES::writeBits(address, 5);
  for (register uint8_t i = 0; i < cnt; i++)
  {
    ELVES::writeBits(data, 4);
  }
      digitalWrite(_RW_pin, LOW);
                  delayMicroseconds(25);
                 digitalWrite(_DATA_pin, LOW);
  RELEASE_CS();
                  delayMicroseconds(25);
}

void ELVES::write(uint8_t address, uint8_t *data, uint8_t cnt)
{
  TAKE_CS();
  ELVES::writeBits(WRITE_MODE, 4);
  ELVES::writeBits(address, 5);
  for (register uint8_t i = 0; i < cnt; i++)
  {
    ELVES::writeBits(data[address + i], 4);
  }
      digitalWrite(_RW_pin, LOW);
                  delayMicroseconds(25);
                 digitalWrite(_DATA_pin, LOW);
  RELEASE_CS();
                  delayMicroseconds(25);
}

void ELVES::clear_all()
{
  ELVES::write_c(0, 0, 32);
}


void ELVES::Ton_2()
{
  sendCommand(0b01100000);//TONE2K
  sendCommand(0b00001001);//TONE_ON
  delay (200);
  sendCommand(0b00001000);//TONE_OFF
}

void ELVES::Ton_4()
{
  sendCommand(0b01000000);//TONE4K
  sendCommand(0b00001001);//TONE_ON
  delay (200);
  sendCommand(0b00001000);//TONE_OFF
}

void ELVES::Light_ON()
{
  sendCommand(0b10001000);//IRQ_EN
}

void ELVES::Light_OFF()
{
  sendCommand(0b10000000);//IRQ_DIS
}

void ELVES::OUT(int razr,int dat,int dot,int dd)        //разряд,число,количество знаков после запятой
{  int d=0;
int k=0;
   if (razr==dot-1)d=2;                   //Ставим точку
   if (razr==dd)k=2;
   if (razr>4)dat=dat+10;                 //Если разряд больше 4 переключаемся на 2 знакогенератор
   if (razr==7)dat=dat+10;                //Если разряд равен  7 переключаемся на 3 знакогенератор
   write_c(pos[razr][0],(simv[dat][0])+d,1);    //+2 точка перед цифрой 
   write_c(pos[razr][1],simv[dat][1],1);//
   write_c(pos[razr][2],(simv[dat][2])+k,1);    //+2 - двоеточие после и точка после 7 разр
}

 

и текстовый файл  keywords.txt

ELVES KEYWORD1
Ton_2 KEYWORD2
Ton_4 KEYWORD2
Light_ON KEYWORD2
Light_OFFKEYWORD2
clear_all KEYWORD2
OUT KEYWORD2
write_c KEYWORD2
 
И второй скетч Часы с установкой из монитора:
 

/*  Распайка индикатора STC030801DLGY-E-LM от ККМ "ЭЛВЕС-МИКРО"
 *1  Gnd                              Команды библиотеки
 *2  +5 V                             begin()       инициализация
 *3  Ddat                             clear_all()   очистка дисплея
 *4  Clk                              Ton_2()       звук 2 кГц 200 мс
 *5  CHARGE   зеленый светодиод       Ton_2()       звук 4 кГц 200 мс            
 *6  ACCLO    красный светодиод       Light_ON()      включить подсветку
 *7  DRes                             Light_OFF()     выключить подсветку 
 *8  +5 V                             OUT(a,b,c,d)    выести в позицию а,
 *9  NC                               число b, запятая отделяет с разрядов
 *10 NC                               d 4 или 2 - двоеточие */
#include "ELVES.h"
ELVES tablo(5,6,7); // DDAT,CLK,DRES   согласно схемы ККМ "ЭЛВЕС-МИКРО"
byte i,j,n;
// часы 

#include <Wire.h>
 #define DS3231_I2C_ADDRESS 0x68
  
 byte seconds, minutes, hours, day, date, month, year;
 char weekDay[4];  
 byte tMSB, tLSB;
 float temp3231;




void setup() {

  tablo.begin();
  tablo.Light_ON();
  tablo.Ton_2();
// часы
 Wire.begin();
   Serial.begin(9600);
   //set control register to output square wave on pin 3 at 1Hz
   Wire.beginTransmission(DS3231_I2C_ADDRESS); // 104 is DS3231 device address
   Wire.write(0x0E); //выставляемся в 14й байт 
   Wire.write(B00000000); //сбрасываем контрольные регистры 
   Wire.write(B10001000); //выставляем 1 на статус OSF и En32kHz
   Wire.endTransmission();

}

void loop()
 { tablo.clear_all();
 L1:
  /* 
  tablo.clear_all(); 
  for (j=0;j<8;j++){for (i=0;i<10;i++)
  {tablo.OUT(j,i,5);delay (150);}}
   delay (100);
*/  
watchConsole(); //читаем консоль. Если нажата "T" читаем из консоли следующий 7 байт и устанавливаем время.    
   get3231Date(); //получаем данные 
/*
          //и выводим их через Serial.print() в монитор   
   Serial.print(weekDay); Serial.print(", "); Serial.print(month, DEC); Serial.print("/"); Serial.print(date, DEC); Serial.print("/"); Serial.print(year, DEC); Serial.print(" - ");
   Serial.print(hours, DEC); Serial.print(":"); Serial.print(minutes, DEC); Serial.print(":"); Serial.print(seconds, DEC);    
   Serial.print("   Temperature: "); Serial.print(get3231Temp());Serial.print("; ");
          Serial.println(get3231Register(0x0F)); //получаем и выводим статусовый регистр
*/   
    //или выводим на дисплей
   
   
    
  
   
   n++;               // Вывод часы, минуты и моргалка двоеточия
   tablo.OUT(2,minutes%10,0,0);//позиция,значение,позиция точки,позиия двоеточия (2,4)
   tablo.OUT(3,minutes%100/10,0,0);
   seconds=seconds%10&1; 
   tablo.OUT(4,hours%10,0,seconds*4);
   tablo.OUT(5,hours%100/10,0,0);
   delay(50);
  if(n< 255)goto L1;
   tablo.clear_all();//     дата , месяц , год
   tablo.OUT(1,year%10,0,0);
   tablo.OUT(2,year%100/10,3,0);
   tablo.OUT(3,month%10,2,0);
   tablo.OUT(4,month%100/10,5,0);
   tablo.OUT(5,date%10,0,0);
   tablo.OUT(6,date%100/10,0,0); 

    delay(3000);
 }
  
 // Convert normal decimal numbers to binary coded decimal
 byte decToBcd(byte val)
 {
   return ( (val/10*16) + (val%10) );
 }
  
 void watchConsole()
 {
   if (Serial.available()) {      // Look for char in serial queue and process if found
     if (Serial.read() == 84) {      //If command = "T" Set Date
       set3231Date();
       get3231Date();
       Serial.println(" ");
     }
   }
 }
    
 void set3231Date()// Установка времени, в терминале набрать "Т"лат, затем значения:
 {
 //T(сек)(мин)(часы)(день недели)(число)(месяц)(год)
 //T(00-59)(00-59)(00-23)(1-7)(01-31)(01-12)(00-99)
 //Например: 15-Февраля-19  13:42:11 5 день недели следует ввести-> T1142135150219 
  
   seconds = (byte) ((Serial.read() - 48) * 10 + (Serial.read() - 48)); // Use of (byte) type casting and ascii math to achieve result. 
   minutes = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
   hours   = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
   day     = (byte) (Serial.read() - 48);
   date    = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
   month   = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
   year    = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));

   Wire.beginTransmission(DS3231_I2C_ADDRESS); //начали сессию
   Wire.write(0x00); //поставляемся в нулевой байт для чтения данных
   Wire.write(decToBcd(seconds));
   Wire.write(decToBcd(minutes));
   Wire.write(decToBcd(hours));
   Wire.write(decToBcd(day));
   Wire.write(decToBcd(date));
   Wire.write(decToBcd(month));
   Wire.write(decToBcd(year));
   Wire.endTransmission();//закрыли сессию
 }
  
 byte get3231Register(byte regNo) {
   // send request to receive data starting at register regNo
   Wire.beginTransmission(DS3231_I2C_ADDRESS); // 104 is DS3231 device address
   Wire.write(regNo); // start at register regNo
   Wire.endTransmission();
   Wire.requestFrom(DS3231_I2C_ADDRESS, 1); // request one byte
   if(Wire.available()) return  Wire.read();
 }
  
 void set3231Register(byte regNo, byte value) {
   Wire.beginTransmission(DS3231_I2C_ADDRESS);
   Wire.write(regNo);
   Wire.write(value);
   Wire.endTransmission();
 }
  
 void get3231Date()
 {
   // send request to receive data starting at register 0
   Wire.beginTransmission(DS3231_I2C_ADDRESS); // 104 is DS3231 device address
   Wire.write(0x00); // start at register 0
   Wire.endTransmission();
   Wire.requestFrom(DS3231_I2C_ADDRESS, 7); // request seven bytes
  
   if(Wire.available()) {
     seconds = Wire.read(); // get seconds
     minutes = Wire.read(); // get minutes
     hours   = Wire.read();   // get hours
     day     = Wire.read();
     date    = Wire.read();
     month   = Wire.read(); //temp month
     year    = Wire.read();

//Конвертация происходит очень просто - битовым оператором & мы очищаем МЛАДШИЕ (0,1,2,3) четыре бита , сдвигаем все вправо на 4 позиции (очищенные биты
//вылезут при этом с левой стороны и результат умножаем на 10, т.к. в старших битах хранится информация о десятках секунд.
//После этого битовым оператором & очищаем СТАРШИЕ (4,5,6,7)четыре бита и получаем секунды. Затем суммируем десятки секунд и единиц.
     seconds = (((seconds & B11110000)>>4)*10 + (seconds & B00001111));
     minutes = (((minutes & B11110000)>>4)*10 + (minutes & B00001111));
     hours   = (((hours & B00110000)>>4)*10 + (hours & B00001111)); 
     day     = (day & B00000111); // 1-7
     date    = (((date & B00110000)>>4)*10 + (date & B00001111)); // 1-31
     month   = (((month & B00010000)>>4)*10 + (month & B00001111)); //msb7 is century overflow
     year    = (((year & B11110000)>>4)*10 + (year & B00001111));
   }
   else {
     //oh noes, no data!
   }
    
   switch (day) {     
     case 1:
       strcpy(weekDay, "Mon");
       break;
     case 2:
       strcpy(weekDay, "Tue");
       break;
     case 3:
       strcpy(weekDay, "Wed");
       break;
     case 4:
       strcpy(weekDay, "Thu");
       break;
     case 5:
       strcpy(weekDay, "Fri");
       break;
     case 6:
       strcpy(weekDay, "Sat");
       break;
            case 7:
       strcpy(weekDay, "Sun");
       break;
   }
 }
  
 float get3231Temp()
 {
   //temp registers (11h-12h) get updated automatically every 64s
   Wire.beginTransmission(DS3231_I2C_ADDRESS);
   Wire.write(0x11);
   Wire.endTransmission();
   Wire.requestFrom(DS3231_I2C_ADDRESS, 2);
    
   if(Wire.available()) {
     tMSB = Wire.read(); //2's complement int portion
     tLSB = Wire.read(); //fraction portion      
     temp3231 = (tMSB & B01111111); //do 2's math on Tmsb
     temp3231 += ( (tLSB >> 6) * 0.25 ); //only care about bits 7 & 8
   }
   else {
     //oh noes, no data!
   }
      
   return temp3231;
 }

Файлы библиотеки те-же

 

svm
Offline
Зарегистрирован: 06.11.2016

Еще один дисплей на двух КР1820ВГ1. Файл nanopins2.h  может отличаться, не помню.

#include "nanopins2.h"
/*
 * Распайка индикатора на КР1820ВГ1  РЮИБ 5.104.543
 * 1 - GKI-D   (DATA)   D5
 * 2 - GKI-C   (CLK)    D6
 * 3 - GKI-W1  (CS-1)   D7
 * 4 - GKI-W1  (CS-2)   D8
 * 5 - GND
 * 6 - UCC +5V
 * Внимание! На входе стоят инверторы поэтому все  управляющие сигналы инверсные
 */

//0000 команда инициализации обеих микросхем
//1111 команда инициализации ведомой микросхемы
//0111 команда записи младших разрядов
//1001 команда записи старших разрядов
byte simv[10]={//          знакогенератор
B11000000, //0                _____
B11111001, //1               | D0  |
B10100100, //2           D5  |     | D1
B10110000, //3               |_____|
B10011001, //4               | D6  |                
B10010010, //5           D4  |     | D2
B10000010, //6               |_____| o D7
B11111000, //7                 D3
B10000000, //8
B10010000, //9            при "0" светится, при "1" нет
};

void setup()
{
   D5_Out;D6_Out;D7_Out;D8_Out;
   // ************      ИНИЦИАЛИЗАЦИЯ ДИСПЛЕЯ      *******      
   byte i;
   D8_High;D7_High; w_xx(36); for (i = 0; i < 4 ; ++i) { D5_Low;strob();}
   D8_Low;D7_Low;D8_High; w_xx(40);D8_Low;
 }
//***************************************************************************
void loop() {
  // Вывод всех сегментов на индикаторе
  
  // ------- запись 4-х младших битов -------------
   D8_High;
   byte i;
   for (i = 0; i <4;i++) {
   writeBits(simv[3-i]+128);}  // 128 - добавляет точку
   writeBits(0b00001111);      //черточки над разрядами + синхро
   D8_Low;
   // ------- запись 4-х старших битов -------------
   D7_High;
   for (i = 0; i <4; i++) {
   writeBits(simv[7-i]+128);}   // 128 - добавляет точку
   writeBits(0b00001001);       //черточки над разрядами + синхро
   D7_Low; 
}

//**************************   Процедуры  *************************************   

void strob(){D6_Low;D6_High;}

void w_xx(byte n )            //запись n нулей в память дисплея
{byte i;for (i = 0; i < n; ++i) {D5_High;strob();}}

void writeBits(byte data)     // запись символа в дисплей
{ byte i;
  for ( i = 0; i < 8; i++, data<<=1) {
  if (data & 0x80)D5_High;
  else D5_Low;
  strob();
  }}

Файл nanopins2.h

#ifndef NANOPINS2_H
#define NANOPINS2_H
//****************INPUT PINS*************
#define D0_In DDRD &=B11111110
#define D1_In DDRD &=B11111101
#define D2_In DDRD &=B11111011
#define D3_In DDRD &=B11110111
#define D4_In DDRD &=B11101111
#define D5_In DDRD &=B11011111
#define D6_In DDRD &=B10111111
#define D7_In DDRD &=B01111111
 
#define D8_In DDRB &= B11111110
#define D9_In DDRB &= B11111101
#define D10_In DDRB &=B11111011
#define D11_In DDRB &=B11110111
#define D12_In DDRB &=B11101111
#define D13_In DDRB &=B11011111

#define D14_In DDRC &=B11111110
#define D15_In DDRC &=B11111101
#define D16_In DDRC &=B11111011
#define D17_In DDRC &=B11110111
#define D18_In DDRC &=B11101111
#define D19_In DDRC &=B11011111

//***************Output Pins*************
#define MotorA0 DDRD |=B00010000
#define MotorA1 DDRD |=B00100000
#define MotorB0 DDRD |=B01000000
#define MotorB1 DDRD |=B10000000
  
#define D0_Out DDRD |=B00000001
#define D1_Out DDRD |=B00000010
#define D2_Out DDRD |=B00000100
#define D3_Out DDRD |=B00001000
#define D4_Out DDRD |=B00010000
#define D5_Out DDRD |=B00100000
#define D6_Out DDRD |=B01000000
#define D7_Out DDRD |=B10000000

#define D8_Out DDRB |= B00000001
#define D9_Out DDRB |= B00000010
#define D10_Out DDRB |=B00000100
#define D11_Out DDRB |=B10001000
#define D12_Out DDRB |=B00010000
#define D13_Out DDRB |=B00100000

#define D14_Out DDRC |=B00000001
#define D15_Out DDRC |=B00000010
#define D16_Out DDRC |=B00000100
#define D17_Out DDRC |=B00001000
#define D18_Out DDRC |=B00010000
#define D19_Out DDRC |=B00100000

//***************Status High Pins*************
#define D0_High PORTD |=B00000001
#define D1_High PORTD |=B00000010
#define D2_High PORTD |=B00000100
#define D3_High PORTD |=B00001000
#define D4_High PORTD |=B00010000
#define D5_High PORTD |=B00100000
#define D6_High PORTD |=B01000000
#define D7_High PORTD |=B10000000

#define D8_High PORTB |=B00000001
#define D9_High PORTB |=B00000010
#define D10_High PORTB|=B00000100
#define D11_High PORTB|=B00001000   
#define D12_High PORTB|=B00010000
#define D13_High PORTB|=B00100000

#define D14_High PORTC |=B00000001
#define D15_High PORTC |=B00000010
#define D16_High PORTC |=B00000100
#define D17_High PORTC |=B00001000
#define D18_High PORTC |=B00010000
#define D19_High PORTC |=B00100000

//***************Status Low Pins*************
#define D0_Low PORTD &= B11111110
#define D1_Low PORTD &= B11111101
#define D2_Low PORTD &= B11111011
#define D3_Low PORTD &= B11110111  
#define D4_Low PORTD &= B11101111  
#define D5_Low PORTD &= B11011111 
#define D6_Low PORTD &= B10111111 
#define D7_Low PORTD &= B01111111 

#define D8_Low PORTB &= B11111110 
#define D9_Low PORTB &= B11111101 
#define D10_Low PORTB &=B11111011 
#define D11_Low PORTB &=B11110111 
#define D12_Low PORTB &=B11101111 
#define D13_Low PORTB &=B11011111 

#define D14_Low PORTC &= B11111110  
#define D15_Low PORTC &= B11111101 
#define D16_Low PORTC &= B11111011 
#define D17_Low PORTC &= B11110111
#define D18_Low PORTC &= B11101111
#define D19_ PORTC &= B11011111

//**************Invers Status Pins*************
#define D0_Inv PORTD ^=B00000001
#define D1_Inv PORTD ^=B00000010
#define D2_Inv PORTD ^=B00000100
#define D3_Inv PORTD ^=B00001000
#define D4_Inv PORTD ^=B00010000
#define D5_Inv PORTD ^=B00100000
#define D6_Inv PORTD ^=B01000000
#define D7_Inv PORTD ^=B10000000

#define D8_Inv PORTB ^=B00000001
#define D9_Inv PORTB ^=B00000010
#define D10_Inv PORTB^=B00000100
#define D11_Inv PORTB^=B00001000
#define D12_Inv PORTB^=B00010000
#define D13_Inv PORTB^=B00100000

#define D14_Inv PORTC ^=B00000001
#define D15_Inv PORTC ^=B00000010
#define D16_Inv PORTC ^=B00000100
#define D17_Inv PORTC ^=B00001000
#define D18_Inv PORTC ^=B00010000
#define D19_Inv PORTC ^=B00100000

//**************READ Status Pins HICH*************
#define D0_RH PIND & B00000001
#define D1_RH PIND & B00000010
#define D2_RH PIND & B00000100
#define D3_RH PIND & B00001000
#define D4_RH PIND & B00010000
#define D5_RH PIND & B00100000
#define D6_RH PIND & B01000000
#define D7_RH PIND & B10000000

#define D8_RH PINB & B00000001
#define D9_RH PINB & B00000010
#define D10_RH PINB & B00000100
#define D11_RH PINB & B00001000
#define D12_RH PINB & B00010000
#define D13_RH PINB & B00100000

#define D14_RH PINC & B00000001
#define D15_RH PINC & B00000010
#define D16_RH PINC & B00000100
#define D17_RH PINC & B00001000
#define D18_RH PINC & B00010000
#define D19_RH PINC & B00100000

//**************READ Status Pins LOW*************
#define D0_RL !(PIND & B00000001)
#define D1_RL !(PIND & B00000010)
#define D2_RL !(PIND & B00000100)
#define D3_RL !(PIND & B00001000)
#define D4_RL !(PIND & B00010000)
#define D5_RL !(PIND & B00100000)
#define D6_RL !(PIND & B01000000)
#define D7_RL !(PIND & B10000000)

#define D8_RL !(PINB & B00000001)
#define D9_RL !(PINB & B00000010 )
#define D10_RL !(PINB & B00000100)
#define D11_RL !(PINB & B00001000)
#define D12_RL !(PINB & B00010000)
#define D13_RL !(PINB & B00100000)

#define D14_RL !(PINC & B00000001)
#define D15_RL !(PINC & B00000010)
#define D16_RL !(PINC & B00000100)
#define D17_RL !(PINC & B00001000)
#define D18_RL !(PINC & B00010000)
#define D19_RL !(PINC & B00100000)

#endif //NANOPINS2_H

Ну и тот-же вольтметр питающего напряжения:

#include "nanopins2.h"
/*
 * Распайка индикатора на КР1820ВГ1  РЮИБ 5.104.543
 * 1 - GKI-D   (DATA)   D5
 * 2 - GKI-C   (CLK)    D6
 * 3 - GKI-W1  (CS-1)   D7
 * 4 - GKI-W1  (CS-2)   D8
 * 5 - GND
 * 6 - UCC +5V
 * Внимание! На входе стоят инверторы поэтому все  управляющие сигналы инверсные
 */

//0000 команда инициализации обеих микросхем
//1111 команда инициализации ведомой микросхемы
//0111 команда записи младших разрядов
//1001 команда записи старших разрядов
byte simv[18]={//          знакогенератор
B11000000, //0                _____
B11111001, //1               | D0  |
B10100100, //2           D5  |     | D1
B10110000, //3               |_____|
B10011001, //4               | D6  |                
B10010010, //5           D4  |     | D2
B10000010, //6               |_____| o D7
B11111000, //7                 D3
B10000000, //8
B10010000, //9            при "0" светится, при "1" нет
B11111111, //пробел
B10111111, //минус
B10011100, //градус
B11000110, //C
B11000001, //U
B10100111, //c
B10110111, //= 
B11100011, //v 
};
byte u,p;
long rez;
byte simv_razr[8];// массив 

void setup()
{
   D5_Out;D6_Out;D7_Out;D8_Out;
   //Serial.begin(9600);
   
   // ************      ИНИЦИАЛИЗАЦИЯ ДИСПЛЕЯ      *******      
   byte i;
   D8_High;D7_High; w_xx(36); for (i = 0; i < 4 ; ++i) { D5_Low;strob();}
   D8_Low;D7_Low;D8_High; w_xx(40);D8_Low;
 }
//***************************************************************************
void loop() {
  rez=readVcc();
  u=0b00000000;               // "1" - над разрядом черточка, "0" - нет черточки
  p=0b00001000;               // "1" - за разрядом точка, "0" - нет точки
  
  rez_mass();                 //преобразуем число в массив символов разрядов индикатора
                              // Добавляем в массив надписи "Ucc=   v"
  simv_razr[4]=16;            // "U"
  simv_razr[5]=15;            // "c"
  simv_razr[6]=15;            // "c"
  simv_razr[7]=14;            // "="
  simv_razr[0]=17;            // "v"
  
  Chow_disp();                //вывод массива разрядов индикатора на дисплей
  delay(1000);                //период обновления информации
}

//***************************************************************************   

void strob(){D6_Low;D6_High;}

void w_xx(byte n )            //запись n нулей в память дисплея
{byte i;for (i = 0; i < n; ++i) {D5_High;strob();}}

void writeBits(byte data)     // запись символа в дисплей
{ byte i;
  for ( i = 0; i < 8; i++, data <<=1) {
  if (data & 0x80)D5_High;
  else D5_Low;
  strob();
  }}

  //************ преобразуем число в массив символов разрядов индикатора *******************
void rez_mass()
{
simv_razr[0]=(rez%10);
simv_razr[1]=(rez%100/10);if(rez<10)simv_razr[1]=10;
simv_razr[2]=(rez%1000/100);if(rez<100)simv_razr[2]=10;
simv_razr[3]=(rez%10000/1000);if(rez<1000)simv_razr[3]=10;
simv_razr[4]=(rez%100000/10000);if(rez<10000)simv_razr[4]=10;
simv_razr[5]=(rez%1000000/100000);if(rez<100000)simv_razr[5]=10;
simv_razr[6]=(rez%10000000/1000000);if(rez<1000000)simv_razr[6]=10;
simv_razr[7]=(rez%100000000/10000000);if(rez<100000000)simv_razr[7]=10;
}
//****************************************************************************************
void Chow_disp()
{
  u=~u;if (u<128)u=(u<<1);    // исправляем косяк распайки индикатора
  else (u<<1)+1;              
  
  // ------- запись 4-х младших битов -------------
   D8_High;
   byte i;
   for (i = 3; i <255; --i) {
   byte x=255;
   if (p & (1<<i))x=127;                       //расставляем точки
   writeBits(simv[simv_razr[(i)]]&x);}
   writeBits((u<<4 & 0b11110000)+0b1111);      //черточки над разрядами + синхро
   D8_Low;
   // ------- запись 4-х старших битов -------------
   D7_High;
   for (i = 7; i > 3; --i) {
   byte x=255;
   if (p & (1<<i))x=127;                       //расставляем точки
   writeBits(simv[simv_razr[(i)]]&x);}
   writeBits((u & 0b11110000)+0b1001);         //черточки над разрядами + синхро
   D7_Low; 
}
//************************************************************************

long readVcc() {//измерение напряжения питания ардуино (опорное 1.1 В)
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);  delay(2);
  ADCSRA |= _BV(ADSC);
  while (bit_is_set(ADCSRA,ADSC));
  uint8_t low = ADCL;uint8_t high = ADCH;
  long rez = (high<<8) | low;
  rez = (1.1 * 1023*1000) / rez;
  return rez;
}

 

svm
Offline
Зарегистрирован: 06.11.2016

Ну и последний из тех что нашел от ККМ ЭКР2102 предыдущий использовался на более ранних моделях.

#include "ht1621.h"
/*
1   DATA
2   WR
3   CS
4   NC
5   GND
6   +5V
*/
#define DATA_PIN  5
#define WR_PIN    6
#define CS_PIN    7
#define RD_PIN    8
  byte DigitC = 0;
  char Str[25] = "HELL0,123";
  HT1621 ht1621(DATA_PIN, WR_PIN, RD_PIN, CS_PIN);

byte pos; byte val;
byte arrASCII[48][3]={
 { 0b0110, 0b1100, 0b0110}, //0  0х30
 { 0b0000, 0, 0b0110},           //1
 { 0b0010, 0b1110, 0b0100}, //2
 { 0b0000, 0b1110, 0b0110},      //3
 { 0b0100, 0b0010, 0b0110}, //4
 { 0b0100, 0b1110, 0b0010}, //5
 { 0b0110, 0b1110, 0b0010}, //6
 { 0b0000, 0b0100, 0b0110}, //7
 { 0b0110, 0b1110, 0b0110}, //8
 { 0b0100, 0b1110, 0b0110}, //9
 { 0, 0, 0},                //
 { 0, 0, 0},                //
 { 0, 0, 0},                //
 { 0b0000, 0b0100, 0b0000}, //  = -  0x3D
 { 0, 0, 0},                //
 { 0, 0, 0},                //  0x3F
 
 { 0, 0, 0},                //  0х40
 { 0b1100, 0b1100, 0b1100}, //A
 { 0b0100, 0b0110, 0b1100}, //B (мал)
 { 0b0000, 0b1010, 0b1100}, //C
 { 0b1100, 0b0110, 0b0100}, //D (мал)
 { 0b0110, 0b1110, 0b0000}, //E
 { 0b0000, 0b1100, 0b1100}, //F
 { 0b0100, 0b1010, 0b1100}, //G
 { 0b0110, 0b0010, 0b0110}, //H
 { 0b0000, 0b0000, 0b1100}, //I
 { 0b1100, 0b0010, 0b0100}, //J
 { 0, 0, 0}, //K
 { 0b0110, 0b1000, 0b0000}, //L
 { 0, 0, 0}, //M
 { 0b0100, 0b0100, 0b0100}, //N (мал)
 { 0b0100, 0b0110, 0b0100}, //O (мал)
 
 { 0b1000, 0b1100, 0b1100}, //P  0х50
 { 0, 0, 0},                //Q
 { 0b0000, 0b0100, 0b0100}, //R (мал)
 { 0b0100, 0b1110, 0b1000}, //S
 { 0b0000, 0b0110, 0b1100}, //T (мал)
 { 0b1100, 0b0010, 0b1100}, //U
 { 0, 0, 0},                //V
 { 0, 0, 0},                //W
 { 0, 0, 0},                //X
 { 0b1100, 0b0110, 0b1000}, //Y
 { 0, 0, 0}, //Z
 { 0b0000, 0b1010, 0b1100}, //[
 { 0, 0, 0}, //
 { 0b1100, 0b1010, 0b0000}, //]
 { 0b0000, 0b1000, 0b0000}, //^
 { 0b0000, 0b0010, 0b0000}, //_
};

//создаём новую функцию для отображения по шаблону "позиция-цифра" (подчеркивание, точка):
void writeSymbol(byte pos, byte val, byte und, byte pnt)
  { byte tek3; byte adr;
    pos--;
    if (val < 0x20) return;
    if (val > 0x5F) return;
    if (val == ' ') val = 0x3F;  //пробел отдельно
    if (val == '-') val = 0x3D;  //минус
    val = val - 0x30;
  for (byte j = 0; j < 3; j++)
    { tek3 = arrASCII[val][j];
      if (pnt == 1 && j == 2) tek3 = tek3 | 0b1000;  //ставим подчеркивание
      if (und == 1 && j == 0) tek3 = tek3 | 0b1000;  //ставим точку
      adr = 3*pos+8+j;
      ht1621.writeMem(adr, tek3);
    }
  }
  
void writeString(char Str[25])
 { byte pos = 1;  //позиция индикатора (слева - направо от 8 до 1)
   byte und = 0;  //признак подчеркивания (указателя)
   byte pnt = 0;  //наличие в знакоместе точки
   byte symb;     //текущий символ
   byte i = 0;
   while (pos < 9)      {
         und = 0; pnt = 0; symb = Str[i];
         if (symb == '!') {und = 1;i++;}
         symb = Str[i]; i++;
         if (Str[i] == '.' || Str[i] == ',') {pnt = 1; i++;}
         writeSymbol(pos,symb,und,pnt);
         pos++;
    }  
 }  
  
void setup(){
  pinMode(DATA_PIN, OUTPUT);
  pinMode(WR_PIN,   OUTPUT);
  pinMode(CS_PIN,   OUTPUT);
 
  ht1621.begin();
}

void loop()
{
writeString(Str); 
delay (1000);
writeString("!H!ELL0,456"); 
delay (1000);
}

Файл  ht1621.h 

/* HT1621 - Holtek RAM Mapping 32x4 LCD Controller */
#ifndef HT1621_H
#define HT1621_H

#include <inttypes.h>

class HT1621 {
public:
    enum {
        SYS_DIS   = 0b00000000,
        SYS_EN    = 0b00000001,
        LCD_OFF   = 0b00000010,
        LCD_ON    = 0b00000011,
        TIMER_DIS = 0b00000100,
        WDT_DIS   = 0b00000101,
        TIMER_EN  = 0b00000110,
        WDT_EN    = 0b00000111,
        TONE_OFF  = 0b00001000,
        TONE_ON   = 0b00001001,
        
        //Set bias to 1/2 or 1/3 cycle
        //Set to 2,3 or 4 connected COM lines
        BIAS_HALF_2_COM  = 0b00100000,
        BIAS_HALF_3_COM  = 0b00100100,
        BIAS_HALF_4_COM  = 0b00101000,
        BIAS_THIRD_2_COM = 0b00100001,
        BIAS_THIRD_3_COM = 0b00100101,
        BIAS_THIRD_4_COM = 0b00101001,
        
        //Don't use
        TEST_ON   = 0b11100000,
        TEST_OFF  = 0b11100011
    } Commands;

    HT1621(uint8_t data, uint8_t wr, uint8_t rd, uint8_t cs) : 
        data_pin(data), wr_pin(wr), rd_pin(rd), cs_pin(cs) {}

    bool begin();

    void sendCommand(uint8_t cmd, bool first = true, bool last = true);

    void write(uint8_t address, uint8_t *data, uint8_t cnt);
    void read(uint8_t address, uint8_t *data, uint8_t cnt);

    void writeMem(uint8_t address, uint8_t data);
    uint8_t readMem(uint8_t address);

    void memset(uint8_t address, uint8_t data, uint8_t cnt);

private:
    void writeBits(uint8_t data, uint8_t cnt);
    uint8_t readBits(uint8_t cnt);

    inline void initControlBus();
    inline bool testMem();
    
    uint8_t data_pin;
    uint8_t wr_pin;
    uint8_t rd_pin;
    uint8_t cs_pin;
};

#endif //HT1621_H

И файл ht1621.cpp

/* HT1621 - Holtek RAM Mapping 32x4 LCD Controller */
#ifndef HT1621_H
#define HT1621_H

#include <inttypes.h>

class HT1621 {
public:
    enum {
        SYS_DIS   = 0b00000000,
        SYS_EN    = 0b00000001,
        LCD_OFF   = 0b00000010,
        LCD_ON    = 0b00000011,
        TIMER_DIS = 0b00000100,
        WDT_DIS   = 0b00000101,
        TIMER_EN  = 0b00000110,
        WDT_EN    = 0b00000111,
        TONE_OFF  = 0b00001000,
        TONE_ON   = 0b00001001,
        
        //Set bias to 1/2 or 1/3 cycle
        //Set to 2,3 or 4 connected COM lines
        BIAS_HALF_2_COM  = 0b00100000,
        BIAS_HALF_3_COM  = 0b00100100,
        BIAS_HALF_4_COM  = 0b00101000,
        BIAS_THIRD_2_COM = 0b00100001,
        BIAS_THIRD_3_COM = 0b00100101,
        BIAS_THIRD_4_COM = 0b00101001,
        
        //Don't use
        TEST_ON   = 0b11100000,
        TEST_OFF  = 0b11100011
    } Commands;

    HT1621(uint8_t data, uint8_t wr, uint8_t rd, uint8_t cs) : 
        data_pin(data), wr_pin(wr), rd_pin(rd), cs_pin(cs) {}

    bool begin();

    void sendCommand(uint8_t cmd, bool first = true, bool last = true);

    void write(uint8_t address, uint8_t *data, uint8_t cnt);
    void read(uint8_t address, uint8_t *data, uint8_t cnt);

    void writeMem(uint8_t address, uint8_t data);
    uint8_t readMem(uint8_t address);

    void memset(uint8_t address, uint8_t data, uint8_t cnt);

private:
    void writeBits(uint8_t data, uint8_t cnt);
    uint8_t readBits(uint8_t cnt);

    inline void initControlBus();
    inline bool testMem();
    
    uint8_t data_pin;
    uint8_t wr_pin;
    uint8_t rd_pin;
    uint8_t cs_pin;
};

#endif //HT1621_H

Библиотека, кажется стандартная. Были еще какие-то варианты без библиотек, но пока не нашел. Попадутся добавлю

Electr0
Offline
Зарегистрирован: 24.06.2019

касательно этого примера работает, единственно не включает подсветку по краем дисплея (на мультиметре на контанктах А и К приходящих с нее постоянка скачет 0.1-0.2 вольт, перевел в перенку показывает 2.0 вольта), если подать вручную на A = 5+v и на K = GND то подсвечивает желтым, в принципе это уже не большая проблема ведь можно просто отдельным логическим пином включать (но тут вопрос в том какое же напряжение ей нужно, вдруг ниже 5V, хотя уже при 3.3V она не горит), спасибо вам большое за информацию

Electr0
Offline
Зарегистрирован: 24.06.2019

Electr0 пишет:

касательно этого примера работает, единственно не включает подсветку по краем дисплея (на мультиметре на контанктах А и К приходящих с нее постоянка скачет 0.1-0.2 вольт, перевел в перенку показывает 2.0 вольта), если подать вручную на A = 5+v и на K = GND то подсвечивает желтым, в принципе это уже не большая проблема ведь можно просто отдельным логическим пином включать (но тут вопрос в том какое же напряжение ей нужно, вдруг ниже 5V, хотя уже при 3.3V она не горит), спасибо вам большое за информацию

Нашел проблему, как оказалось я не подал на 8 пин 5v а ведь указано в описании, хорошо что я не стал использовать схему с подачей 5v т.к. еще по памяти помню что они должны гореть зеленым, а желтый это уже явный перебор, теперь все работает)

 

 

svm
Offline
Зарегистрирован: 06.11.2016

В принципе, дисплеи неплохие и в некоторых конструкциях смотрятся вполне гармонично. Еще один их плюс - это доступность. Сейчас по гаражам и сараям валяются миллионы никому не нужных ККМ. И если есть знакомые предприниматели со стажем, хотя-бы лет 10, то у них точно пара-тройка найдется. Да и кроме дисплея там многое, что можно использовать. БП, клавиатура, часы реального времени, драйвера шаговиков, а в более древних моделях и сами шаговики, пищалки ну и мелочевка разная. Ну а если отойти от Ардуино, то и прцессор можно использовать. Кстати в ЭКЛЗ стоит процессор на порядок мощнее любой из ардуинок.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

svm, +100500!

svm
Offline
Зарегистрирован: 06.11.2016

ЕвгенийП пишет:

svm, +100500!

Служу народу!

vladimir_62
Offline
Зарегистрирован: 18.01.2019

svm пишет:

В принципе, дисплеи неплохие и в некоторых конструкциях смотрятся вполне гармонично. Еще один их плюс - это доступность. Сейчас по гаражам и сараям валяются миллионы никому не нужных ККМ. И если есть знакомые предприниматели со стажем, хотя-бы лет 10, то у них точно пара-тройка найдется. Да и кроме дисплея там многое, что можно использовать. БП, клавиатура, часы реального времени, драйвера шаговиков, а в более древних моделях и сами шаговики, пищалки ну и мелочевка разная. Ну а если отойти от Ардуино, то и прцессор можно использовать. Кстати в ЭКЛЗ стоит процессор на порядок мощнее любой из ардуинок.

 

Привет. Еще один дисплей попался fm16032. Помимо стандартного подключения можно подключить по 2-м проводам. Могу выложить (опять же для LPC) - разместите в своей копилке.

svm
Offline
Зарегистрирован: 06.11.2016

Выкладывайте, кому то пригодится.

vladimir_62
Offline
Зарегистрирован: 18.01.2019
#include <LPC214x.h>

#define led  0x00100000
#define THRE (1<<5) // Transmit Holding Register Empty
#define RDR (1<<0) // Receiver Data Ready
#define MULVAL 15
#define DIVADDVAL 1


//CLEAR      0 0 0 0 0 0 0 0  0   1  |Fill DDRAM with "20H", and set DDRAM address counter (AC)to "00H" 1.6 ms 
//HOME       0 0 0 0 0 0 0 0  1   X  |Set DDRAM address counter(AC)to "00H", and put cursor to origin ;the content of DDRAM are not changed 72us
//ENTRY MODE 0 0 0 0 0 0 0 1 I/D  S  |Set cursor position and display shift when doing write or read operation 72us
//

void out_bit_to_lcd(unsigned long int data);	
void lcd_send_data (char d);
void lcd_send_command (char d);
void SystemInit(void);
void delay_(int d);
void Timer0_Init(void);
void LcdInit (void);
void DisplayRow (int row, char *str);
void delay(unsigned int counts);
void UART0_init(void);
__irq void timer0_ISR(void);
__irq void uart0_ISR(void);
void UART0_RxString(void);
char buf[20]; char flag_buf; 	char i_rx = 0;
void U0Write(char data);	



int main(void)
{
	
SystemInit();
IO0DIR |= led;
Timer0_Init();
UART0_init();
delay(4);
LcdInit();

	
	DisplayRow (1,"LCD FM16032  16-09"); // Display on 1st row 
	DisplayRow (2,"CONTROLLER LPC-2146"); // Display on 2nd row
 
	while(1)
{	
T0TCR = 0x01;		//Start Timer
}
}
 
void Timer0_Init(void)
{
  T0CTCR = 0x0;   //Set Timer 0 into Timer Mode
  T0PR = 59999;   //Increment T0TC at every 60000 clock cycles Count begins from zero hence subtracting 1 60000 clock cycles @60Mhz = 1 mS

  T0MR0 = 500-1;   //Zero Indexed Count-hence subtracting 1 (t=500 ms)
  T0MCR = (1<<0) | (1<<1);//Set bit0 & bit1 to Interrupt & Reset TC on MR0  
 
	
	VICVectAddr1 = (unsigned )timer0_ISR; //Pointer Interrupt Function (ISR)
  VICVectCntl1 = (1<<5) | 4; //(bit 5 = 1)->to enable Vectored IRQ slot 1
  VICIntEnable = (1<<4); // Enable timer0 interrupt
	T0TCR = 0x02;   //Reset Timer
	
  VICVectAddr2 = (unsigned )uart0_ISR; //Pointer Interrupt Function (ISR)
  VICVectCntl2 = (1<<5) | 6; //(bit 5 = 1)->to enable Vectored IRQ slot 2
//  VICIntEnable = (1<<6); // Enable uart0 interrupt
//	U0IER=0x1;

	  
}

void delay(unsigned int counts) //Using Timer0
{
    T0TCR = 0x02;        //Reset Timer
    T0TCR = 0x01;        //Enable timer
		IO0PIN ^= led; 
    while(T0TC < counts);//wait until TC reaches the desired delay
    T0TCR = 0x00;        //Disable timer
}

__irq void timer0_ISR(void)
{
	long int readVal;
	IO0PIN ^= led; // Toggle LED at Pin P0.10	
	readVal = T0IR; // Read current IR value 
	T0IR = readVal; // Write back to IR to clear Interrupt Flag
	VICVectAddr = 0x0; // End of interrupt execution
}


__irq void uart0_ISR(void)
{

long int readVal;
readVal=U0IIR;

VICVectAddr = 0x0; // End of interrupt execution
}

void LcdInit(void)
{
IO0DIR |= 0xD0; // Configure P0.4(EN) and P0.6(WR) and P0.7(RS) as Output
IO0CLR=(1<<6); //SCLK
IO0SET=(1<<7); //CS
IO0CLR=(1<<4); //SCLK


lcd_send_command(0x20); //Function Set: 4-bit, 2 Line, 5x7 Dots
lcd_send_command(0x08); //Display Off, cursor Off
lcd_send_command(0x0c); //Display On, cursor Off
lcd_send_command(0x06); //Entry Mode
}
 
 
void DisplayRow (int row, char *str)
{
int k ;
 
if (row == 1)
lcd_send_command(0x80);
else
lcd_send_command(0x90);

for(k = 0 ; k < 20 ; k ++)
 {
 if (str[k])
 { 
 lcd_send_data(str[k]);
 }
 else
 break;
 }
 while(k < 20)
 {
 lcd_send_data(' ');	 
 k ++ ;
 }
}
 


void delay_(int d)
{
 int i;
 for(i=0;i<d;i++); 
}


void UART0_init(void)
{
	PINSEL0 = 0x5;  /* Select TxD for P0.0 and RxD for P0.1 */
	U0LCR = 3 | (1<<7) ; /* 8 bits, no Parity, 1 Stop bit | DLAB set to 1  */
	U0DLL = 110;
	U0DLM = 1;   
	U0FDR = (MULVAL<<4) | DIVADDVAL; /* MULVAL=15(bits - 7:4) , DIVADDVAL=0(bits - 3:0)  */
	U0LCR &= 0x0F; // Set DLAB=0 to lock MULVAL and DIVADDVAL
	U0IER = 0x00000003;	/* Enable THRE and RBR interrupt */	
	//BaudRate is now ~9600 and we are ready for UART communication!
}

void U0Write(char data)
{
	while ( !(U0LSR & THRE ) ); // wait till the THR is empty
	// now we can write to the Tx FIFO
	U0THR = data;
}

char U0Read(void)
{
	while( !(U0LSR & RDR ) ); // wait till any data arrives into Rx FIFO
	return U0RBR;

}

void UART0_RxString(void) //A function to receive string on UART0
{
	char i = 0;
	do{
	while( (U0LSR & 0x01) == 0){};
		buf[i] = U0RBR;
		i++;
	}while( (U0RBR != 0x0D) );
}




void lcd_send_data (char d) 
{
unsigned long int data=0;
data=0x00FA0000 | ((d&0xF0)<<8)|((d&0x0F)<<4);	
out_bit_to_lcd(data);	
}

void lcd_send_command (char d)
{
unsigned long int data=0;
data=0x00F80000 | ((d&0xF0)<<8)|((d&0x0F)<<4);	
out_bit_to_lcd(data);	
}


void out_bit_to_lcd(unsigned long int data)
{
unsigned long int mask=0x00800000;
while (mask>0)
{

IO0CLR=(1<<4);		
if (data&mask) IO0SET=(1<<6); else IO0CLR=(1<<6);
delay_(2);
IO0SET = (1<<4);
delay_(2);
mask>>=1;	
}	
}	

void SystemInit(void) //PLL
{
  PLL0CON = 0x01; // PPLE=1 & PPLC=0, only PLL enabled but not connected 
  PLL0CFG = 0x24; // set the multipler to 5 (i.e actually 4)  12x5 = 60 Mhz (M - 1 = 4)!!!
	PLL0FEED = 0xAA; // Unlock the PLL registers by sending the sequence(0xAA-0x55)
  PLL0FEED = 0x55;
  while( !( PLL0STAT & 0x00000400 ))    {}
  PLL0CON = 0x03;
  PLL0FEED = 0xAA; // lock the PLL registers after setting the required PLL
  PLL0FEED = 0x55;
  VPBDIV = 0x01; // PCLK is same as CCLK i.e 60Mhz  
}

 

vladimir_62
Offline
Зарегистрирован: 18.01.2019

выложил. в принципе там все понятно. 

datasheet: https://www.lcd-module.de/eng/pdf/zubehoer/st7920_chinese.pdf 

p.38. цепляется по 2-м проводам + земля+5v. итого четыре провода. 

vladimir_62
Offline
Зарегистрирован: 18.01.2019

Добрый день.

Еще один дисплей от Меттлер Толедо нужен в копилку ? Протокол i2c.