ЖК-модуль HT1621, 2,4 дюйма, 6-разрядный 7-сегментный (Arduino)

ЖК-модуль с контроллером HT1621 состоит из 6-и разрядов (7 сегментов) и дополнительно содержит индикатор батареи. Управление индикатора осуществляется по шине 3-Wire.

Подключение индикатора к плате Arduino Nano достаточно простое, индикатор содержит всего 5 контактов (или 6, дополнительный контакт может быть для отдельного питания подсветки). Три контакта эта шина управления CS WR Data, а два остальных это питание GND и VCC (5 В).

Для поддержки ЖК-модуля на базе платформы Arduino имеются несколько библиотек, одна из них это библиотека HT1621. Библиотека достаточно проста в использовании, поддерживает вывод на индикатор цифр и различных символов, так же имеет отдельную функцию для управления индикатором батареи.

Ниже показан скетч с простым примером использования библиотеки:

#include <HT1621.h> // http://rcl-radio.ru/wp-content/uploads/2024/06/HT1621-2.1.2.zip
 HT1621 lcd; 

void setup(){
  lcd.begin(6, 7, 8); // (cs, wr, Data)
  lcd.backlight(); 
  lcd.clear(); 
  lcd.print("HELLO");
  delay(5000);
  lcd.setBatteryLevel(3);
  lcd.print("HT1621");
  delay(5000);
  lcd.clear();
}

void loop(){
  lcd.print(millis()/1000.0, 1); 
  delay(100); 
}

Так же библиотека содержит несколько примеров которые Вы можете использовать для Ваших проектов.

Контроллер HT1621 может применяться с различными ЖК индикаторами,  следует учитывать, что все ЖК индикаторы разные, у них может быть разное кол-во выводов, кол-во сегментов, порядковый номер сегментов, такие индикаторы могут содержать сегментные группы в виде матрицы для вывода символов или содержать определенное кол-во сегментов в группе для вывода цифр или символов (7 сегментов или 16 сегментов). Поэтому предложенная библиотека подходит только конкретно для этого ЖК-модуля. Если Вам необходимо использовать контроллер HT1621 но с другим ЖК-индикатором, то необходимо понять как работает данный контроллер хотя бы на примере выше описанного ЖК-модуля, но без применения библиотек.

Как работает ЖК-индикатор можно узнать из  http://rcl-radio.ru/?p=131856.

Описание контроллера HT1621:

  • Напряжение питания: 2.4…5.2 В
  • Встроенный 256 kHz RC генератор
  • Работа с внешним 32.768 kHz кварцем или от источника частоты 256 kHz
  • Выбор напряжения смещения (bias) 1/2 или 1/3 и выбор продолжительности работы 1/2, 1/3 или 1/4 (duty)
    • 1/2 или 1/3 bias — уровень напряжения
    • 1/2, 1/3 или 1/4 duty — кол-во COM линий
  • Внутренний формирователь основной частоты
  • Две частоты работы драйвера звонка (2kHz/4kHz)
  • Режим пониженного энергопотребления
  • Внутренний генератор и WDT
  • Вывод основной частоты или вывод переполнения WDT
  • 8 видов источников для получения основной частоты и для WDT
  • 32×4 LCD драйвер
  • Встроенная оперативная память дисплея 32х4
  • Трехпроводный, последовательный интерфейс
  • Встроенное формирование частоты возбуждение LCD
  • Программное конфигурирование
  • Два режима работы: c данными и с командами
  • Операции обращения к памяти с автоинкрементом
  • Три режима доступа к данным
  • Вывод VLCD для настройки рабочего напряжения LCD

Память контроллера содержит 32 байта по 4-е бита, что дает возможность управления 128-ю сегментами ЖК-индикатора.

Как видно на скриншоте, каждый бит отвечает за одну COM линию, а один адрес отвечает за один вывод линии сегментов. Поэтому контроллер содержит 4 вывода под COM линию и 32 вывода под линию сегментов. Дополнительно есть выводы под подключение пьезоизлучателя и подключение кварцевого резонатора, в данном ЖК-модуле кварцевый резонатор не используется, используется внутренняя тактовая частота 256 кГц.

 

В данной ЖК-модуле который содержит 6 разрядов по 7 сегментов плюс запятые и индикатор батареи, подключение индикатора к ЖК-контроллеру достаточно упорядочено, а именно на каждый разряд отводится 2 адреса памяти и используются все 4-е COM линии. Адреса 0:1 (из адресов 0:31) отвечают только за самый младший разряд индикатора, а адреса 10:11 отвечают за самый старший разряд индикатора, при этом в разрядах где-то есть запятая, а где-то вместо запятой происходит управление индикатором батареи.

Для запуска ЖК-модуля используется две основные команды, это команда конфигурации (код 100) и команда записи памяти (код 101).

Отправка кода 100

Коды конфигурации необходимы для корректного запуска контроллера, в даташите имеется подробный список необходимых команд, но для запуска данного модуля необходимо всего 4-е команды:

  • data_100(HT1621_SYS_EN); // включение внутреннего тактового генератора
  • data_100(HT1621_BIAS); // использует 1/3 bias (3 уровня напряжений) и 4-е COM линии
  • data_100(HT1621_RC256); // Внутренняя тактовая частота RC-генератора 256 кГц
  • data_100(HT1621_LCD_ON); // включаем индикатор

Функция отправки кода 100

void data_100(int data){
     digitalWrite(LCD_CS,LOW);
   for(int i = 2; i >=0; i--){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (0b100 >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     } 
   for(int i = 8; i >=0; i--){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (data >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     } 
     delayMicroseconds(10);digitalWrite(LCD_CS,HIGH);
     delayMicroseconds(10);digitalWrite(LCD_WR,LOW);
     delayMicroseconds(10);
  }

Байт отправки кода 100 содержит двоичное число 100 и 9-ь бит кода команды.

Отправка кода 101

Код команды 101 (отправка данных в память) содержит двоичное число 101, адрес памяти А5:А0 и данные COM линии D0:D3.

Функция отправки кода 101

void data_101(int addr, int data){
     digitalWrite(LCD_CS,LOW);
   for(int i = 2; i >=0; i--){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (0b101 >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     } 
   for(int i = 5; i >=0; i--){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (addr >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     } 
   for(int i = 0; i <=3; i++){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (data >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     }   
     delayMicroseconds(10);digitalWrite(LCD_CS,HIGH);
     delayMicroseconds(10);digitalWrite(LCD_WR,LOW);
  }  

Если для примера отправить две команды записи памяти:

data_101(0,0b0110);

data_101(1,0b1100);

то на индикаторе в самом младшем разряде загорится цифра 4, так как каждый бит отправляемый в память отвечает за свой сегмент индикатора.

Ниже показано распределение бит по сегментам:

data_101(0,0bABC DP);

data_101(1,0bFGED);

Как видно адрес 0 отвечает за сегменты ABC и dp, а адрес памяти 1 за сегменты FGED.

Ниже показан простой пример управления ЖК-индикатором без использования библиотек, это код поддерживает вывод цифр, добавить различные символы по примеру кода вывода цифр достаточно просто.

Основная функция для вывода цифр и символов:

 print_lcd(n, m, dp);

где:

n — это номер разряда, m — выводимая цифра или код символа(например код 11 выведет знак «-«),  dp — выводит запятую или управляет индикатором батареи.

Используя этот пример запуска ЖК-модуля на HT1621 Вы можете запустить любой другой ЖК-индикатор который использует контроллер HT1621.

#define LCD_CS    6
#define LCD_WR    7
#define LCD_DATA  8

#define HT1621_BIAS                 0x52                    // 1/3duty 4com
#define HT1621_SYS_DIS              0x00                    // Turn off the oscillator system oscillator and LCD bias generator
#define HT1621_SYS_EN               0x02                    // Turn on the system oscillator
#define HT1621_LCD_OFF              0x04                    // Turn off LCD bias
#define HT1621_LCD_ON               0x06                    // Turn on the LCE bias
#define HT1621_XTAL                 0x28                    // external clock
#define HT1621_RC256                0x30                    // internal clock


void setup() {
  pinMode(LCD_CS, OUTPUT);
  pinMode(LCD_WR, OUTPUT);
  pinMode(LCD_DATA, OUTPUT);
  digitalWrite(LCD_CS,HIGH);
  digitalWrite(LCD_WR,HIGH);
  data_100(HT1621_SYS_EN); // Turn on the system oscillator
  data_100(HT1621_BIAS);   // BIAS 13 4 public ports
  data_100(HT1621_RC256);  // Use RC_256K system clock source, on-chip RC oscillator
  data_100(HT1621_LCD_ON);
  clear_lcd();
}

void loop(){
  print_lcd(0, 6,false);
  print_lcd(1, 5,true);
  print_lcd(2, 4,false);
  print_lcd(3, 3,true);
  print_lcd(4, 2,true);
  print_lcd(5, 11,false);
  delay(500);
}

void print_lcd(byte raz, byte num, bool dp){
  switch(raz){
    case 0: raz=0;break;
    case 1: raz=2;break;
    case 2: raz=4;break;
    case 3: raz=6;break;
    case 4: raz=8;break;
    case 5: raz=10;break;
    }
  switch(num){
    case 0: data_101(raz,0b1110+dp);data_101(raz+1,0b1011);break;  // 0 
    case 1: data_101(raz,0b0110+dp);data_101(raz+1,0b0000);break;  // 1 
    case 2: data_101(raz,0b1100+dp);data_101(raz+1,0b0111);break;  // 2 
    case 3: data_101(raz,0b1110+dp);data_101(raz+1,0b0101);break;  // 3 
    case 4: data_101(raz,0b0110+dp);data_101(raz+1,0b1100);break;  // 4 
    case 5: data_101(raz,0b1010+dp);data_101(raz+1,0b1101);break;  // 5 
    case 6: data_101(raz,0b1010+dp);data_101(raz+1,0b1111);break;  // 6 
    case 7: data_101(raz,0b1110+dp);data_101(raz+1,0b0000);break;  // 7 
    case 8: data_101(raz,0b1110+dp);data_101(raz+1,0b1111);break;  // 8 
    case 9: data_101(raz,0b1110+dp);data_101(raz+1,0b1101);break;  // 9 
    case 10: data_101(raz,0);data_101(raz+1,0);break;  // пусто
    case 11: data_101(raz,0b0000);data_101(raz+1,0b0100);break;  // -
    }
  }

void clear_lcd(){for(int a=0;a<=32;a++){data_101(a,0);}}

void data_100(int data){
     digitalWrite(LCD_CS,LOW);
   for(int i = 2; i >=0; i--){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (0b100 >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     } 
   for(int i = 8; i >=0; i--){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (data >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     } 
     delayMicroseconds(10);digitalWrite(LCD_CS,HIGH);
     delayMicroseconds(10);digitalWrite(LCD_WR,LOW);
     delayMicroseconds(10);
  }

void data_101(int addr, int data){
     digitalWrite(LCD_CS,LOW);
   for(int i = 2; i >=0; i--){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (0b101 >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     } 
   for(int i = 5; i >=0; i--){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (addr >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     } 
   for(int i = 0; i <=3; i++){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (data >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     }   
     delayMicroseconds(10);digitalWrite(LCD_CS,HIGH);
     delayMicroseconds(10);digitalWrite(LCD_WR,LOW);
  }  

Практический пример использования ЖК-модуля на контроллере HT1621

Соберем для примера простые часы на базе DS3231. На дисплей будет выводится время (часы—минуты) и температура (датчик температуры встроен в DS3231). Так же часы будут иметь две кнопки коррекции времени.

Соберите схему

Скетч

#define LCD_CS    6
#define LCD_WR    7
#define LCD_DATA  8

#define HH  2
#define MM  3

#define HT1621_BIAS                 0x52                    // 1/3duty 4com
#define HT1621_SYS_DIS              0x00                    // Turn off the oscillator system oscillator and LCD bias generator
#define HT1621_SYS_EN               0x02                    // Turn on the system oscillator
#define HT1621_LCD_OFF              0x04                    // Turn off LCD bias
#define HT1621_LCD_ON               0x06                    // Turn on the LCE bias
#define HT1621_XTAL                 0x28                    // external clock
#define HT1621_RC256                0x30                    // internal clock

#include <Wire.h>
#include <DS3231.h> // http://rcl-radio.ru/wp-content/uploads/2022/10/DS3231.zip
  DS3231 clock;
  RTCDateTime DateTime;

unsigned long times;
int hour,minut,secon,temp;

void setup() {
  clock.begin();
  //clock.setDateTime(__DATE__, __TIME__); // Устанавливаем время на часах, основываясь на времени компиляции скетча
  pinMode(LCD_CS, OUTPUT);
  pinMode(LCD_WR, OUTPUT);
  pinMode(LCD_DATA, OUTPUT);
  pinMode(HH,INPUT_PULLUP);
  pinMode(MM,INPUT_PULLUP);
  digitalWrite(LCD_CS,HIGH);
  digitalWrite(LCD_WR,HIGH);
  data_100(HT1621_SYS_EN); // Turn on the system oscillator
  data_100(HT1621_BIAS);   // BIAS 13 4 public ports
  data_100(HT1621_RC256);  // Use RC_256K system clock source, on-chip RC oscillator
  data_100(HT1621_LCD_ON);
  clear_lcd();
}

void loop(){
  DateTime = clock.getDateTime();
  hour = DateTime.hour;
  minut = DateTime.minute; 
  secon = DateTime.second;

  if(digitalRead(HH)==LOW){hour++;if(hour>23){hour=0;} clock.setDateTime(2024, 2, 22, hour, minut, 0);} 
  if(digitalRead(MM)==LOW){minut++;if(minut>59){minut=0;} clock.setDateTime(2024, 2, 22, hour, minut, 0);} 

  if(secon<50){
  print_lcd(0, minut%10,false);
  print_lcd(1, minut/10%10,false);
  if(millis()-times<500){print_lcd(2, 11,false);print_lcd(3, 11,false);}
  if(millis()-times>=500){print_lcd(2, 10,false);print_lcd(3, 10,false);}
  if(millis()-times>=1000){times=millis();}
  print_lcd(4, hour%10,false);
  print_lcd(5, hour/10%10,false);
  }
  if(secon>=50){
  temp=clock.readTemperature()*10;
  
  print_lcd(5, 10,false);
  print_lcd(4, temp/100%10,false);
  print_lcd(3, temp/10%10,false);
  print_lcd(2, temp%10,true);
  print_lcd(1, 12,false);
  print_lcd(0, 13,false);
  }

  delay(200);
}

void print_lcd(byte raz, byte num, bool dp){
  switch(raz){
    case 0: raz=0;break;
    case 1: raz=2;break;
    case 2: raz=4;break;
    case 3: raz=6;break;
    case 4: raz=8;break;
    case 5: raz=10;break;
    }
  switch(num){
    case 0: data_101(raz,0b1110+dp);data_101(raz+1,0b1011);break;  // 0 
    case 1: data_101(raz,0b0110+dp);data_101(raz+1,0b0000);break;  // 1 
    case 2: data_101(raz,0b1100+dp);data_101(raz+1,0b0111);break;  // 2 
    case 3: data_101(raz,0b1110+dp);data_101(raz+1,0b0101);break;  // 3 
    case 4: data_101(raz,0b0110+dp);data_101(raz+1,0b1100);break;  // 4 
    case 5: data_101(raz,0b1010+dp);data_101(raz+1,0b1101);break;  // 5 
    case 6: data_101(raz,0b1010+dp);data_101(raz+1,0b1111);break;  // 6 
    case 7: data_101(raz,0b1110+dp);data_101(raz+1,0b0000);break;  // 7 
    case 8: data_101(raz,0b1110+dp);data_101(raz+1,0b1111);break;  // 8 
    case 9: data_101(raz,0b1110+dp);data_101(raz+1,0b1101);break;  // 9 
    case 10: data_101(raz,0);data_101(raz+1,0);break;  // пусто
    case 11: data_101(raz,0b0000);data_101(raz+1,0b0100);break;  // -
    case 12: data_101(raz,0b1100);data_101(raz+1,0b1100);break; // градус
    case 13: data_101(raz,0b1000);data_101(raz+1,0b1011);break; // C
    }
  }

void clear_lcd(){for(int a=0;a<=32;a++){data_101(a,0);}}

void data_100(int data){
     digitalWrite(LCD_CS,LOW);
   for(int i = 2; i >=0; i--){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (0b100 >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     } 
   for(int i = 8; i >=0; i--){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (data >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     } 
     delayMicroseconds(10);digitalWrite(LCD_CS,HIGH);
     delayMicroseconds(10);digitalWrite(LCD_WR,LOW);
     delayMicroseconds(10);
  }

void data_101(int addr, int data){
     digitalWrite(LCD_CS,LOW);
   for(int i = 2; i >=0; i--){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (0b101 >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     } 
   for(int i = 5; i >=0; i--){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (addr >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     } 
   for(int i = 0; i <=3; i++){
     digitalWrite(LCD_WR,LOW);delayMicroseconds(10);
     digitalWrite(LCD_DATA, (data >> i) & 1); 
     digitalWrite(LCD_WR,HIGH);delayMicroseconds(10);
     }   
     delayMicroseconds(10);digitalWrite(LCD_CS,HIGH);
     delayMicroseconds(10);digitalWrite(LCD_WR,LOW);
  }  


Дополнительные материалы:

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

Войти с помощью: