Жидкокристаллический индикатор HT1613 / HT1611 (КО-4В) представляет собой десятиразрядный модуль, предназначенный для использования в домашних телефонах.Индикаторный модуль состоит из ЖКИ десяти разрядного индикатора и микроконтроллера управления. Микросхема и индикатор размещены на одной плате размерами 67Ч36 мм. Видимая область индикатора 35Ч12мм. Высота символа 10 мм. Индикаторный модуль предназначен для использования в телефонных аппаратах в качестве индикатора времени и набора.

Самостоятельно, при питании от источника 1,5V индикаторный модуль может работать как электронные часы — секундомер. На рисунке приводится схема такого варианта. В режиме часов индицируются часы и минуты, при переходе на «секундомер» измеряется интервал времени от 1 секунды до 59 минут 59 сек. связь с внешним устройством происходит по простому двухпроводному последовательному интерфейсу. Дисплей может отображать 16 символов. Это десятичные цифры плюс пробел и несколько знаков.

Перевести модуль в режим индикатора можно, установив на выводе 5 логический ноль. В режиме цифрового индикатора запись данных происходит по отрицательному фронту CLK (синхроимпульсы) при установленном DI (данные). Заполнение индикатора происходит последовательно от первого знакоместа (от правого) к десятому. Для формирования цифры в одном знакоместе нужно последовательно побитно записать 4-разрядный код, начиная со старшего разряда.
Для полной очистки индикатора нужно установить логический ноль на DI и выдать 40 импульсов CLK. Для того чтобы на индикаторе постоянно индицировались данные их необходимо обновлять не реже, чем один раз в 8 секунд. Иначе индикатор автоматически переключится в режим секундомера.

Пример C кода программы для работы с этим индикатором:
Файл main.c:
——————————————
#include <AT89X52.H>
#include "HT1611.h"
unsigned char i1,a,t;
void InitSystem(void);
void DelaySec(unsigned char);
void main(void)
{
InitSystem();
while(1){
for(i1=0;i1<=0xff;i1++){
a=i1;
t=a/100;
PutCharLCD(t|0x30,3);
a-=(t*100);
t=a/10;
PutCharLCD(t|0x30,4);
a-=(t*10);
PutCharLCD(a|0x30,5);
DelaySec(1);
}
ClearLCD();
}
}
void InitSystem(void)
{
CLK=1; DTL=1;
ClearLCD();
}
//--------------------------
// Delay Sec procedure
//--------------------------
void DelaySec(unsigned char inSec)
{unsigned char de1=0xff,de2=0xff;
while(inSec--)while(de1--)while(de2--);}
File ht1611.c
——————————————
<!-- wp:prismatic/blocks {"language":"arduino"} -->
<pre class="wp-block-prismatic-blocks">
<code class="language-arduino">#include <AT89X52.H>
#include "HT1611.h"
unsigned char i1,a,t;
void InitSystem(void);
void DelaySec(unsigned char);
void main(void)
{
InitSystem();
while(1){
for(i1=0;i1<=0xff;i1++){
a=i1;
t=a/100;
PutCharLCD(t|0x30,3);
a-=(t*100);
t=a/10;
PutCharLCD(t|0x30,4);
a-=(t*10);
PutCharLCD(a|0x30,5);
DelaySec(1);
}
ClearLCD();
}
}
void InitSystem(void)
{
CLK=1; DTL=1;
ClearLCD();
}
//--------------------------
// Delay Sec procedure
//--------------------------
void DelaySec(unsigned char inSec)
{unsigned char de1=0xff,de2=0xff;
while(inSec--)while(de1--)while(de2--);}</code></pre>
<!-- /wp:prismatic/blocks -->
Посмотреть и скачать datasheet на HT1613
Где можно взять библиотеку HT1611.h , описанную в примере?
Это пример из интернета, там не было ссылки на библиотеку. Вот я когда-то мутил тест по даташиту, вроде работало. дисплей простой, разорбраться не сложно. Написано на MicroC Pro For Pic
______________
//ПРОВЕРКА ВЗАИМОДЕЙСТВИЯ КОНТРОДДЕРА С
//ЦИФРОВЫМ 10 РАЗРЯДНЫМ ДИСПЛЕЕМ HT1611
//демо плата работает. мспользуем
//Внутренний генератор на 4 мгц
//Пины RB3 и RB4 на вывод — для управления ЖКИ
//RC0 = DI — данные
//RC1 = SK — Строб
#define D_zero 10 //Цифра 0
#define D_L 13 //Символ L
#define D_RL 12 //Символ L наоборот
#define D_F 11 //F
#define D_P 14 //P
#define D_M 15 //симфол минус —
#define blank 0 //Пробел
sbit SK at RC1_bit;
sbit DI at RC0_bit;
sbit butt_mala at RB0_bit;
sbit butt_m_dir at TRISB0_bit;
char lcd_code [16] = {D_zero, 1, 2, 3, 4, 5, 6, 7, 8 ,9,D_L,D_RL,D_F,D_P,D_M,blank};
char display [10]; //МАССИВ СТРОКИ ДИСПЛЕЯ — будем выводить сразу 10 символов за цикл
unsigned int rounds; //счетчик кругов
char malas; //счетчик повторения мантры
char rescount;
//Попробуем сделать процедуру для вывода символа
//Вывод данных по даташиту
//- Изначально высокий уровень на SK (RB4);
//- Установить 3-й бит данных на линии DI (RB3);
//- Подождать > 1 мксек
//- Установить низкий уровень на SK (RB4);
//- Ждать > 2 мксек
//- Установить высокий уровень на SK (RB4);
//- Установить 2-й бит данных на линии DI (RB3);
//- Подождать > 1 мксек
//- Установить низкий уровень на SK (RB4);
//- Ждать > 2 мксек
//- Установить высокий уровень на SK (RB4);
//- Установить 1-й бит данных на линии DI (RB3);
//- Подождать > 1 мксек
//- Установить низкий уровень на SK (RB4);
//- Ждать > 2 мксек
//- Установить высокий уровень на SK (RB4);
//- Установить 0-й бит данных на линии DI (RB3);
//- Подождать > 1 мксек
//- Установить низкий уровень на SK (RB4);
//- Ждать > 2 мксек
//- Установить высокий уровень на SK (RB4);
//- Ждать > 5 мксек после чего можно вывожить след. символ
void digout(unsigned char dig){
char lcode;
//Сперва декодируем данные
lcode = lcd_code[dig];
DI = lcode.B3; //Выводим данные;
Delay_Us(10); //Ждем 2 мкс — для универсальности, вдруг быстрый проц
SK = 0; //Стробируем
Delay_Us(15);
SK = 1;
DI = lcode.B2;
Delay_Us(10);
SK = 0;
Delay_Us(15);
SK = 1;
DI = lcode.B1;
Delay_Us(10);
SK = 0;
Delay_Us(15);
SK = 1;
DI = lcode.B0;
Delay_Us(10);
SK = 0;
Delay_Us(15);
SK = 1;
Delay_Us(100);
} //digout
//————————————————————
//Подпрограмма обглвления строки. В качестае данных
//использует глобальные переменные malas и rounds
void lineout(){
char i;
char DA,DB,DC; //десятичные разряды
//дополнительные символы
display[0] = 15;//Пробел
display[4] = 14; // «-»
display[5] = 14; // «-»
display[9] = 15;//Пробел
//теперь цифры — круги
//с младшего разряда к старшему
DC = rounds % 10;
DB = rounds — DC;
DA = DB / 100;
DB = DB / 10;
DB = DB % 10;
//Запоминаем
display[1] = DA;
display[2] = DB;
display[3] = DC;
//теперь Malas
//с младшего разряда к старшему
DC = malas % 10;
DB = malas — DC;
DA = DB / 100;
DB = DB / 10;
DB = DB % 10;
//Запоминаем
display[6] = DA;
display[7] = DB;
display[8] = DC;
//Обновляем дисплей, проталкивая строку
for (i = 0; i <= 9; i++) digout(display[i]); } void main() { //Порт со светодиодами на вывод - пригодится ANSEL = 0b00000000; //все ацп отключены ANSELH = 0b00000000; INTCON.GIE=0;//Запретить все прерывания TRISD = 00; //Порт D на вывод. На нем светодиоды вспомогат. PORTD = 0x00; butt_m_dir = 1; //порт кнопки - на ввод TRISC = 0b11111100;//С0 и С1 на вывод - управление индикатором SK = 1; DI = 1; //Задержка на инициализвцию дисплея Delay_Ms(2000); //Инициализация счетчиков и диспоея malas = 0; rounds = 0; lineout(); while (1) { //бесконечный цикл if (malas==108) { malas=0; rounds++; } if (Button(&PORTB, 0, 100, 0)) { malas++; lineout(); rescount = 0;//Обнуляем счетчик удержания кнопки do{ rescount++; if (rescount > 99) { //Прошло прибл. 5 секунд, сбрасываем все
malas = 0;
rounds = 0;
//здесь можно еще издать звук
lineout();
rescount = 0;
}
} while (Button(&PORTB, 0, 50, 0)); //Дожидаемся отпускания
}//Нажатие кнопки
}//Конец бесконечного цикла
}
Кроме того вот здесь мой рабочий проект таймера на этом дисплее, тоже пригодится. Там все с подробными комментариями. Если есть вопросы — пишите
https://github.com/MbsElectronics/Timer_Thermo_PIC16F628A
Не думал, что вы ответите, но все равно огромное спасибо))
Спасибо что зашли на мой сайт!
А вы не подскажете, как правильно переписать ваш код под ESP32 ?
(необходимо вывести на дисплей: 0123456789)
Впервые программирую, не получатся осознать даже настройку пинов. Подписался на ваш канал.
Попытался переписать ваш код и получилось следующее:
#define D_zero 10 //Цифра 0
#define D_L 13 //Символ L
#define D_RL 12 //Символ L наоборот
#define D_F 11 //F
#define D_P 14 //P
#define D_M 15 //симфол минус —
#define blank 0 //Пробел
char lcd_code [16] = {D_zero, 1, 2, 3, 4, 5, 6, 7, 8 ,9,D_L,D_RL,D_F,D_P,D_M,blank};
char display [10]; //МАССИВ СТРОКИ ДИСПЛЕЯ — будем выводить сразу 10 символов за цикл
void digout(unsigned char dig)
{
char lcode;
//Сперва декодируем данные
lcode = lcd_code[dig];
DI = lcode[0,1,2,3,4,5,6,7,8,9]; //Попытался переделать
Delay_Us(10); //Ждем 2 мкс — для универсальности, вдруг быстрый проц
SK = 0; //Стробируем
Delay_Us(15);
SK = 1;
Delay_Us(100);
for (i = 0; i <= 9; i++)
{
digout(display[i]);
}
} //digout
void app_main(void)
{
gpio_set_direction(GPIO_NUM_6, GPIO_MODE_OUTPUT); // для выхода CLK
gpio_set_direction(GPIO_NUM_8, GPIO_MODE_OUTPUT); // для выхода D1
}
Переписанный код скомпилировался и зашился, но все равно дисплей показывает билиберду
пины на ESP32
GPIO 6 — строб
GPIO 8 — данные
//ПРОВЕРКА ВЗАИМОДЕЙСТВИЯ КОНТРОДДЕРА С
//ЦИФРОВЫМ 10 РАЗРЯДНЫМ ДИСПЛЕЕМ HT1611
//демо плата работает. мспользуем
//Внутренний генератор на 4 мгц
//Пины 6 и 8 на вывод — для управления ЖКИ
//8 — данные
//6 — Строб
#include
#include «freertos/FreeRTOS.h»
#include «freertos/task.h»
#include «driver/gpio.h»
#include «sdkconfig.h»
#define D_zero 10 //Цифра 0
#define D_L 13 //Символ L
#define D_RL 12 //Символ L наоборот
#define D_F 11 //F
#define D_P 14 //P
#define D_M 15 //симфол минус —
#define blank 0 //Пробел
#define GPIO_NUM_8 8 //GPIO_NUM_6 6
#define GPIO_NUM_6 6 //GPIO_NUM_8 8
// для выхода D1
char lcd_code [16] = {D_zero, 1, 2, 3, 4, 5, 6, 7, 8 ,9,D_L,D_RL,D_F,D_P,D_M,blank};
char display [10]; //МАССИВ СТРОКИ ДИСПЛЕЯ — будем выводить сразу 10 символов за цикл
unsigned int rounds; //счетчик кругов
char malas; //счетчик повторения мантры
char rescount;
char lcode;
//Попробуем сделать процедуру для вывода символа
//Вывод данных по даташиту
//- Изначально высокий уровень на SK (RB4);
//- Установить 3-й бит данных на линии DI (RB3);
//- Подождать > 1 мксек
//- Установить низкий уровень на SK (RB4);
//- Ждать > 2 мксек
//- Установить высокий уровень на SK (RB4);
//- Установить 2-й бит данных на линии DI (RB3);
//- Подождать > 1 мксек
//- Установить низкий уровень на SK (RB4);
//- Ждать > 2 мксек
//- Установить высокий уровень на SK (RB4);
//- Установить 1-й бит данных на линии DI (RB3);
//- Подождать > 1 мксек
//- Установить низкий уровень на SK (RB4);
//- Ждать > 2 мксек
//- Установить высокий уровень на SK (RB4);
//- Установить 0-й бит данных на линии DI (RB3);
//- Подождать > 1 мксек
//- Установить низкий уровень на SK (RB4);
//- Ждать > 2 мксек
//- Установить высокий уровень на SK (RB4);
//- Ждать > 5 мксек после чего можно вывожить след. символ
void digout(unsigned char dig)
{
//char lcode;
//Сперва декодируем данные
lcode = lcd_code[dig];
lcode = GPIO_NUM_6; //Выводим данные; (поменять местами lcode и GPIO)
vTaskDelay(1000 / portTICK_PERIOD_MS); //-не родной код //Delay_Us(10); //Ждем 2 мкс — для универсальности, вдруг быстрый проц
gpio_set_level(GPIO_NUM_8, 0);//GPIO_NUM_20 = 0; //Стробируем
vTaskDelay(1500 / portTICK_PERIOD_MS); //-не родной код//Delay_Us(15);
gpio_set_level(GPIO_NUM_8, 1); //GPIO_NUM_20 = 1;
lcode = GPIO_NUM_6;
vTaskDelay(1000 / portTICK_PERIOD_MS); //-не родной код //Delay_Us(10);
gpio_set_level(GPIO_NUM_8, 0); //GPIO_NUM_20 = 0;
vTaskDelay(1500 / portTICK_PERIOD_MS); //-не родной код //Delay_Us(15);
gpio_set_level(GPIO_NUM_8, 1); //GPIO_NUM_20 = 1;
lcode = GPIO_NUM_6;
vTaskDelay(1000 / portTICK_PERIOD_MS); //-не родной код //Delay_Us(10);
gpio_set_level(GPIO_NUM_8, 0); //GPIO_NUM_20 = 0;
vTaskDelay(1500 / portTICK_PERIOD_MS); //-не родной код //Delay_Us(15);
gpio_set_level(GPIO_NUM_8, 1); //GPIO_NUM_20 = 1;
lcode = GPIO_NUM_6;
vTaskDelay(1000 / portTICK_PERIOD_MS); //-не родной код //Delay_Us(10);
gpio_set_level(GPIO_NUM_8, 0); //GPIO_NUM_20 = 0;
vTaskDelay(1500 / portTICK_PERIOD_MS); //Delay_Us(15);
gpio_set_level(GPIO_NUM_8, 1);//GPIO_NUM_20 = 1;
vTaskDelay(10000000 / portTICK_PERIOD_MS); //-не родной код //Delay_Us(100);
}
//digout
//————————————————————
//Подпрограмма обглвления строки. В качестае данных
//использует глобальные переменные malas и rounds
void lineout()
{
unsigned char i;
unsigned char DA,DB,DC; //десятичные разряды
//дополнительные символы
display[0] = 15;//Пробел
display[4] = 14; // «-»
display[5] = 14; // «-»
display[9] = 15;//Пробел
//теперь цифры — круги
//с младшего разряда к старшему
DC = rounds % 10;
DB = rounds — DC;
DA = DB / 100;
DB = DB / 10;
DB = DB % 10;
//Запоминаем
display[1] = DA;
display[2] = DB;
display[3] = DC;
//теперь Malas
//с младшего разряда к старшему
DC = malas % 10;
DB = malas — DC;
DA = DB / 100;
DB = DB / 10;
DB = DB % 10;
//Запоминаем
display[6] = DA;
display[7] = DB;
display[8] = DC;
//Обновляем дисплей, проталкивая строку
for (i = 0; i <= 9; i++)
digout(display[i]);
}
void app_main()
{
malas = 0;
rounds = 0;
gpio_pad_select_gpio(GPIO_NUM_8);
gpio_pad_select_gpio(GPIO_NUM_6);
gpio_set_direction(GPIO_NUM_8, GPIO_MODE_OUTPUT); // для выхода CLK
gpio_set_direction(GPIO_NUM_6, GPIO_MODE_OUTPUT);
lineout();
rescount = 0;
}
Получилось заслать данные (DI) через пин 13 на ESP32
Не могу настроить CLK, подскажите как?
Новый код:
#include
#include «freertos/FreeRTOS.h»
#include «freertos/task.h»
#include «driver/gpio.h»
#include «sdkconfig.h»
#define DI 13 //13 пин
void blink_task(void *pvParameter)
{
gpio_pad_select_gpio(DI);
gpio_set_direction(DI, GPIO_MODE_OUTPUT);
while(1) {
gpio_set_level(DI, 0);
vTaskDelay(1000 / portTICK_PERIOD_MS);
gpio_set_level(DI, 1);
vTaskDelay(2000 / portTICK_PERIOD_MS);
gpio_set_level(DI, 0);
vTaskDelay(1000 / portTICK_PERIOD_MS);
gpio_set_level(DI, 1);
vTaskDelay(2000 / portTICK_PERIOD_MS);
gpio_set_level(DI, 0);
vTaskDelay(1000 / portTICK_PERIOD_MS);
gpio_set_level(DI, 1);
vTaskDelay(2000 / portTICK_PERIOD_MS);
gpio_set_level(DI, 0);
vTaskDelay(1000 / portTICK_PERIOD_MS);
gpio_set_level(DI, 1);
vTaskDelay(2000 / portTICK_PERIOD_MS);
vTaskDelay(5000 / portTICK_PERIOD_MS);
}
}
void app_main()
{
xTaskCreate(&blink_task, «blink_task», 512, NULL, 5, NULL);
}