Что-то пока не поддается, вроде с даташитом разобрался , но не взлетела.
Напмсал отдельно три команды инициализацию и включение звука. Запустил их по кругу, чтобы посмотреть что отправляется от МК к дисплею. Пришлось из DS138 сделать псевдо трехканальный осциллограф, чтобы совместить три осциллограммы. Благо сигнал цифровой и можно обойтись 4 резисторами. Но просмотр картинки ничего не дал, вроде все логично и даташиту не противоречит. Есть несколько вариантов:
1. Не хватает команд для инициализации
2. Не те тайминги
3. Что-то не догоняю, и посылаю не то
Вот фото с экрана осциллографа, и немного дополнительной информации:
Вы у себя не сможете проверить минимальный набор команд для проверки?
Не хочет, прбовал еще вставлять 18Н, вроде как выбор тактового генератора. У Вас в отладчике между пунктирными линиями сетки 10 мкс? А то у меня клоки по 40 мкс, может здесь собака порылась? Попробую еще библиотеку поправить.
Сейчас 200 мс перед инициализацией и по 10 между всеми командами. Правда в процессе перетыкания проводов случайно загорелась верхняя половина разрядов, и все. Дальше тишина. Другая модификация индикатора намного проще.
если все резисторы одинаковые - почему уровень на данных такой низкий относительно других.
Резисторы специально разные, чтобы каналы по уровню отличались, а то их можно перепутать. Кроме того по самому всокому (CS) происходит синхронизация ослика.
Владимир, у тебя не сохранилась таблица соответствия адресов и сегментов, а то что-то грустно искать методом тыка. И в твоей программе массивы разрядов, что куда идет?
Ок! Но это на досуге. Просидел часа полтора, тупо тыкая кнопкой изменения адреса, и записывая результат в тетрадку в линейку (в клеточку не оказалось). Для пяти левых разрядов проблем нет. С точками тоже. Там все просто. Данные для левых сегментов имеют два варианта без точки и с точкой. И если нужна точка перед этим разрядом, то данные посылаемые в ячейку памяти увеличиваем на два, и все. С первыми тремя разрядами пока не разбирался. Пока приведу в порядок бумажки, а то и забыть, что там намулевано недолго.
Вот окультурил адреса и данные по последним 5 разрядам:
А это три первых:
Вроде все решаемо, только подумать немного. По этим картинкам достаточно легко рисовать символы. Конечно памяти, которой у ардуинки и так немнрго, откусит. Но с другой стороны если дисплеи можно взять за бутылку пива, то игра стоит свеч.
А насчет первых трех разрядов, можно сказать только одно - те кто их проектировал, явно курили что-то крутое.
с первыми 3-я согласен (озвучивал ранее), особенно первые 2 - шедевр. в остальном примерно все одинаково как у меня, вот только где в данных 1 разряд (d0), т.е. ddat
d3 d2 d1 d0 =0001
первые три - напрашивается идея использовать бы "чтение-модификация-запись", но нет вывода RD. возможно он есть в одном из 2-х неиспользуемых выводах дисплея...
другой вариант - образ памяти индикатора размещать в памяти процессора, с ней манипулировать как душе угодно и все сливать в дисплей одной командой с начальным адресом "0". инкремент адреса дисплей умеет делать сам.
Он никакой роли не играет, если я посылаю в ячейку памяти "0" или "1", результат одинаков - все сегменты гаснут. То-же эффект если "2" и "3", загораются сегменты согласно картинкам. Вот пример вывода цифр .
Первый параметр - адрес ячейки, второй - данные. Третий -всегда еденица, он указывает сколько раз отослать данные (для чего-то был в исходной бибпиотеке, позже вырежу).
Правда текст для ардуино ИДЕ, но он элементарный и там все понятно. Написан тупо в лоб.
На дисплей выводит цифры 6543.2 в последние разряды. Во 2 и 3 разрядах цифры меняются от 0 до 9. В первом от 1 до 9 (ноль не реализуем), но если в цифре 1 разряда присутствует верхний правый сегмент, то он затирает нижний левый сегмент второго разряда. Это по моему непреодолимо.
но 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. */
Что-то меняется, но не врубился. Скорее всего это для дисплеев с другой организацией разрядов и сегментов.
com - это общие сегменты, объединенные в группы (у каждого индикатора по своему). т.е. можно какието группы включать/отключать.
bias регулирует степень возбуждения кристаллов, или по простому их ориентацию, для возможности использования дисплея под разыными углами обзора, в основном 30 град. покрутите биты и увидите, что контрастность изображения меняется в зависимости от угла обзора.
bias регулирует степень возбуждения кристаллов, или по простому их ориентацию, для возможности использования дисплея под разыными углами обзора, в основном 30 град. покрутите биты и увидите, что контрастность изображения меняется в зависимости от угла обзора.
Повидимому, не только. В некоторых режимах отображаются только нижние и центральные сегменты. Что-то там еще есть, но в даташите не нашел. Хотя это скорее всего влияние СОМ. Вовсяком случае даже в таком виде, нелохой дисплей и применение ему можно найти.
Если бы этот даташит был сначала, большинство вопросов - бы отпало. Расписано для школьников младших классов и на одном листе. Ну ладно, думать иногда тоже полезно. Да и язык неплохо-бы изучить, но наверное уже не суждено.
svm, имеется такой же дисплей, у вас остались наработки по данному дисплею для ардуино?
Есть несколько наработок для дисплеев от ККМ : Штриховские, для старых и новых Элвесов и ЭКРок. Посмотрю уточню. Правда написаны достаточно грубо, т.к. писал для того чтобы разобраться с их работой. Но в принципе работать можно (правда без изысков). Думал довести до ума и потом выложить. Но если нужно могу и в таком виде. Но дорабатывать пока не собираюсь.
да было бы круто), тоже есть парочка от касс, один на cd4015bcm благодаря вашему примеру завел (спасибо, кстати очень помогли), а вот этот не понимаю, мне бы пример как завести его, а дальше от него плясать уже можно самостоятельно тем кому это нужно
Дисплей имеет некоторую особенность, если долго не обновлять информацию, то символы плавно исчезают. Чтобы этого не было в строках 64,65 меняется полярность на сегментах. В спец. микросхемах это происходит на аппаратном уровне. А здесь приходится программно.
Следующий тоже от "Элвес Микро", но более современный на 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
касательно этого примера работает, единственно не включает подсветку по краем дисплея (на мультиметре на контанктах А и К приходящих с нее постоянка скачет 0.1-0.2 вольт, перевел в перенку показывает 2.0 вольта), если подать вручную на A = 5+v и на K = GND то подсвечивает желтым, в принципе это уже не большая проблема ведь можно просто отдельным логическим пином включать (но тут вопрос в том какое же напряжение ей нужно, вдруг ниже 5V, хотя уже при 3.3V она не горит), спасибо вам большое за информацию
касательно этого примера работает, единственно не включает подсветку по краем дисплея (на мультиметре на контанктах А и К приходящих с нее постоянка скачет 0.1-0.2 вольт, перевел в перенку показывает 2.0 вольта), если подать вручную на A = 5+v и на K = GND то подсвечивает желтым, в принципе это уже не большая проблема ведь можно просто отдельным логическим пином включать (но тут вопрос в том какое же напряжение ей нужно, вдруг ниже 5V, хотя уже при 3.3V она не горит), спасибо вам большое за информацию
Нашел проблему, как оказалось я не подал на 8 пин 5v а ведь указано в описании, хорошо что я не стал использовать схему с подачей 5v т.к. еще по памяти помню что они должны гореть зеленым, а желтый это уже явный перебор, теперь все работает)
В принципе, дисплеи неплохие и в некоторых конструкциях смотрятся вполне гармонично. Еще один их плюс - это доступность. Сейчас по гаражам и сараям валяются миллионы никому не нужных ККМ. И если есть знакомые предприниматели со стажем, хотя-бы лет 10, то у них точно пара-тройка найдется. Да и кроме дисплея там многое, что можно использовать. БП, клавиатура, часы реального времени, драйвера шаговиков, а в более древних моделях и сами шаговики, пищалки ну и мелочевка разная. Ну а если отойти от Ардуино, то и прцессор можно использовать. Кстати в ЭКЛЗ стоит процессор на порядок мощнее любой из ардуинок.
В принципе, дисплеи неплохие и в некоторых конструкциях смотрятся вполне гармонично. Еще один их плюс - это доступность. Сейчас по гаражам и сараям валяются миллионы никому не нужных ККМ. И если есть знакомые предприниматели со стажем, хотя-бы лет 10, то у них точно пара-тройка найдется. Да и кроме дисплея там многое, что можно использовать. БП, клавиатура, часы реального времени, драйвера шаговиков, а в более древних моделях и сами шаговики, пищалки ну и мелочевка разная. Ну а если отойти от Ардуино, то и прцессор можно использовать. Кстати в ЭКЛЗ стоит процессор на порядок мощнее любой из ардуинок.
Привет. Еще один дисплей попался fm16032. Помимо стандартного подключения можно подключить по 2-м проводам. Могу выложить (опять же для LPC) - разместите в своей копилке.
отлично, что взялись. не беда - завалим железку.
Что-то пока не поддается, вроде с даташитом разобрался , но не взлетела.
Напмсал отдельно три команды инициализацию и включение звука. Запустил их по кругу, чтобы посмотреть что отправляется от МК к дисплею. Пришлось из DS138 сделать псевдо трехканальный осциллограф, чтобы совместить три осциллограммы. Благо сигнал цифровой и можно обойтись 4 резисторами. Но просмотр картинки ничего не дал, вроде все логично и даташиту не противоречит. Есть несколько вариантов:
1. Не хватает команд для инициализации
2. Не те тайминги
3. Что-то не догоняю, и посылаю не то
Вот фото с экрана осциллографа, и немного дополнительной информации:
Вы у себя не сможете проверить минимальный набор команд для проверки?
как будто все ровно.
давайте так попробуем:
Не хочет, прбовал еще вставлять 18Н, вроде как выбор тактового генератора. У Вас в отладчике между пунктирными линиями сетки 10 мкс? А то у меня клоки по 40 мкс, может здесь собака порылась? Попробую еще библиотеку поправить.
после подачи питания есть задержка ?
Сейчас 200 мс перед инициализацией и по 10 между всеми командами. Правда в процессе перетыкания проводов случайно загорелась верхняя половина разрядов, и все. Дальше тишина. Другая модификация индикатора намного проще.
это значит тайминги надо крутить немного
пробовать чуть влево двинуть clock после смены данных
А у Вас в анализаторе, показывает реальное время? И по подключению: верхний канал идет на 3 ногу индикатора, средний на 3 и нижний на 7 ?
3 - ddat; 4 - dclk; 7 - dres. сверху вниз. время реальное
оставил только инициализацию
если все резисторы одинаковые - почему уровень на данных такой низкий относительно других.
уроните все в 0 и поставьте прямо перед /cs небольшую задержку.
если все резисторы одинаковые - почему уровень на данных такой низкий относительно других.
Резисторы специально разные, чтобы каналы по уровню отличались, а то их можно перепутать. Кроме того по самому всокому (CS) происходит синхронизация ослика.
оставил только инициализацию
и с ней заводится?
да
Какова цена деления временной шкалы? Или длительность клока. Попробую тупо подогнать под Вашу картинку.
растянул картинку.
цена = 2 us; t clk=1.4
Спасбо. Да анализатор это вещь. После часа примерной подгонки картинки с него и ослика железка завелась.
Причем оказалось ,что от длительности ничего не зависит. Начинает работать от 1 мкс и скорее всего дальше ограничено разумными пределами.
поздравляю. коллективный разум побеждает.
вот интересно как у Вас будут работать первые левые 2 разряда в совместной жизни.
Владимир, у тебя не сохранилась таблица соответствия адресов и сегментов, а то что-то грустно искать методом тыка. И в твоей программе массивы разрядов, что куда идет?
у меня это все на бумажке. там черт ногу сломит. могу скан скинуть.
адрес и данные, соответствующие сегменту в элементах массива, причем в том виде, в каком можно отправлять в дисплей.
arr1 - это правые 5 разрядов со смещением 20h
wr_Data(8, m1&0x1F, 0x200,m);
else
попробуйте это воспроизвести.
Ок! Бумажек, я сегодня много извел, и чувствую- это надолго. Попрбую пойти по Вашему пути. А то времени не хватает. Живу-то в деревне.
еще точек нет в массивах. у нижних точек : правые 5 (data,adr) 4.19d... 4.12d первые 2 = 4.0 и 4.3
Пока вопросов больше нее, буду разбираться.
http://roboforum.ru/forum1/topic3527.html
Ок! Но это на досуге. Просидел часа полтора, тупо тыкая кнопкой изменения адреса, и записывая результат в тетрадку в линейку (в клеточку не оказалось). Для пяти левых разрядов проблем нет. С точками тоже. Там все просто. Данные для левых сегментов имеют два варианта без точки и с точкой. И если нужна точка перед этим разрядом, то данные посылаемые в ячейку памяти увеличиваем на два, и все. С первыми тремя разрядами пока не разбирался. Пока приведу в порядок бумажки, а то и забыть, что там намулевано недолго.
Вот окультурил адреса и данные по последним 5 разрядам:
А это три первых:
А насчет первых трех разрядов, можно сказать только одно - те кто их проектировал, явно курили что-то крутое.
с первыми 3-я согласен (озвучивал ранее), особенно первые 2 - шедевр. в остальном примерно все одинаково как у меня, вот только где в данных 1 разряд (d0), т.е. ddat
d3 d2 d1 d0 =0001
первые три - напрашивается идея использовать бы "чтение-модификация-запись", но нет вывода RD. возможно он есть в одном из 2-х неиспользуемых выводах дисплея...
другой вариант - образ памяти индикатора размещать в памяти процессора, с ней манипулировать как душе угодно и все сливать в дисплей одной командой с начальным адресом "0". инкремент адреса дисплей умеет делать сам.
Он никакой роли не играет, если я посылаю в ячейку памяти "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 разряда присутствует верхний правый сегмент, то он затирает нижний левый сегмент второго разряда. Это по моему непреодолимо.
" но если в цифре 1 разряда присутствует верхний правый сегмент, то он затирает нижний левый сегмент второго разряда. Это по моему непреодолимо."
- у меня также. значит все верно. я думал где ошибся.
но 2-й и 3-й разряды можно использовать с индивидуальной адресацией
но 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. */Что-то меняется, но не врубился. Скорее всего это для дисплеев с другой организацией разрядов и сегментов.
com - это общие сегменты, объединенные в группы (у каждого индикатора по своему). т.е. можно какието группы включать/отключать.
bias регулирует степень возбуждения кристаллов, или по простому их ориентацию, для возможности использования дисплея под разыными углами обзора, в основном 30 град. покрутите биты и увидите, что контрастность изображения меняется в зависимости от угла обзора.
bias регулирует степень возбуждения кристаллов, или по простому их ориентацию, для возможности использования дисплея под разыными углами обзора, в основном 30 град. покрутите биты и увидите, что контрастность изображения меняется в зависимости от угла обзора.
Повидимому, не только. В некоторых режимах отображаются только нижние и центральные сегменты. Что-то там еще есть, но в даташите не нашел. Хотя это скорее всего влияние СОМ. Вовсяком случае даже в таком виде, нелохой дисплей и применение ему можно найти.
вот русскоязычное описание аналогичного модуля на 1621
https://drive.google.com/open?id=125D72dwxCkgDJ4_wLUqpqscj3Y1kkB0r
вот русскоязычное описание аналогичного модуля на 1621
https://drive.google.com/open?id=125D72dwxCkgDJ4_wLUqpqscj3Y1kkB0r
Если бы этот даташит был сначала, большинство вопросов - бы отпало. Расписано для школьников младших классов и на одном листе. Ну ладно, думать иногда тоже полезно. Да и язык неплохо-бы изучить, но наверное уже не суждено.
Я думаю вопрос закрыт.
svm, имеется такой же дисплей, у вас остались наработки по данному дисплею для ардуино?
Есть несколько наработок для дисплеев от ККМ : Штриховские, для старых и новых Элвесов и ЭКРок. Посмотрю уточню. Правда написаны достаточно грубо, т.к. писал для того чтобы разобраться с их работой. Но в принципе работать можно (правда без изысков). Думал довести до ума и потом выложить. Но если нужно могу и в таком виде. Но дорабатывать пока не собираюсь.
да было бы круто), тоже есть парочка от касс, один на cd4015bcm благодаря вашему примеру завел (спасибо, кстати очень помогли), а вот этот не понимаю, мне бы пример как завести его, а дальше от него плясать уже можно самостоятельно тем кому это нужно
Сейчас пороюсь в архивах и выложу каждый дисплей отдельным постом
Для начала самый простой на 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
Дисплей имеет некоторую особенность, если долго не обновлять информацию, то символы плавно исчезают. Чтобы этого не было в строках 64,65 меняется полярность на сегментах. В спец. микросхемах это происходит на аппаратном уровне. А здесь приходится программно.
Следующий тоже от "Элвес Микро", но более современный на 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
/* Распайка индикатора 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; }Файлы библиотеки те-же
Еще один дисплей на двух КР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
Ну и тот-же вольтметр питающего напряжения:
#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; }Ну и последний из тех что нашел от ККМ ЭКР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Библиотека, кажется стандартная. Были еще какие-то варианты без библиотек, но пока не нашел. Попадутся добавлю
касательно этого примера работает, единственно не включает подсветку по краем дисплея (на мультиметре на контанктах А и К приходящих с нее постоянка скачет 0.1-0.2 вольт, перевел в перенку показывает 2.0 вольта), если подать вручную на A = 5+v и на K = GND то подсвечивает желтым, в принципе это уже не большая проблема ведь можно просто отдельным логическим пином включать (но тут вопрос в том какое же напряжение ей нужно, вдруг ниже 5V, хотя уже при 3.3V она не горит), спасибо вам большое за информацию
касательно этого примера работает, единственно не включает подсветку по краем дисплея (на мультиметре на контанктах А и К приходящих с нее постоянка скачет 0.1-0.2 вольт, перевел в перенку показывает 2.0 вольта), если подать вручную на A = 5+v и на K = GND то подсвечивает желтым, в принципе это уже не большая проблема ведь можно просто отдельным логическим пином включать (но тут вопрос в том какое же напряжение ей нужно, вдруг ниже 5V, хотя уже при 3.3V она не горит), спасибо вам большое за информацию
Нашел проблему, как оказалось я не подал на 8 пин 5v а ведь указано в описании, хорошо что я не стал использовать схему с подачей 5v т.к. еще по памяти помню что они должны гореть зеленым, а желтый это уже явный перебор, теперь все работает)
В принципе, дисплеи неплохие и в некоторых конструкциях смотрятся вполне гармонично. Еще один их плюс - это доступность. Сейчас по гаражам и сараям валяются миллионы никому не нужных ККМ. И если есть знакомые предприниматели со стажем, хотя-бы лет 10, то у них точно пара-тройка найдется. Да и кроме дисплея там многое, что можно использовать. БП, клавиатура, часы реального времени, драйвера шаговиков, а в более древних моделях и сами шаговики, пищалки ну и мелочевка разная. Ну а если отойти от Ардуино, то и прцессор можно использовать. Кстати в ЭКЛЗ стоит процессор на порядок мощнее любой из ардуинок.
svm, +100500!
svm, +100500!
Служу народу!
В принципе, дисплеи неплохие и в некоторых конструкциях смотрятся вполне гармонично. Еще один их плюс - это доступность. Сейчас по гаражам и сараям валяются миллионы никому не нужных ККМ. И если есть знакомые предприниматели со стажем, хотя-бы лет 10, то у них точно пара-тройка найдется. Да и кроме дисплея там многое, что можно использовать. БП, клавиатура, часы реального времени, драйвера шаговиков, а в более древних моделях и сами шаговики, пищалки ну и мелочевка разная. Ну а если отойти от Ардуино, то и прцессор можно использовать. Кстати в ЭКЛЗ стоит процессор на порядок мощнее любой из ардуинок.
Привет. Еще один дисплей попался fm16032. Помимо стандартного подключения можно подключить по 2-м проводам. Могу выложить (опять же для LPC) - разместите в своей копилке.
Выкладывайте, кому то пригодится.
#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 }выложил. в принципе там все понятно.
datasheet: https://www.lcd-module.de/eng/pdf/zubehoer/st7920_chinese.pdf
p.38. цепляется по 2-м проводам + земля+5v. итого четыре провода.
Добрый день.
Еще один дисплей от Меттлер Толедо нужен в копилку ? Протокол i2c.