Начальная

Windows Commander

Far
WinNavigator
Frigate
Norton Commander
WinNC
Dos Navigator
Servant Salamander
Turbo Browser

Winamp, Skins, Plugins
Необходимые Утилиты
Текстовые редакторы
Юмор

File managers and best utilites

Управляем ЖК дисплеем HD44780 с помощью ассемблера. Hd44780 эмулятор


AVR. Учебный Курс. Библиотека для LCD на базе HD44780

Сел я и дописал свою библиотеку для LCD на базе HD44780.

Как она работает я тут расписывать не буду — код весьма плотно фарширован комментариями. Тем более я уже рассказывал как работать с этим дисплеем Поэтому, думаю, разберетесь. Если будут вопросы, то обращайтесь. Тут же я расскажу как ей пользоваться.

СоставБиблиотека состоит из двух файлов LCD.asm и LCD_macro.inc для подключения по 8ми битной шине и LCD4.asm и LCD4_macro.inc для подключения по четырех битной шине данных. Используете тот вариант, по которому у вас подключен дисплей.

  • Файл LCD.asm содержит все основные настройки портов и, собственно, код.
  • LCD_macro.inc содержит макросы для работы с дисплеем. И используется для работы с библиотекой.
Подключение LCD к микроконтроллеру. Порт данных использует биты 7…4 любого порта на 4 битном подключении, или весь порт целиком на 8ми разрядном Порт управления использует 3 любых бита любого порта. Главное, чтобы они были на одном порту. Впрочем код можно и чуток подправить :)

Подключение библиотеки в код.Где нибудь в начале программы, там где обычно определяют макросы, добавляете строчку

1 .include "LCD4_macro.inc"

.include "LCD4_macro.inc"

А в конце кода, там где все процедуры, добавляете

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

НастройкаВ файле LCD.asm есть раздел LCD_Define

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ;=========== LCD Define ==================================== .equ DATA_PORT = PORTB ; LCD Порт данных .equ DATA_PIN = PINB .equ DATA_DDR = DDRB   .equ CMD_PORT = PORTA ; LCD Порт управления .equ CMD_PIN = PINA .equ CMD_DDR = DDRA   .equ E = 0 ; Бит строба .equ RW = 1 ; Бит чтения/записи .equ RS = 2 ; Бит команда/Данные   .equ SPEED = 14 ; 14 для XTAL=16MHz, 10 для XTAL=8MHz, ; 6 для XTAL=4MHz, 5 для XTAL<4MHz

;=========== LCD Define ==================================== .equ DATA_PORT = PORTB ; LCD Порт данных .equ DATA_PIN = PINB .equ DATA_DDR = DDRB .equ CMD_PORT = PORTA ; LCD Порт управления .equ CMD_PIN = PINA .equ CMD_DDR = DDRA .equ E = 0 ; Бит строба .equ RW = 1 ; Бит чтения/записи .equ RS = 2 ; Бит команда/Данные .equ SPEED = 14 ; 14 для XTAL=16MHz, 10 для XTAL=8MHz, ; 6 для XTAL=4MHz, 5 для XTAL<4MHz

Порт данных и порт управления указывай те, которые у тебя используются. У меня вот это В и А. Также не забудь указать к каким битам подключены линии управления.Параметр SPEED задается в зависимости от скорости кристалла. Больше можно, меньше нет. Можно поставить 14 и не парится. Но некрасиво :)

В файле LCD_macro.inc нужно найти блок настроек дисплея и выставить там нужные биты. Выглядит это так:

1 2 3 4 5 6 7 8 9 10 11 12 13 .MACRO INIT_LCD ; Инициализация LCD RCALL InitHW ; Настроить контрольный порт RCALL LCD_DELAY ; Подождать WR_CMD (1<<LCD_F)|(0<<LCD_F_8B) ; Выдать функцию смены разрядности. WR_CMD (1<<LCD_F)|(0<<LCD_F_8B)|(1<<LCD_F_2L) ; Дважды.   ; Так как по дефолту шина 8 бит и нельзя передать сразу вторую половину байта.   WR_CMD (1<<LCD_CLR) ;0x01 WR_CMD (1<<LCD_ENTRY_MODE)|(1<<LCD_ENTRY_INC) ;0x06 WR_CMD (1<<LCD_ON)|(1<<LCD_ON_DISPLAY)|(0<<LCD_ON_CURSOR)|(0<<LCD_ON_BLINK) ;0x0C WR_CMD (1<<LCD_HOME) .ENDM

.MACRO INIT_LCD ; Инициализация LCD RCALL InitHW ; Настроить контрольный порт RCALL LCD_DELAY ; Подождать WR_CMD (1<<LCD_F)|(0<<LCD_F_8B) ; Выдать функцию смены разрядности. WR_CMD (1<<LCD_F)|(0<<LCD_F_8B)|(1<<LCD_F_2L) ; Дважды. ; Так как по дефолту шина 8 бит и нельзя передать сразу вторую половину байта. WR_CMD (1<<LCD_CLR) ;0x01 WR_CMD (1<<LCD_ENTRY_MODE)|(1<<LCD_ENTRY_INC) ;0x06 WR_CMD (1<<LCD_ON)|(1<<LCD_ON_DISPLAY)|(0<<LCD_ON_CURSOR)|(0<<LCD_ON_BLINK) ;0x0C WR_CMD (1<<LCD_HOME) .ENDM

Перечень опций, сгруппированных по типу приведен там чуть выше. Обращу внимание на то, что инициализация 4х разрядной шины идет ДВА РАЗА. Первый раз мы говорим контроллеру, что у нас шина 4 разрядная. Но при этом мы не можем сказать второй полубайт слова управления. Поэтому, когда контроллер перейдет на 4х разрядный режим, выдаем нашу посылку снова, на этот раз вторая тетрада нормально пройдет.

ИспользованиеПеред первым использованием надо сделать инициализацию индикатора. Делается это макросом

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

Запись байта в дисплей осуществляется макросами

Где вместо хх вписываем наш байт.

Если надо выдать на экран, что либо программно сгенеренное, в таком случае используется прямой вызов процедуры. Байт передается через регистр R17.

1 2 RCALL CMD_WR RCALL DATA_WR

RCALL CMD_WR RCALL DATA_WR

Чтение осуществляется аналогичным образом:

или

1 2 RCALL CMD_RD RCALL DATA_RD

RCALL CMD_RD RCALL DATA_RD

В данном случае макрос и процедура ничем не отличаются. Сделано просто для унификации. Считанный байт будет в регистре R17Установка координаты курсора осуществляется макросомLCD_COORD X,YГде X и Y координаты по горизонтали, и вертикали в знакоместах.

Сдвиг курсора или экрана осуществляется макросом SHIFT xx, где вместо xx подставляются нужные аргументы

1 2 3 4 SHIFT SCR_L ; сдвиг экрана влево SHIFT SCR_К ; сдвиг экрана вправо SHIFT CUR_L ; сдвиг курсора влево SHIFT CUR_R ; сдвиг курсора вправо

SHIFT SCR_L ; сдвиг экрана влево SHIFT SCR_К ; сдвиг экрана вправо SHIFT CUR_L ; сдвиг курсора влево SHIFT CUR_R ; сдвиг курсора вправо

Макрос LCDCLR делает полную очистку видеопамяти.

Макрос WR_CGADR xx позволяет установить указатель в область памяти знакогенератора, чтобы можно было записать свой символ. Если затем начать слать данные, то они будут записаны в ячейки знакогенератора.Макрос RD_CGADR xx позволяет установить указатель в область памяти знакогенератора,чтобы можно было считать байт из знакогенератора.Макрос WR_DDADR xx устанавливает указатель на видео память. С этого момента все данные попадают на экран.

Для примера попробуем создать зиг руну, ранее упомянутую в записи про описании контроллера

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 INIT_LCD ; Инициализируем   WR_CGADR 0 ; Указатель на начало знакогенератора.   WR_DATA 0b00000001 ; Запись данных нового знака WR_DATA 0b00000010 WR_DATA 0b00000100 WR_DATA 0b00011111 WR_DATA 0b00000010 WR_DATA 0b00000100 WR_DATA 0b00001000   WR_DDADR 0 ; Указатель на начало видео памяти (ячейка с координатми 0,0)   WR_DATA 0 ; У новоиспеченного символа код 0 напечатем его

INIT_LCD ; Инициализируем WR_CGADR 0 ; Указатель на начало знакогенератора. WR_DATA 0b00000001 ; Запись данных нового знака WR_DATA 0b00000010 WR_DATA 0b00000100 WR_DATA 0b00011111 WR_DATA 0b00000010 WR_DATA 0b00000100 WR_DATA 0b00001000 WR_DDADR 0 ; Указатель на начало видео памяти (ячейка с координатми 0,0) WR_DATA 0 ; У новоиспеченного символа код 0 напечатем его

Системные требования и ограниченияИспользуется система команда ATMega на некоторых ATTiny может начать ругаться. Придется править. Занимает 474 байта кода в максимальном исполнении (4 битная шина). На 8ми битной шине будет байт на 100 короче. Если выкинуть процедуру чтения, то будет еще короче.

Процедура активно использует регистр R16 и R17, поэтому их содержимое меняется непредсказуемым образом!!! Так что либо учитывайте это, либо сохраняйте заранее эти регистры.

Вот так вот, если что будет нового то выпущу версию 2. Пользуйтесь.

easyelectronics.ru

Управляем ЖК дисплеем HD44780 с помощью ассемблера / Хабр

.include <m8def.inc> #define RS 2 //RS=PD2 #define E 3 //E=PD3 .def temp = r16 rjmp reset .org 40 reset: ldi r16, HIGH(RAMEND) ;настройка стека out SPH,r16 ldi r16,LOW(RAMEND) out SPL,r16 ldi r16,0xfc ;настройка ножек PD2-PD7 на выход out ddrd,r16 ldi r16,0x00 out portd,r16 rcall LCD_init sbi portb,6 ;пишем данные rcall LCD_dat rjmp loop LCD_init: ldi temp,0x30 ;управляющее слово rcall LCD_com1 ;вызов программы ввода ldi temp,0x30 rcall LCD_com1 ldi temp,0x30 rcall LCD_com1 ldi temp,0x20 ;4 бит режим rcall LCD_com1 ldi temp,0x20 rcall LCD_com ldi temp,0x0c rcall LCD_com ldi temp,0x06 rcall LCD_com ldi temp,0x01 rcall LCD_com ret LCD_dat: ldi ZL, LOW(DB << 1) ldi ZH, HIGH(DB << 1) ldi r21,8 ;количество элементов в массиве m1: lpm temp, Z+ rcall LCD_com dec r21 cpi r21,0 brne m1 ret LCD_com: ldi r24,(0<<RS)|(1<<E) sbic portb,6 ldi r24,(1<<RS)|(1<<E) out portD,r24 mov r23,temp andi temp,0b11110000 ;вырываем старшую тетраду or temp,r24 ;суммируем с E и RS out portD,temp ldi r24,(0<<RS)|(0<<E) out portD,r24 ;выводим rcall func_delay ldi r24,(0<<RS)|(1<<E) sbic portb,6 ldi r24,(1<<RS)|(1<<E) out portD,r24 andi r23,0b00001111 ;вырываем младшую тетраду swap r23 mov temp,r23 or temp,r24 ;суммируем с E и RS out portD,temp ;выводим ldi r24,(0<<RS)|(0<<E) out portD,r24 rcall func_delay ret LCD_com1: ldi r24,(0<<RS)|(1<<E) out portD,r24 or temp,r24 out portD,temp ldi r24,(0<<RS)|(0<<E) out portD,r24 rcall func_delay ret loop: rjmp loop func_delay: ;задержка ldi r17,0x20 ldi r18,0x00 func_delay_subb: subi r18,1 sbci r17,0 brcc func_delay_subb ret DB: .db 0xA8,0x70,0x65,0xB3,0x65,0xE0,0x3A,0x29 ;массив символов

habr.com

AVR. Учебный курс. Подключение к AVR LCD дисплея HD44780

Так случилось, что прикупил я тут себе поприколу LCD дисплейчик две строки по восемь символов. Валялся он в ящике валялся, да чегото поперло меня и решил я его заюзать, попутно вкурив в его работу. О том как подключить к AVR LCD дисплей я вам сейчас и поведаю.

Для начала оговорюсь сразу, что речь тут пойдет о LCD индикаторах на контроллере HD44780, который стал промышленным стандартом де-факто на рынке цифро-буквенных дисплеев. Продается везде где только можно, стоит недорого (8х2 мне обошелся порядка 150 рублей), а также под него написана куча кода. Я же, как обычно, решил изобрести велосипед и сварганить свою собственную тру-библиотеку для работы с этим типом индикаторов. Разумеется на ассемблере, а на чем же еще? ;)

Подключение.LCD на базе HD44780 подключается к AVR микроконтроллеру напрямую к портам. Есть два способа подключения — на 8 бит и на 4 бита. В восьмибитном режиме немножко проще закидывать байты — не нужно сдвигать байт, зато в четырех битном резко нужно тратить на целых четыре ножки контроллера меньше. Есть еще одна особенность работы в 8-битном режиме — к некоторым контроллерам можно подрубить этот дисплей как внешнее ОЗУ и засылать данные простыми командами пересылки. Лично я подключил его в режиме полного порта у меня один фиг выводы уже девать некуда было, так что не жалко.
  • Выводы DB7…DB0 это шина данных/адреса.
  • E — стробирующий вход. Дрыгом напряжения на этой линии мы даем понять дисплею что нужно забирать/отдавать данные с/на шину данных.
  • RW — определяет в каком направлении у нас движутся данные. Если 1 — то на чтение из дисплея, если 0 то на запись в дисплей.
  • RS — определяет что у нас передается, команда (RS=0) или данные (RS=1). Данные будут записаны в память по текущему адресу, а команда исполнена контроллером.

Со стороны питания все еще проще:

Подключение дисплея
Видимая и скрытая область экранной памяти
Структура адресации контроллера HD44780
Формирование символа в ячейке CGRAM
  • GND — минус, он же общий.
  • Vcc — плюс питания, обычно 5V
  • V0 — вход контрастности. Сюда нужно подавать напряжение от нуля до напряжения питания, тем самым задается контрастность изображения. Можно поставить переменный резистор, включенный потенциометром и крутить в свое удовольствие. Главное поймать значение максимального контраста, но чтобы не было видно знакомест (серый ореол из квадратов вокруг символа). Если же выставить слишком малый контраст, то символы будут переключаться лениво и задумчиво. Примерно как в калькуляторе у которого сели батарейки.
  • А — это вход Анода светодиодной подсветки. Короче плюс.
  • К — соответственно Катод, он же минус. Подсветка хавает примерно 100мА и поэтому нужно выставить туда токоограничительный резистор на 100 Ом. Кстати, многие ЖК дисплеи имеют на плате пятачки для припайки резисторов. Если прозвонить, то можно убедиться в том, что эти линии ведут на входы питания LCD, поэтому, впаяв резисторы, можно не заморачиваться на запитку подстветки, она будет подключена к питанию контроллера.
Логическая структура LCD контроллера HD44780

Контроллер имеет свой блок управления, который обрабатывает команды и память. Она делится на три вида:

DDRAM — память дисплея. Все что запишется в DDRAM будет выведено на экран. То есть, например, записали мы туда код 0x31 — на экране выскочит символ «1» т.к. 0х31 это ASCII код цифры 1. Но есть тут одна особенность — DDRAM память гораздо больше чем видимая область экрана. Как правило, DDRAM содержит 80 ячеек — 40 в первой строке и 40 во второй, а на дисплей может двигаться по этой линейке как окошко на логарифмической линейке, высвечивая видимую область. То есть, например, можно засунуть в DDRAM сразу пять пунктов меню, а потом просто гонять дисплей туда сюда, показывая по одному пункту. Для перемещения дисплея есть спец команда. Также есть понятие курсора — это место в которое будет записан следующий символ, т.е. текущее значение счетчика адреса. Курсор не обязательно может быть на экране, он может располагаться и за экраном или быть отключен вовсе.

CGROM — таблица символов. Когда мы записываем в ячейку DDRAM байт, то из таблицы берется символ и рисуется на экране. CGROM нельзя изменить, поэтому важно, чтобы она имела на борту русские буквы. Если, конечно, планируется русскоязычный интерфейс.

CGRAM — тоже таблица символов, но ее мы можем менять, создавая свои символы. Адресуется она линейно, то есть вначале идет 8 байт одного символа, построчно, снизу вверх — один бит равен одной точке на экране. Потом второй символ тем же макаром. Поскольку знакоместо у нас 5 на 8 точек, то старшие три бита роли не играют. Всего в CGRAM может быть 8 символов, соответственно CGRAM имеет 64 байта памяти. Эти программируемые символы имеют коды от 0х00 до 0х07. Так что, закинув, например, в первые 8 байт CGRAM (первый символ с кодом 00) какую нибудь фигню, и записав в DDRAM нуль (код первого символа в CGRAM) мы увидим на экране нашу хрень.

Доступ к памяти.Тут все просто. Мы командой выбираем в какую именно память и начиная с какого адреса будем писать. А потом просто шлем байты. Если указано, что записываем в DDRAM то на экран (или в скрытую область) полезут символы, если в CGRAM то байты полезут уже в память знакогенератора. Главное потом не забыть переключится обратно на область DDRAM

Система команд.Система команд проста как мычание. О том, что передается команда контроллеру дисплея сообщит нога RS=0. Сама команда состоит из старшего бита, определяющего за что отвечает данная команда и битов параметров, указывающих контроллеру HD44780 как дальше жить.

Таблица команд:

DB7DB6DB5DB4DB3DB2DB1DB0Значение
00000001Очистка экрана. Счетчик адреса на 0 позицию DDRAM
0000001Адресация на DDRAM сброс сдвигов, Счетчик адреса на 0
000001I/DSНастройка сдвига экрана и курсора
00001DCBНастройка режима отображения
0001S/CR/LСдвиг курсора или экрана, в зависимости от битов
001DLNFВыбор числа линий, ширины шины и размера символа
01AGAGAGAGAGAGПереключить адресацию на SGRAM и задать адрес в SGRAM
1ADADADADADADADПереключить адресацию на DDRAM и задать адрес в DDRAM
Теперь поясню что значат отдельные биты:
  • I/D — инкремент или декремент счетчика адреса. По дефолту стоит 0 — Декремент. Т.е. каждый следующий байт будет записан в n-1 ячейку. Если поставить 1 — будет Инкремент.
  • S — сдвиг экрана, если поставить 1 то с каждым новым символом будет сдвигаться окно экрана, пока не достигнет конца DDRAM, наверное удобно будет когда выводишь на экран здоровенную строку, на все 40 символов, чтобы не убегала за экран.
  • D — включить дисплей. Если поставить туда 0 то изображение исчезнет, а мы в это время можем в видеопамяти творить всякие непотребства и они не будут мозолить глаза. А чтобы картинка появилась в эту позицию надо записать 1.
  • С — включить курсор в виде прочерка. Все просто, записали сюда 1 — включился курсор.
  • B — сделать курсор в виде мигающего черного квадрата.
  • S/C сдвиг курсора или экрана. Если стоит 0, то сдвигается курсор. Если 1, то экран. По одному разу за команду
  • R/L — определяет направление сдвига курсора и экрана. 0 — влево, 1 — вправо.
  • D/L — бит определяющий ширину шины данных. 1-8 бит, 0-4 бита
  • N — число строк. 0 — одна строка, 1 — две строки.
  • F — размер символа 0 — 5х8 точек. 1 — 5х10 точек (встречается крайне редко)
  • AG — адрес в памяти CGRAM
  • АD — адрес в памяти DDRAM

Я сам долго тупил в эту табличку, пытаясь понять, что же от меня хотят. Видимо был невыспавшийся, но и вправду, она на первый взгляд не очевидна, поэтому подкреплю все примером.

Задача:

  1. Включить дисплей.
  2. Очистить содержимое.
  3. Сдвинуть курсор на одну позицию.
  4. И записать туда «1».
Решение (последовательность команд):

Первым делом Инициализация дисплея без которой большая часть дисплеев на HD44780 просто откажется работать. Некоторые виды имеют дефолтные состояние (шина 8 бит, курсор в 0) и им только дисплей включить. Но все же ее лучше сделать, мало ли что там намудрил разработчик. Лишней не будет.

  1. 00111000 Шина 8 бит, 2 строки
  2. 00000001 Очистка экрана
  3. 00000110 Инкремент адреса. Экран не движется
  1. 00001100 Включили дисплей (D=1)
  2. 00000001 Очистили дисплей. Указатель встал на DDRAM
  3. 00010100 Сдвинули курсор (S/C=0) вправо (R/L=1)
  4. 00110001 — это мы уже записали данные (ножка RS=1) код «1» 0х31
Жирным шрифтом выделен идентификатор команды, ну а остальное по таблице увидите.

Задача: создать свой символ. С кодом 01 и вывести его на экран.Считаем, что дисплей у нас уже инициализирован и готов к приему данных.

Решение:

  1. 01001000      Выбираем в CGRAM адрес 0х08 — как раз начало второго символа (напомню, что на один символ уходит 8 байт)
  2. 00000001     Это пошли 8 байт данных. (RS=1)
  3. 00000010     Рисуем значок молнии, ну или
  4. 00000100     ССовскую Зиг руну, кому как
  5. 00001000     больше нравится.
  6. 00011111     Старшие три бита не действуют
  7. 00000010     Туда можно писать что угодно, на
  8. 00000100     результат влиять не будет.
  9. 00001000     Последний байт данных  
  10. 10000000      А это уже команда — переключение адреса на DDRAM и указатель на адрес 0000000 — первый символ в первой строке.
  11. 00000001      И снова данные (RS=1), код 01 — именно в него мы засунули нашу молнию.
Опа и он на экране!

Так, с логикой разобрались, пора вкуривать в физику протокола общения. Код я приведу несколько позже, когда вылижу свою библиотеку и заоптимизирую до состояния идеала. Пока же дам алгоритм, а его уж на любом языке программирования реализовать можно. Хоть на ассемблере, хоть на Сях, да хоть на Васике :)

Алгоритм чтения/записи в LCD контроллер HD44780Направление, а также команда/данные определяются ножками, а чтение и запись осуществляется по переходу строба (вывод Е) из 1 в 0

Инициализация портов

  1. RS, RW, E — в режим выхода.
  2. DB7..DB0 в режим входа. Впрочем, можно их не трогать, дальше переопределим.
Ожидание готовности, чтение флага занятости.
  1. Порт данных на вход с подтяжкой (DDR=0, PORT=1)
  2. RS=0 (команда)
  3. RW=1 (чтение)
  4. E=1 (Готовьсь!!!)
  5. Пауза (14 тактов процессора на 8МГЦ хватало)
  6. Е=0 (Пли!)
  7. Читаем из порта. Если бит 7 (Busy flag) установлен, то повторяем все заново, пока не сбросится.
Запись команды
  1. Ожидание готовности
  2. RS=0 (команда)
  3. RW=0 (запись)
  4. Е=1 (Готовьсь!!!)
  5. Порт на выход
  6. Вывести в порт код команды
  7. Пауза
  8. Е=0 (Пли!)
  9. Орудие на плечо Порт на вход, на всякий случай.
Запись Данных
  1. Ожидание готовности
  2. RS=1 (Данные)
  3. RW=0 (запись)
  4. Е=1 (Готовьсь!!!)
  5. Порт на выход
  6. Вывести в порт код команды
  7. Пауза
  8. Е=0 (Пли!)
  9. Порт на вход, на всякий случай.
Чтение команды
  1. Ожидание готовности
  2. Порт данных на вход с подтяжкой (DDR=0, PORT=1)
  3. RS=0 (команда)
  4. RW=1 (чтение)
  5. Е = 1 (Готовьсь! В этот момент данные из LCD вылазят на шину)
  6. Пауза
  7. Считываем данные с порта
  8. E=0 (Ать!)
Чтение Данных
  1. Ожидание готовности
  2. Порт данных на вход с подтяжкой (DDR=0, PORT=1)
  3. RS=1 (Данные)
  4. RW=1 (чтение)
  5. Е = 1 (Готовьсь! В этот момент данные из LCD вылазят на шину)
  6. Пауза
  7. Считываем данные с порта
  8. E=0 (Ать!)

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

Запись:

  1. E=1
  2. Пауза
  3. Выставили в порт старшую тетраду
  4. E=0
  5. Пауза
  6. Е=1
  7. Пауза
  8. Выставили в порт младшую тетраду
  9. Е=0
Чтение
  1. E=1
  2. Пауза
  3. Читаем из порта старшую тетраду
  4. Е=0
  5. Пауза
  6. Е=1
  7. Пауза
  8. Читаем из порта младшую тетраду
  9. Е=0

Ждите код :) Скоро будет :)UPD:А вот и код!

easyelectronics.ru

» Работаем с LCD дисплеем на основе микроконтроллера — HD44780 (ч.1)

 

lcd_HD44780

 

ЖК дисплей на основе микроконтроллера HD44780 является наиболее часто используемым в электроники. Вы можете его встретить в кофейных автоматах, часах, копирах, принтерах, роутерах и т.п. Также данный дисплей используется в LCD шилдах для Arduino.

ЖК дисплей представляет из себя модуль, состоящий из микроконтроллера HD44780 разработанный фирмой Hitachi и непосредственно самим ЖК дисплеем. Микроконтроллер принимает команды и обрисовывает соответствующие символы на ЖК дисплее.

 

Существует огромное количество разновидностей данного ЖК модуля, он может быть 1,2, 4 –ех строчный с различным числом символов на строке, с подсветкой или без, с различным цветом подсветки и т.п. Объединяет их всех наличие микроконтроллера HD44780, зная команды которого позволит нам без проблем использовать в своих проектах ту или иную модификацию. 

Предисловие

 

Для работы с дисплеями на основе HD44780 создано большое количество библиотек как на ассемблере так и на СИ, также для Arduino существует своя библиотека «LiquidCrystal».

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

 

Где взять первоисточник информации?

Если вы захотите сами разобраться как работать с LCD дисплеем на HD44780 и вникнуть глубже, то в этом вам поможет даташит на микроконтроллер HD44780, которые легко найти в интернете (но если вам лень, вы можете скачать с сайта).

 

Изучение я разобью на два этапа

1. Сначалая я приведу матчасть по работе с LCD на HD44780, этому посвящён данный пост

2. Далее, в следующем посте, я буду использовать модель дисплея LMO16L в Proteus. (LMO16L это один из типичный дисплеев на HD44780)

  • на данном этапе я отработаю протокол взаимодействия с дисплеем используя PATTERN GENERATOR.
  • после того, как отработаю протокол, я напишу прошивку для Arduino, попробую её на той же модели LMO16L и испытаю на реальном Arduino с подключенным LCD шилдом. Если дисплей будет работать также как и на модели, можно считать что мы умеем работать с ЖК дисплеем.
  • для закрепления, я напишу прошивку на ассемблере для Atmega8 и испробую её на LMO16L

 

 

В данном посте я расскажу:

P.S. разделы кликабельны, при нажатие вы спускаетесь к соответствующему разделу

 

 

Как подключить дисплей?

 

Все дисплеи на основе HD44780 имеет схожую распиновку

config_HD44780

Где

  • GND – земля (иногда пишут Vss)
  • Vcc – напряжение питания +5В (иногда пишут Vdd)
  • Vo – напряжение контрастности от 0В до +5В, данный вывод надо подключить к потенциометру, для регулировки
  • RS –вывод с помощью которого, дисплей определяет что в него поступает данные или команды
  • RW – вывод с помощью которого, дисплей определяет передавать или получать данные
  • E – линия синхронизации
  • D0 – D7 – шина команд/данных
  • LED + , LED — – выводы для питания подсветки

 

Дисплей может работать в 2-ух режимах:

  • в 8-и разрядном (т.е. когда, для обмена информацией используются контакты от D0 до D7),  данные пересылаются за один такт
  •  в 4-ех разрядном (для обмена используются только контакты D4 – D7),  в этом случае данные пересылаются за 2-а такта, сначала старшие 4-е бита, потом младшие 4-е бита.

 

Мы будем экономить выводы микроконтроллера и подключим наш дисплей для работы в 4-ех разрядном режиме.

 

circuit_HD44780

 

В качестве примера я показал подключение дисплея к ATmega8, хотя, можно использовать любой другой микроконтроллер. Выводы D4-D7, RS, E подключаются к любому цифровому порту микроконтроллера. Вывод RW мы использовать не будем, т.к. нам нет практической нужды принимать данные из ЖК (это обычная практика), наша задача — только передавать. По этому, свободные выводы RW, D0 – D3 посадим на землю.

Заметьте что Ve (управление контрастностью) подключается через реостат (можно через делитель напряжения), вполне уверен, что вы проигнорируете и подключите его или к 5В или к земле. Сразу скажу, что тогда, на экране вы ничего не увидите, т.к. при минимальной или максимальной контрастности дисплей не способен вывести что ни будь различимое.

 

 

Как происходит обмен информаций с ЖК?

 

Мы будем говорить о 4-ех разрядном режиме ЖК, поэтому для работы нам потребуется минимум 6 линий микроконтроллера.

Итак общение с ЖК происходит с помощью управляющих выводов:

RS – логическая единица ЖК принимает данные, логический ноль ЖК принимает команды;

С помощью линий данных:

D4 – D7 — разряды идут от младшего к старшему

И с помощью вывода стобирующих импульсов:

E

ЖК принимает информацию с помощью D4-D7, которая может быть данными (ASCII код выводимого символа)  если на RS логическая единица или командой (очистить экран, перенести курсор и т.п.) если на RS логический ноль. О том, какие бывают команды я расскажу позже, сейчас сконцентрируем внимание на физическом уровне взаимодействия.

Обмен информацией происходит по байтно, т.к. мы говорим 4-ех разрядном режиме, то микроконтроллер выставляет на D4-D7 логические единицы и логические нули, которые соответствуют старшему передаваемому полубайту, далее на E формируется стробирующий импульс, по заднем фронту которого ЖК считывает данные.

Далее микроконтроллер заново выставляет на D4-D7 логические единицы и логические нули, которые соответствуют младшему передаваемому полубайту и опять на E формируется стробирующий импульс, по заднем фронту которого ЖК считывает данные. После некоторой временной паузы (зависит от команды) цикл передачи байта данных или команды повторяется, ничего сложного.

time_data_HD44780

 

Если работать в 8-и разрядном режиме, то будут задействованы D0 – D7 и данные/команды будут передаваться за один такт, а не за два.

time_data_HD44780_2

 

 

Какие бывают команды?

 

Команды ЖК на HD44780 можно разделить на две группы:

  • команды настройки и записи в ЖК (9 команд)
  • команды чтения из ЖК (2-е команды)

 

Т.к. мы не будем считывать с ЖК (вывод RW посадили на ноль), то, я рассмотрю команды для настройки и записи, которые для удобства я свел в таблицу и пронумеровал, весь список вы можете посмотреть в даташите на странице 191.

table_command_HD44780

 

Каждая команда имеет свою длительность выполнения, это означает, что необходимо выдержать данный интервал времени перед подачей следующей команды или данных.

 

По порядку разберем, какая память есть в HD44780 и как работают команды…

Микроконтроллер HD44780 содержит следующую память:

  1. DDRAM;
  2. CGROM;
  3. CGRAM.

 

1.  В DDRAM памяти содержится ASCII коды символов которые в данный момент отображаются на экране, еще её называют видеопамять. Для 16-и символьных 2-ух строчных дисплеев её размер составляет 80 байт, т.е. по 40 байт на каждую строку. Каждый символ занимает 1 байт. У вас может возникнуть вопрос, почему 40 байт, ведь символов на строке 16? Дело в том, что на дисплеи отображается только часть DDRAM, с 0х80 по 0х8F включительно для 1-ой строки и с 0хС0 по 0хСF включительно для 2-ой строки, остальную часть не видно.

DDRAM_HD44780

 

Перенести черту видимости вправо или влево, можно с помощью команды №5. Для этого, нужно выставить S/C=1 и R/L в зависимости от направления, если вправо —R/L=1, если влево — R/L=0. Таким образом мы можем передвигать видимую часть по DDRAM, ширина её все равно останется равным 16-и символам для 1-й строки и 16-и символам для 2-й строки.

С помощью команды №5 передвигая видимую часть DDRAM, мы получаем эффект бегущей строки, например команда №5 была послана ЖК модулю 7 раз:

 

left_display_lcd

 

В дисплеи есть так называемый счетчик адреса или курсор, который начинает считать с 0x80 (в экране это левый верхний угол), при записи нового символа в DDRAM счетчик инкрементируется или декрементируется.

Помимо этого, с помощью команды №5 можно перемещать сам курсор, если выставить S/C=0 и R/L в зависимости от направления, если вправо —R/L=1, если влево — R/L=0.

 

Команда №1 служит для очистки памяти DDRAM, следовательно, всех текущих отображающихся символов и  установки курсора в начальное положение, т.е. в верхний левый угол дисплея.

 

Команда №2 не очищает DDRAM, а только устанавливает курсор в начальное положение, т.е. в верхний левый угол дисплея.

 

Дисплей по умолчанию не знает, в какую сторону сдвигать курсор при записи, для этого существует команда №3. Если бит ID=1, то курсор после записи символа сдвигается вправо (инкрементируется), если ID=0 (декрементируется), то влево.

Например, пусть курсор установлен в начальное положение (в левый верхний угол), то, для случая, когда ID=1 – курсор смещается при записи вправо, буква за буквой выводится слева на право (это типичный случай).

 

usual_lcd_HD44780

 

Пусть курсор также установлен в начальное положение (в левый верхний угол), но ID=0 – курсор смещается при записи влево, буква за буквой выводиться справа налево, то, мы получим следующее:

 

no_usual_lcd_HD44780

 

Первый символ ‘s’ поместился на экране, а следующие уже вышли за него. Не знаю, зачем вам может понадобиться вывод символов справа налево, но в данном случае вам нужно устанавливать курсор заранее зная количество символов или в конец строки.

Установив бит S=1 в этой-же команде, вы разрешаете сдвигать экран при записи символов. Если курсор инкрементируется (т.е. пишем слева на право), то экран будет сдвигаться влево. Если пишем справа налево, то экран будет сдвигаться вправо. Запутались? =)

Например, если мы установим курсор в правый нижний угол (команда №5), далее в команде №3 установим ID=1 (пишем слева направо) и S=1 (разрешаем сдвигать экран при записи), то при записи s-engineer.ru мы получим следующий результат.

 

no_usual_lcd_HD44780_2

 

Текст выводился слева на право (как обычно) и сдвигался влево.

 

С помощью команды №4 мы можем включать и отключать отображение DDRAM памяти на дисплеи. Установив бит D=0, дисплей прекращает отображать символы, но в памяти DDRAM они остаются, при D=1 дисплей отображает содержимое DDRAM.

 

lcd_display_off_on

 

Бит С позволяет отобразить курсор, если С=1, то курсор в виде символа “_”, если С=0 курсор не виден.

 

cursor_on_HD44780

 

Если установить бит В=1, то курсор будет мигать, если В=0 курсор не мигает.

 

gif_blink_cursor

 

Команда №6 используется при инициализации ЖК, если бит DL=1, то, дисплей использует с DB0 по DB7, а при DL=0, только 4-е вывода шины, т.е. с DB5 по DB7.

Бит N указывает сколько строк мы будем использовать (N=1 две строки, N=0 одну строку).

Разряд F позволяет указать размер шрифта, обычно используется 5х7 при F=1, но можно использовать и 5х10 при F=0 используя только одну строку (обычно, данный функционал не работает).

 

С помощью команды №8 можно указать в какую ячейку DDRAM мы будем записывать ASCII код символа. Она похожа на команду №5, т.к. в ней мы тоже управляем перемещением курсора, но только уже по адресам. Командой №8, мы можем использовать для своих нужд часть памяти DDRAM, которая не отображается на дисплеи.

 

Команда №9 переставляет собой просто данные. С её помощью производится запись ASCII кода символа в DDRAM память для его отображения на ЖК дисплеи. Для 4-ех разрядного режима, запись производится в два такта, сначала старший полубайт, потом младший полубайт.

Например, пошлем код 0x53, что соответствует знаку ‘S’.

 

one_char_HD44780

 

2. В памяти CGROM храниться «битовое изображение» выводимых символов. См. таблицу ниже

 

table_char_HD44780

 

Т.е. когда мы посылаем в DDRAM код 0x53, микроконтроллер HD44780 ищет ячейку 0x53 в CGROM и отрисовывает символ в соответствие с 1-и и 0-и данной ячейки.

(не всегда микроконтроллер содержит в CGROM кириллицу, там могут быть латинские или японские символы)

 

3. Память  CGRAM является частью CGROM. Главное её свойство заключается в том, что мы можем записывать в неё свои символы. Для этого нужно воспользоваться командой №7, в которой мы указываем адрес ячейки и далее командой №9 отправить 8 байт под ряд с «битовым изображением символа»

 

bit_image

 

Я решил создать символ состоящий из ‘s e’ по вертикали.

Далее, мы можем вывести данный символ, используя команду №9 зная его адрес ячейки.

 

new_image_HD44780

 

 

Как инициализировать дисплей на HD44780?

 

Т.к. ЖК дисплей содержит микроконтроллер, следовательно его необходимо проинициализировать, т.е. привести в рабочее состояние.

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

Я вывел для себя универсальную последовательность команд для инициализации, я проверил её на модели ЖК дисплея LM016L в Proteus и на реальном ЖК дисплеи Wh2602B (LCD шилд для Arduino).

Итак для успешной инициализации нам необходимо послать следующую последовательность команд и выдержать паузы:

(картинка кликабельна)

initsilization_HD44780

Вы могли заметить, что для первой команды 0x30 не нужно выдавать младший полубайт, это потому, что, дисплей сразу принимает данные в 8и битном режиме, а т.к. DB0-DB4 у нас посажены на ноль, мы не можем ими управлять, да это и не нужно.

 

Если кратко, то инициализация это последовательность команд

  1. Команда №6 — 0x30 – установить режим 8 бит
  2. Команда №6 — 0x28 – установить режим 4 бита
  3. Команда №4 — 0x08 – выключить дисплей
  4. Команда №1 — 0x01–  сброс дисплея
  5. Команда №3 — 0x06–  при записи, курсор сдвигать вправо
  6. Команда №4 — 0x0C – включить дисплей

Вторая, практическая часть

Вам будет интересно:

Буду признателен если вы поделитесь данным постом

s-engineer.ru

Жидкокристаллический символьный дисплей 0802 hd44780. Собираем ЛабБП часть 4

Всем привет. Продолжаем собирать ЛабБП, на этот раз обзор символьного жидкокристаллического дисплея 0802 на контроллере hd44780, на котором будет собран ампервольтметр для блока питания. Всем кому интересно добро пожаловать под Кат. Ранее я делал обзор на дисплей 1602, в комментариях были высказывания: Ого! Вот это некропост про некродисплей) Да возможно это так и есть, но мне кажется, что для самодельного ампервольтметра этого вполне достаточно. Почему самодельный ампервольтметр? Ну во первых, захотелось сделать этот девайс самостоятельно, надеюсь это веская причина? ;-) Да, китайцы продают подобные устройства. Да цена их сопоставима или даже ниже. Но… Можно купить и готовый ЛабБП… Но это же не интересно и не «наш метод» ©

И так что же представляет собой этот дисплей? Данный дисплей работает на контроллере HD44780, и полностью совместим с более распространенными LCD1602, 2002 и 2004. Как видно из названия, имеет две строки по 8 символов. Размеры платы всего 58х32 мм, тогда как у стандартного 1602 80х36 мм Размер области цифр — 28х12 мм Интерфейс, как и у всех HD44780, параллельный. 16 пинов идут в два ряда. Распиновка такая же как у 1602. Порадовало, что на плате сразу установлен ограничивающий резистор для подсветки дисплея, потому можно на пины 15 и 16 подавать напряжения 5В. Судя по информации из Интернета, с русскими буквами все ожидаемо. В дисплеях, приобретенных в Китае, их нет, а знакогенератор, увы, намертво прошит в микросхеме. Но для самодельного ампервольтметра русские буквы не нужны.

Ток потребления индикатора — 0.5мА без подсветки и 15мА с подсветкой.

Что ж, попытаемся собрать ампервольтметр. Сразу даю ссылку на сайт где описано, как собирать, есть список деталей, печатная плата и прошивка для микроконтроллера… Желающие повторить проект могут все скачать оттуда напрямую… Приведу лишь схему Все детали (микросхемы и дисплей) заказаны были из Китая… Только микросхему LM358 нужно купить не китайскую, или выпаять с какой-нибудь платы… Только тогда амперметр без нагрузки будет показывать нулевые значения. Если без нагрузки дисплей показывается какие то цифры, то меняйте LM358…

Шунт я сделал самостоятельно из трех жил нихрома. Сопротивление шунта 0.017 Ом. Для точного измерения сопротивления использовался самодельный миллиомметр. Не буду долго тянуть, вот такая получилась плата Со стороны печатных проводников Везде где только можно я впаял 6 танталовых конденсаторов 10мкФ*16В, вместо рекомендуемого автором электролита 100мкФ. Думаю емкости вполне достаточно. В сборе с дисплеем… Делаем первое включение: Вроде все нормально, но с прогревом LM358 вместо нулевых значений тока, появились некоторые значения отличные от нуля, а значит, с первого раза не повезло, нужно подбирать микросхему. А пока откалибровал вольтметр. Показывает на удивление очень точно, точнее некоторых китайских щитовых вольтметров… Результаты смотрите на серии фотографий: Остальные фото под спойлером:

Перебрал штук 15 микросхем LM358 купленных в разных магазинах, заказанных с Али… Стабильных нулевых показаний амперметра без нагрузки нет… Наконец нашел нужную микросхему на старой материнской плате. Впаял… Нулевые показания встали как «вкопанные»… Выдержал 30 минут, дрейфа нулевых показаний нет… Начинаем тестировать амперметр. К сожалению, под рукой был только блок питания с максимальным током 1.2А. Буду тестировать на нем. Выставляем максимальный ток в цепи. И подстроечным резистором подгоняем показания под условно «образцовый» амперметр. Затем уменьшаем ток до 1А Пол ампера Выставляем ток в 100мА Отключаем нагрузку

Предварительные выводы: вроде как получился неплохой приборчик… Окончательно будет понятно, когда буду измерять ток выше 3А. Если линейность во всем диапазоне измерения будет нормальная, то можно использовать данную самоделку в качестве ампервольтметра. На этом всё… Всем мира и добра…

mysku.ru

Управляем ЖК дисплеем HD44780 с помощью ассемблера

