ЖК Индикатор HT1613 / HT1611 (KO-4B)


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

ЖК Индикатор HT1613 / HT1611 (KO-4B)

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

ЖК Индикатор HT1613 / HT1611 (KO-4B)

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

ЖК Индикатор HT1613 / HT1611 (KO-4B)

Пример 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


9 comments

    1. Это пример из интернета, там не было ссылки на библиотеку. Вот я когда-то мутил тест по даташиту, вроде работало. дисплей простой, разорбраться не сложно. Написано на 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)); //Дожидаемся отпускания

      }//Нажатие кнопки

      }//Конец бесконечного цикла

      }

    2. Кроме того вот здесь мой рабочий проект таймера на этом дисплее, тоже пригодится. Там все с подробными комментариями. Если есть вопросы — пишите
      https://github.com/MbsElectronics/Timer_Thermo_PIC16F628A

  1. А вы не подскажете, как правильно переписать ваш код под 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

    }

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

    пины на 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;
    }

  3. Получилось заслать данные (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);
    }

  4. Благодарю вас за описание этого ЖК дисплея и оставленный код на него, теперь смогу связать китайский аналог AL-801LCD с Arduino. Стоял такой в старом телефоне АОНе, искал в интернете инфу про AL-801LCD и нашел там ничего.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *