Например TDA7294

РадиоКот >Статьи >

Теги статьи: Добавить тег

ЖК дисплей на HT1621 в AVR assembler

Автор: a1000
Опубликовано 26.02.2021
Создано при помощи КотоРед.

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

Когда-то давно заказал его на али, опробовал на ардуино и положил в коробочку. А что там интересного – воткнул готовую библиотеку, загрузил пример и всё работает. Но с недавнего времени мне в голову пришла идея разобраться в премудростях программирования микроконтроллеров AVR на assembler. Победив очередной модуль, я вспомнил о вышеупомянутом дисплее. А почему бы и нет?
Сердцем модуля является HT1621 RAM Mapping 32х4 LCD Controller for I/O MCU. Из всего богатства ножек данной микросхемы пользователю модуля доступны только следующие:
CS - вход выбора микросхемы с подтягивающим резистором. Если прижать этот выход к нулю, модуль начнёт нас слушать. Если отпустить, он поднимется до логической единицы и модуль перестанет нас слушать.
WR - тактирующий сигнал для записи данных. Также имеет подтягивающий резистор.
DATA - Последовательный ввод / вывод данных с подтягивающим резистором.
Vcc и Gnd – питание модуля. По даташиту от 2,4 до 5,2 вольта.
LED+ – питание подсветки.

Сразу хочу остановиться на включении подсветки. Сзади на плате есть две точки

 

Если каплей припоя замкнуть контакты в точке 1, то положительный выход подсветки будет подключен к Vcc, и подсветка будет включаться при подаче напряжения на плату. Если замкнуть контакты в точке 2, то положительный выход подсветки будет подключен к LED+, и для включения подсветки на этот контакт надо дополнительно подать напряжение.
По остальным ножкам понятно, что в данный модуль рассчитан только на отображение посылаемых данных. Ну что ж будем разбираться.
На модуль передаются данные двух типов – команды и данные для отображения. Что мы передаём кодируется первыми тремя битами. Если посылка начинается 100 это команда, если 101 – данные.
Команды устанавливают режим работы модуля. Команда передаётся в следующем формате
100 аааааааа х
100 – режим команды
аааааааа – команда
х – любой бит, обычно 0

Для запуска дисплея ему нужно передать 4 команды

SYS EN – 0000-0001-X
RC 256K - 0001-1000-X
BIAS & COM – 0010-1001-Х
LCD ON - 0000-0011-X

Для примера, полный формат команды SYS EN будет выглядеть так

100000000010

Рассмотрим, что делает каждая команда.
SYS EN – включает системный генератор.
RC 256K – выбирает источником тактирования, встроенный RC-генератор. На данном модуле других вариантов нет.
LCD ON – включает генератор смещения ЖК-дисплея.
BIAS & COM – настраиваем два параметра. Смешение генератора для LCD и количество общих выводов дисплея. Рассмотрим данный пункт подробнее.
Команда BIAS & COM имеет следующий формат

100 0010ab0cX
100 – режим команды
c – pежим смещения генератора. При с=0 это 1/2, при с=1 – 1/3. Параметр связан с контрастностью отображаемых знаков. Подбирайте на свой вкус. У меня лучше работало при с=1.
ab – количество общих выводов дисплея. При ab=00 это 2, при ab=01 – 3, при ab=10 – 4. На модуле установлен дисплей с 4 общими выводами, по этому ab=10.

После запуска дисплея на него можно отправлять данные для отображения. Данные передаются в следующем формате

101 аааааа bbbb
101 – режим передачи данных
аааааа – адрес
bbbb – данные

Разберём, что такое адрес и где его взять. HT1621 имеет на борту RAM, завязанное на выхода. Что лежит в RAM, то и отображается на дисплее. Память адресуется по 4 бита. Каждому сегменту соответствует два адреса. Первому 000000 и 000001, второму 000010 и 000011 и т.д. Нумерация сегментов идём слева на право.

Прошу также обратить внимание, десятичная точка привязана к сегменту стоящему справа от неё. Сегменты 4, 5 и 6 не имеют десятичных точек. Биты относящиеся к точкам этих сегментов управляют указателем заряда батареи.
HT1621 умеет работать с пост-инкрементом адреса. Если адреса идут подряд, достаточно указать адрес первого пакета из 4 байт. Последующие будут записываться увеличивая адрес на единицу.

Теперь какие биты данных за что отвечают.

Предположим, что это первый сегмент. Тогда
4 байта по адресу 000000 соответствуют DP, C, B, A.
4 байта по адресу 000001 соответствуют D, E, G, F.

Что передавать понятно, теперь вопрос как? При первом взгляде на временную диаграмму всё очень похоже на SPI

Но число бит совсем не кратно 8. Аппаратный SPI использовать не получится. Придется всё делать вручную.
Приступим. Я использовал Atmega8. Подключаем модуль дисплея к порту B.
Для начала напишем подпрограмму отправки из байта фиксированного числа бит.

SendBit: ;отправка байта (Temp6 - байт, Temp5 - сколько бит)
    cbi PORTB, WR // Вывод WR на 0
    LSL Temp6 // сдвигаем Temp6
    BRCC SendNULL //смотрим что вылезло в С
    sbi PORTB, DATA // если 1 вывод DATA на +5
    rjmp Exit_Send
  SendNULL:
    cbi PORTB, DATA // если 0 вывод DATA на 0
  Exit_Send:
    sbi PORTB, WR // Вывод WR на +5
    dec Temp5 //уменьшаем счётчик бит
    tst Temp5
    BRNE SendBit //если не достигли нуля возврат в начало
    RET

 Пишем подпрограмму отправки команды. Все нужные нам команды состоят из 9 бит и начинаются на 0. Для упрощения жизни делаем следующее. Вместо идентификатора команды 100 отправляем 1000, тогда команда влазит в один байт

SendCmd: ;отправка команды (Temp6 - команда, Temp5 - сколько бит)
      PUSH Temp6 //сохраняем команду в стек
      LDI Temp6, 0x80 //идентификатор команды
      LDI Temp5, 4 //передача 4 бит из идентификатора
      cbi PORTB, CS // Вывод CS на 0
      RCALL SendBit //отправка идентификатора
      POP Temp6 //востанавливаем команду из стека
      LDI Temp5, 8 //передача 4 бит из команды
      RCALL SendBit //отправка команды
      sbi PORTB, CS // Вывод CS на +5
      RET

Пишем подпрограмму отправки данных. Данные отправляем с пост-инкрементом адреса. Следовательно, указав начальный адрес ячейки можно отправить сразу все 8 бит данных.

 

Write: ;отправка данных (Temp6 - данные, Temp7 - адрес)
     PUSH Temp6 //сохраняем данные в стек
     LSL Temp7 //сдвигаем адрес на два байта влево
     LSL Temp7
     LDI Temp6, 0xa0 //идентификатор данных   
     LDI Temp5, 3 //передача 4 бит из идентификатора
     cbi PORTB, CS // Вывод CS на 0
     RCALL SendBit // отправка идентификатора
     mov Temp6, Temp7 //копируем адрес для записи
     LDI Temp5, 6 //передача 6 бит из адреса
     RCALL SendBit // отправка адреса
     POP Temp6 //востанавливаем данные из стека
     LDI Temp5, 8 //передача 8 бит из данных
     RCALL SendBit // отправка данных
     sbi PORTB, CS // Вывод CS на +5
     RET

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

 

Init: ;инициализация дисплея
     LDI Temp6, Sys_en 
     RCALL SendCmd
     LDI Temp6, RCosc
     RCALL SendCmd
     LDI Temp6, ComMode
     RCALL SendCmd
     LDI Temp6, LCD_on
     RCALL SendCmd
     RET

Clear: ;очистка дисплея
     ldi Temp7, 10
   Povtor:
ldi Temp6, 0x00
   PUSH Temp7
   RCALL Write
   POP Temp7
   SUBI Temp7, 2
   BRCC Povtor
   RET

Ну а дальше из готовых подпрограмм собираем полную версию. 

К статье приложены даташит на HT1621 и архив с полной версией рабочей программы.

 


Файлы:
Проект
Datasheet


Все вопросы в Форум.




Как вам эта статья?

Заработало ли это устройство у вас?

12 5 4