В университете на одном профильном предмете начали изучать стенд на основе микроконтроллера МК-51, дисплея HD44780, клавиатуры. Все это дело программируется через COM порт с помощью ассемблера. На тот момент я изучат микроконтроллеры семейства AVR (а именно Atmega8), поэтому появилось желание научиться инициализировать и выводить на экран какую-нибудь информацию с помощью ассемблера без применения библиотек. После продолжительных поисков нашел только то, как дисплей запрограммировать на языке C с помощью библиотек, в которых не совсем понятно, что происходит. Поэтому было принято решение написать код самому, с использованием ассемблерных команд. Дисплей 0802, две строки.Первым делом нужно было собрать устройство, на котором можно было потренироваться, но так как на тот момент у меня была платка от другой «игрушки», грех было не воспользоваться этой платой, так как обвязка МК в обоих схемах почти идентичная. Исходная схема платы ниже:

Управляем ЖК дисплеем HD44780 с помощью ассемблера

Дальше нужно было подключить дисплей, у нас даже остается 2 не задействованных вывода ( PD0, PD1). Все программируется через JTAG (X1). Соединял дисплей по этой схеме:Управляем ЖК дисплеем HD44780 с помощью ассемблераЯ решил использовать 4 битный режим передачи, как я тогда думал, что его осуществить будет легче. Схему пришлось изменить ввиду отсутствия светодиодной подсветки (нет 15 и 16 вывода на дисплее), также убрал не нужный мне светодиодный индикатор (D1, R2). Питал всю схему и дисплей от аккумулятора от сотового.

В итоге у меня получилось это:

Управляем ЖК дисплеем HD44780 с помощью ассемблера

Управляем ЖК дисплеем HD44780 с помощью ассемблера

Управляем ЖК дисплеем HD44780 с помощью ассемблераПлату изготавливал с помощью ЛУТ (лазерно утюжный метод)

Настало время программной части. Программу писал на AVRstudio

Код .include <m8def.inc> #define RS 2 //RS=PD2 #define E 3 //E=PD3 .def temp = r16 rjmp reset .org 40 reset: ldi r16, HIGH(RAMEND) ;настройка стека out SPH,r16 ldi r16,LOW(RAMEND) out SPL,r16 ldi r16,0xfc ;настройка ножек PD2-PD7 на выход out ddrd,r16 ldi r16,0x00 out portd,r16 rcall LCD_init sbi portb,6 ;пишем данные rcall LCD_dat rjmp loop LCD_init: ldi temp,0x30 ;управляющее слово rcall LCD_com1 ;вызов программы ввода ldi temp,0x30 rcall LCD_com1 ldi temp,0x30 rcall LCD_com1 ldi temp,0x20 ;4 бит режим rcall LCD_com1 ldi temp,0x20 rcall LCD_com ldi temp,0x0c rcall LCD_com ldi temp,0x06 rcall LCD_com ldi temp,0x01 rcall LCD_com ret LCD_dat: ldi ZL, LOW(DB << 1) ldi ZH, HIGH(DB << 1) ldi r21,8 ;количество элементов в массиве m1: lpm temp, Z+ rcall LCD_com dec r21 cpi r21,0 brne m1 ret LCD_com: ldi r24,(0<<RS)|(1<<E) sbic portb,6 ldi r24,(1<<RS)|(1<<E) out portD,r24 mov r23,temp andi temp,0b11110000 ;вырываем старшую тетраду or temp,r24 ;суммируем с E и RS out portD,temp ldi r24,(0<<RS)|(0<<E) out portD,r24 ;выводим rcall func_delay ldi r24,(0<<RS)|(1<<E) sbic portb,6 ldi r24,(1<<RS)|(1<<E) out portD,r24 andi r23,0b00001111 ;вырываем младшую тетраду swap r23 mov temp,r23 or temp,r24 ;суммируем с E и RS out portD,temp ;выводим ldi r24,(0<<RS)|(0<<E) out portD,r24 rcall func_delay ret LCD_com1: ldi r24,(0<<RS)|(1<<E) out portD,r24 or temp,r24 out portD,temp ldi r24,(0<<RS)|(0<<E) out portD,r24 rcall func_delay ret loop: rjmp loop func_delay: ;задержка ldi r17,0x20 ldi r18,0x00 func_delay_subb: subi r18,1 sbci r17,0 brcc func_delay_subb ret DB: .db 0xA8,0x70,0x65,0xB3,0x65,0xE0,0x3A,0x29 ;массив символов

Программу старался писать не отходя от алгоритма приведенного в даташите.Пришлось сделать разделение на подпрограммы LCD_com1 и LCD_com, так как не получалось отправлять команды настройки и коды символов через одну подпрограмму. Если нужно выводить на вторую строку тоже нужно добавить эти строки:

cbi portb,6 ;пишем команды на вторая строку, начало строки ldi temp,0xc2 rcall LCD_com sbi portb,6 ;пишем данные rcall LCD_dat

Однако, по непонятным мне причинам при выводе на экран информации в 2х строчный режим контрастность сильно снижается.

Коды символов нужно брать из таблицы и заносить в массив, не забывая про ограничение размеров экранаУправляем ЖК дисплеем HD44780 с помощью ассемблера

В дальнейшем планируется применить навыки на практике, термометр на процессоре, реобас или еще где-нибудь

Исходный код проекта:dl.dropbox.com/u/77527472/LCDasm.zipВ нем подключена кнопка на ресет, при нажатии, содержимое дисплея обновляетсяДаташит на дисплейdl.dropbox.com/u/77527472/wh2602-datasheet.pdfДаташит на микроконтроллер, там же есть система команд на негоdl.dropbox.com/u/77527472/ATmega8(L).pdf

ps: пост первый, поэтому принимаю всю критику в свою сторону, постараюсь в дальнейшем все учесть

Автор: CryENG

Источник

www.pvsm.ru

Символьный ЖКИ на базе контроллера HD44780 « схемопедия

Рис.1 ЖКИ на базе контроллера HD44780

По отношению к обыкновенным 7-сегментным, ЖКИ модули на базе контроллера HD44780 обладают на порядок большими возможностями.  Количество строк на экране у разных моделей – 1,2 или 4; число символов в строке: 8,10,16,20,24,30,32 или 40. Каждое знакоместо на дисплее представляет собой матрицу размером 5×8 точек. Индикатор может иметь светодиодную или люминесцентную подсветку практически любого цвета свечения. На рис.1 показан внешний вид модуля A162-D фирмы Ampire с разрешением 16 символов x 2 строки. Напряжение питания контроллера HD44780 5В (реже 3В). Ток потребления контроллера очень мал(100…200 мкА), чего не скажешь о светодиодной подсветке. В зависимости от производителя, его величина составляет 80…120 мА. Для работы некоторых типов ЖКИ может потребоваться дополнительный источник напряжения отрицательной полярности. Технология производства модулей подобного рода непрерывно совершенствуется, что, в целом, положительно сказывается на их размерах и электрических характеристиках.  

Рис.2 Таблица символов CGRAM

Изначально HD44780 имеет предопределенную таблицу символов, размещенную в ОЗУ знакогенератора CGRAM (Character Generator RAM). Для отображения любого из них программа микроконтроллера должна передать координаты позиции и, непосредственно за ними, сам адрес символа из CGRAM. Пример таблицы CGRAM приведен на рис.2. Заглавные и прописные буквы латинского алфавита, числовые знаки, а также большинство знаков препинания совпадают в ней с кодами ASCII. Набор символов, размещенных по адресам 0xA0…0xFF, содержит национальный алфавит (в данном случае кириллицу) того региона, где предполагается его использование. Первые 16 ячеек CGRAM имеют особое значение. При желании, в них могут быть записаны любые пользовательские символы, которых нет таблице (сразу после включения модуля в них находится случайная информация). Упростить преобразование строки, состоящей из букв русского и английского алфавитов, в набор кодов HD44780, можно с помощью утилиты "HD44780" (внешний вид на рис.3). Все, что делает эта программа – приводит в соответствие набор введенных символов с их отображением в таблице CGRAM. Результатом преобразования является набор байтов (с нулевым значением в конце), начинающихся с директивы резервирования FLASH-памяти программ .db.

Рис.3 Утилита HD44780

Нумерация и Функциональное назначение выводов ЖКИ приведены в табл.1. Кроме напряжения питания контроллера VCC, модуль имеет вход регулировки контрастности изображения V0. Питание подсветки (если таковая имеется) подается на выводы A и K.

Рис.4 Последовательность передачи данных в HD44780

а – по 8-разрядной шине команд/данных

б – по 4-разрядной шине команд/данных

HD44780 взаимодействует с AVR через 8-битную двунаправленную шину команд/данных DB7:DB0. Временная диаграмма работы шины показана на рис.4а. В момент записи информации в ЖКИ ведущий микроконтроллер выставляет на линиях DB7…DB0 8-разрядный код, после чего формирует на выводе E стробирующий импульс (активный фронт – задний). По окончанию импульса должна быть выдержана пауза до начала новой транзакции. Признаком записи команды/ данных является состояние линии RS. При RS=0 происходит запись команды, при RS=1 – данных. Когда необходимо считать данные из индикатора, то выводы порта DB7:DB0 микроконтроллера настраиваются на ввод. Затем следует импульс подтверждения на линии E и байт данных переписывается во внутренний регистр для дальнейшей обработки. Направление передачи данных определяет уровень на линии R/W (R/W =1 – чтение из индикатора, R/W =0 – запись в индикатор). В реальных приложениях, как правило, нет необходимости в чтение данных. Поэтому вывод R/W всегда соединяют с общим проводом. Схема подключения AVR к A162-D приведена на рис.5a.

Рис.5 Схема подключения символьного ЖКИ к микроконтроллеру

а – при использовании 8-разрядной шины команд/данных

б – при использовании 4-разрядной шины команд/данных

Для управления ЖКИ может быть использован также 4-проводный интерфейс (см. схему подключения на рис.5б), что позволяет сэкономить 4 линии ввода-вывода, при незначительном усложнении программы.

Табл.1. Функциональное назначение выводов символьного ЖКИ на базе D44780:

Номер вывода Название выводов Функциональное назначение
1 GND Общий вывод
2 VCC Напряжение питания
3 V0 Напряжение управления контрастностью
4 RS Выбор записи команды/данные
5 R/W Выбор направления передачи данных запись/чтение
6 E Вход тактовых импульсов
7-14 BD7-DB0 Шина данных
15 A Анод светодиодной подсветки
16 K Катод светодиодной подсветки

Табл.2а. Команды записи в HD44780:

NN Состояние линий, при R/W=0  

Команды

 

Максимальное

время

выполнения,

мкс

RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
1 0 0 0 0 0 0 0 0 1 Полная отчистка дисплея и установка курсора в нулевую позицию. 1600
2 0 0 0 0 0 0 0 1 Установка курсора в нулевую позицию. Установка дисплея в начальное положение. 1600
3 0 0 0 0 0 0 1 I/D S I/D(Increment/Decrement) – направление сдвига курсора после записи (I/D=1 – сдвиг вправо, I/D=0 – сдвиг влево). S(Shift) – разрешение сдвига дисплея вместе с курсором (S=1 – сдвиг разрешен, S=0 – сдвиг запрещен). 40
4 0 0 0 0 0 1 D С B D(Display) – включение дисплея (D=1 – дисплей включен, D=0 – дисплей отключен). C(Cursor)- видимость курсора (C=1 – видимый курсор, C=0 – погашенный курсор).  B(Blink) – мигание курсора (B=1 – курсор мигает, B=0 – курсор не мигает).  40
5 0 0 0 0 1 S/C R/L S/C(Screen/Cursor) – перемещение дисплея/курсора (S/C=1 – перемещается дисплей, S/C=0 – перемещается курсор). R/L(Right/Left)- направление перемещения дисплея/курсора (R/L=1 – перемещение вправо, R/L=0 – перемещение влево). 40
6 0 0 0 1 DL N F DL(Data Length) – разрядность шины данных (DL=1 – 8 бит, DL=0 – 4 бита). N(Number)- число строк дисплея (N=1 – 2 строки, N=0 – 1 строка). F(Font) – размер шрифта (F=1 – шрифт 5×10 точек, F=0 – шрифт 5×7 точек).  40
7 0 0 1  

ADRESS

Установка адреса CGRAM (Character Generator RAM). После команды должны следовать данные для записи/чтения в/из CGRAM. 40
8 0 1 ADRESS Установка адреса DDRAM (Display Data RAM). После команды должны следовать данные для записи/чтения в/из DDRAM.      40
9 1 DATA Запись данных в DDRAM (Display Data RAM) или CGRAM (Character Generator RAM). 40

Табл.2б. Команды чтения из HD44780:

NN Состояние линий, при R/W=1  

Команды

 

Максимальное время выполнения, мкс

RS DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
1 0 BF AC Чтение BF (Busy Flag) – флаг завершения операции (BF=1 – операция завершена, BF=0 – операция не завершена) и текущего состояния внутреннего счетчика адреса AC (Address Counter). 1
2 1 DATA Чтение данных из DDRAM (Display Data RAM) или CGRAM (Character Generator RAM). 40

В этом случае 4-разрядную шину команд/данных формируют линии DB7…DB4 (линии DB3…DB0 остаются незадействованными). Скорость записи снижается в 2 раза, но это, обычно, не вызывает ни каких проблем во время работы. Последовательность передачи данных показана на рис.4б. Команды/ данные передается за два такта. Первым следует старший полубайт, вторым – младший. Каждая тетрада, естественно, должна быть зафиксирована импульсом на линии E.

Рис.6 Адреса ячеек видеопамяти DDRAM

Контроллер HD44780 имеет буфер видеопамяти DDRAM (Display Data RAM), из которой символы переносятся на дисплей. Объем DDRAM зависит от числа строк и позиций на экране. Для индикатора с разрешением 16 символов x 2 строки он составляет 40 б на каждую строку (см.рис.6). Адреса ячеек видеопамяти первой строки 0x80…0xA8, второй 0xC0…0xE8. В текущий момент времени в окно дисплея попадают только 16 символов из DDRAM (положение окна можно изменять программно).

Управляющие команды записи сведены в табл.2а. Запись команды с кодом 0x01 приводит к полной отчистки DDRAM и установке окна дисплея и курсора в начальные позиции. Команда 0x02 заставляет проделать те же самые действия, но при этом оставляет содержимое видеопамяти неизменным. Биты команды под номером 3 задают направление смещение курсора (I/D=1 – сдвиг вправо, I/D=0 – сдвиг влево) и разрешение сдвига дисплея (S=1 – сдвиг разрешен, S=0 – сдвиг запрещен) при вводе очередного символа. Биты команды 4 отвечают за режим отображения курсора (B=1 – курсор мигает, B=0 – курсор не мигает; C=1 – видимый курсор, C=0 – погашенный курсор) и работу экрана (D=1 – дисплей включен, D=0 – дисплей отключен). Команду 5 удобно использовать для реализации бегущей строки. С ее помощью можно принудительно перемещать дисплей или курсор (S/C=1 – перемещается дисплей, S/C=0 – перемещается курсор), в произвольном направлении (R/L=1 – перемещение вправо, R/L=0 – перемещение влево). Содержимое DDRAM, в этом случае, остается неизменным. Команда 6 используется только во время начальной инициализации модуля. Она задает тип интерфейса (DL=1 – 8-проводной, DL=0 – 4-проводной), число строк дисплея (N=1 – 2 строки, N=0 – 1 строка) и размер шрифта (F=1 – шрифт 5×10 точек(не используется), F=0 – 5×7 точек).

Рис.7 Пользовательские символы в таблице CGRAM

Команды 7 и 8 предназначены для установки текущего адреса в CGRAM и DDRAM, соответственно, и могут быть использованы только совместно с командой записи данных 9 (либо с командой чтения 2, из табл.2б, о чем будет сказано ниже). После установки курсора в памяти DDRAM, команда 9 должна передавать адрес символа(0…0xFF) из таблицы CGRAM для его отображения в соответствующей позиции.

Комбинация команд 7 и 9 необходима при программирования пользовательских символов в CGRAM по адресам 0…0x0F. Для записи каждого символа потребуется 8 б памяти микроконтроллера. Полезную информацию будут нести в себе только 5 младших разрядов, соответствующих 5-ти столбцам матрицы (см. рис.7). Логической единице соответствует видимая точка на дисплее.

После установки адреса в ОЗУ знакогенератора, должен следовать 8-байтовый блок данных. Возможна запись нескольких символов подряд. Так, например, чтобы запрограммировать все 16 символов, нужно передать команду 0x40 (установить нулевой адрес в CGRAM), а за ней 16*8 = 128 б данных.

Команды чтения из индикатора приведены в табл.2б. С помощью первой команды может быть считано текущее содержимое счетчика адреса AC в DDRAM и состояние флага завершения операции BF (при BF=1 операция чтения/записи завершена). Команда 2 должна следовать после команды записи 7 или 8 из табл.2а и позволяет считать символы размещенные в CGRAM либо DDRAM.

Как уже говорилось выше, команды чтения не имеют никакой практической ценности. Интерес может представлять только флаг BF. Однако намного удобней программно формировать задержки времени, гарантирующие завершение операций чтения/записи, чем постоянно опрашивать состояние флага окончания операции. Необходимость использования линии R/W при этом также отпадает.

.def data = R16 ;регистр для передачи команд и данных .def row = R17 ;регистр с номером строки .def col = R18 ;регистр с номером позиции на индикатор .def temp = R19 ;регистр для промежуточных операций .equ DELAY = 500 ;задержка времени на частоте 1 МГЦ .equ RS = PC0 .equ EN = PC1 ldi temp,high(RAMEND) ;инициализация стека out SPH,temp ldi temp,low(RAMEND) out SPL,temp . clr temp ;обнуляем регистры PORTD, PORTC out PORTD,temp out PORTC,temp ldi temp,0b11110000;для шины 4 бита настраиваем PD7…PD4 на вывод ;ldi temp,0b11111111;для шины 8 бит настраиваем PD7…PD0 на вывод out DDRD,temp ldi temp,0b00000011 ;настраиваем линии PC1,PC0 на вывод out DDRC,temp rcall hd44780_init;инициализируем модуль перед началом работы . ldi row,1 ;выводим надпись “Hello World !” ldi col,3 ;в строку 1 начиная с позиции 3 ldi ZH,high(2*first_string) ldi ZL,low(2*first_string) rcall show_string ldi row,2 ;выводим надпись “Я люблю AVR” ldi col,4 ;в строку 2 начиная с позиции 4 ldi ZH,high(2*second_string) ldi ZL,low(2*second_string) rcall show_string . first_string: ; строка 13 символов “Hello World !” .db “Hello World !”,0 second_string: ; строка 11 символов “Я люблю AVR” .db 0x20,0xB1,0x20,0xBB,0xC6,0xB2,0xBB,0xC6 .db 0x20,0x41,0x56,0x52,0x20,0x20,0x20,0x20,0 ; Набор подпрограмм для работы с HD44780(16 символов x 2 строки) ; R16 – регистр для передачи команд и данных ; R17,R18 – счетчики циклов, регистры для задания номеров строки ; и позиции в видеопамяти индикатора ; XH:XL – используется как 2-байтовый регистр для задержки ; времени ; ZH:ZL – указатель на строку символов, хранящуюся во ; FLASH-памяти программ ; DELAY – постоянная для задержка времени (500…10000) ; Вспомогательная подпрограмма записи байта при использовании ; 4-проводного интерфейса ; В R16 в подпрограмму передается байт для записи write_byte: push R16 ;сохраняем регистр с байтом данных andi R16,0xF0 ;выделяем старший полубайт в регистре in R17,PORTD ;копируем содержимое порта во временный andi R17,0x0F ;регистр для модификации or R16,R17;оставляем неизменным состояние младших 4-х линий sbi PORTC,EN ;устанавливаем на линии EN лог.1 out PORTD,R16 ;выводим новое значение в порт ldi XH,high(DELAY) ;формируем задержку времени ldi XL,low(DELAY) rcall pause cbi PORTC,EN ;устанавливаем на линии EN лог.0 pop R16 ;восстанавливаем регистр с байтом данных swap R16;обмениваем полубайты для выделения младших 4-х бит andi R16,0xF0 ;выделяем старший полубайт в регистре in R17,PORTD ;копируем содержимое порта во временный andi R17,0x0F ;регистр для модификации or R16,R17;оставляем неизменным состояние младших 4-х линий sbi PORTC,EN ;устанавливаем на линии EN лог.1 out PORTD,R16 ;выводим новое значение в порт ldi XH,high(DELAY) ;формируем задержку времени ldi XL,low(DELAY) rcall pause cbi PORTC,EN ;устанавливаем на линии EN лог.0 ldi XH,high(DELAY) ;формируем задержку времени ldi XL,low(DELAY) rcall pause ret ; Вспомогательная подпрограмма записи байта при использовании ; 8-проводного интерфейса ; В R16 в подпрограмму передается байт для записи ;write_byte: ; sbi PORTC,EN ;устанавливаем на линии EN лог.1 ; out PORTD,R16 ;выводим байт информации в порт ; ldi XH,high(DELAY) ;формируем задержку времени ; ldi XL,low(DELAY) ; rcall pause ; cbi PORTC,EN ;устанавливаем на линии EN лог.0 ; ldi XH,high(DELAY) ;формируем задержку времени ; ldi XL,low(DELAY) ; rcall pause ; ret ; Вспомогательная подпрограмма задержки времени pause: sbiw XH:XL,1 brne pause ret ; Подпрограмма записи команды ; В R16 передается код команды перед вызовом подпрограммы. write_com: cbi PORTC,RS ;устанавливаем на линии RS лог.0 rjmp write_byte ;записываем команду ret ; Подпрограмма записи данных ; В R16 передается байт данных перед вызовом подпрограммы. write_dat: sbi PORTC,RS ;устанавливаем на линии RS лог.1 rjmp write_byte ;записываем данные ret ; Подпрограмма записи символа ; В R16 передается код символа(0…255), в R17 номер строки ; (1,2), в R18 номер символа в строке (1…40) при входе в ; подпрограмму. show_char: push R16 ;сохраняем регистр с символом subi R18,-0x7F ;если запись идет в строку 1, для получения sbrc R17,1 ;адреса в DDRAM к номеру символа в строке subi R18,-0x40 ;добавляется 0x7F, если в строку 2, mov R16,R18 ;то добавляется 0xBF rcall write_com ;задаем адрес символа в видеопамяти pop R16 ;восстанавливаем регистр с символом rcall write_dat ;записываем символ по текущему адресу ret ; Подпрограмма записи строки символов из FLASH-памяти ; В указателе Z передается адрес строки из FLASH-памяти (стока ; должна заканчиваться нулем), в R17 номер строки (1,2), в R18 ; начальный номер позиции, с которой должна начинаться строка ; (1…40) при входе в подпрограмму. show_string: lpm R16,Z+ ;загружаем код символ из строки tst R16 ;если код 0 (NUL), то строка закончена brne ss1 ret ;и выход из подпрограммы ss1: push R17 ;сохраняем регистр с номер строки push R18 ;сохраняем регистр с начальный номером позиции rcall show_char ;записываем символ pop R18;восстанавливаем регистр с начальным номером позиции pop R17 ;восстанавливаем регистр с номер строки inc R18 ;увеличиваем на 1 номер позиции rjmp show_string ; Подпрограмма инициализации hd44780_init: ldi XH,high(5*DELAY) ;формируем задержку времени ldi XL,low(5*DELAY) rcall pause ldi R16,0x33 ;записываем необходимую для инициализации rcall write_com ;холостую команду ldi XH,high(5*DELAY) ;формируем задержку времени ldi XL,low(5*DELAY) rcall pause ldi R16,0x32 ;записываем необходимую для инициализации rcall write_com ;холостую команду ldi R16,0x28 ;выбираем разрядность шины 4 бита и 2 строки ; ldi R16,0x38;выбираем разрядность шины 8 бит и 2 строки rcall write_com ;на дисплее ldi XH,high(5*DELAY) ;формируем задержку времени ldi XL,low(5*DELAY) rcall pause ldi R16,0x08 ;записываем команду выключения дисплея rcall write_com ldi R16,0x01 ;записываем команду начального сброса rcall write_com ldi XH,high(5*DELAY) ;формируем задержку времени ldi XL,low(5*DELAY) rcall pause ldi R16,0x06 ;записываем команду, задающую направление rcall write_com ;сдвига курсора вправо ldi R16,0x0C ;записываем команду включения дисплея rcall write_com ret

Набор подпрограмм для работы с символьным ЖКИ приведен выше. Подпрограммы write_com, write_dat производят запись команд и данных соответственно. Подпрограмма show_char выводит символ на экран дисплея; show_string переписывает строку, хранящуюся во FLASH-памяти программ, в DDRAM индикатора. Обе подпрограммы в качестве параметров принимаю начальные координаты записи – строку и столбец. В show_string, кроме этого необходимо передать еще и указатель на строку в регистре ZH:ZL.

Отдельно следует сказать о подпрограмме инициализации hd44780_init, которая должна быть вызвана после подачи напряжения питания на модуль. Только в ней могут возникнуть некоторые проблемы. Последовательность команд в ходе этой процедуры может иметь небольшие различия у индикаторов разных типов. Поэтому необходимо обращаться к технической документации на конкретную модель. Неправильная инициализация, обычно, приводит к полной неработоспособности исправного экземпляра.

Перейти к следующей части: Аналоговый вывод

shemopedia.ru


 

..:::Новинки:::..

Windows Commander 5.11 Свежая версия.

Новая версия
IrfanView 3.75 (рус)

Обновление текстового редактора TextEd, уже 1.75a

System mechanic 3.7f
Новая версия

Обновление плагинов для WC, смотрим :-)

Весь Winamp
Посетите новый сайт.

WinRaR 3.00
Релиз уже здесь

PowerDesk 4.0 free
Просто - напросто сильный upgrade проводника.

..:::Счетчики:::..