[AD]

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

Автор DI HALT
Опубликовано 10 Окт 2008 
Рубрики: AVR. Учебный курс
Метки: , , , ,

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

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

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

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

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

1
.include "LCD4_macro.inc"

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

1
.include "LCD4.asm"

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

Настройка
В файле 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

Порт данных и порт данных указывай те, которые у тебя используются. У меня вот это В и А. Также не забудь указать к каким битам подключены линии управления.
Параметр 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

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

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

1
	INIT_LCD

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

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

1
2
	WR_CMD xx
	WR_DATA xx

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

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

1
2
	RCALL	CMD_WR
	RCALL	DATA_WR

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

1
2
	RD_CMD
	RD_DATA

или

1
2
	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	; сдвиг курсора вправо

Макрос 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 напечатем его

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

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

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

[AD]

Комментарии

RSS feed

26 комментариев »

Comment от dlinyj
2008-10-10 17:42:29

надеюсь тебе помог тот код, что тебе кидал?

Comment от DI HALT
2008-10-10 19:28:55

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

 
 
Comment от Xok
2008-10-10 19:22:44

; Так как по дефолту шина 8 бит и нельзя передать сразу вторую половину байта. - эммм… туплю? ;-)

Comment от DI HALT
2008-10-10 19:26:56

По дефолту контроллер ждет данные по 8ми битной шине. А У нас подключено только по 4х битной, поэтому младший полубайт мы передать не сможем и контроллер захавает его нулями (т.к. выводы висят). Но старший то пройдет и переключит шину в 4бита. И следующая посылка опять выставит 4бита (чтобы не переопределять) и в догонку выставит второй полубайт.

Comment от Xok
2008-10-10 19:51:19

Ага.. точно, я туплю. =)

 
 
 
Comment от nwanomaly Subscribed to comments via email
2008-10-10 23:14:11

только что вспомнил случайно совершенно…

когда-то мне попадалася мега номер 160(?) вроде.

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

есть ли такие на самом деле или мне это померещилося?

Comment от nestandart
Comment от nwanomaly Subscribed to comments via email
2008-10-11 15:30:55

спасиб за инфу )

 
 
Comment от DI HALT
2008-10-11 03:48:40

Есть целое подсемейство AVR LCD которые содержат встроенный контроллер LCD, но не такой, а для прямого управления стекляхой.

Comment от nwanomaly Subscribed to comments via email
2008-10-11 16:43:13

если б они её сразу со “стекляхой” поставлялися (
и по общей цене, как обычные (надеюся)…

 
 
 
Comment от penzet
2008-10-12 16:50:24

Управление LCD-дисплеем HD44780 по одному проводу
Автор Noureddine Benabadji
18.03.2008 г.
LCD-дисплеи с контроллером HD44780 являются пожалуй одними из самых популярных символьных дисплеев для встраиваемых систем. Единственным их недостатком можно считать необходимость задействования для управления дисплеем шести I/O-линий микроконтроллера в 4-разрядном режиме либо одиннадцати I/O-линий в 8-разрядном режиме. Для сокращения числа управляющих линий можно использовать преобразователи последовательного кода в параллельный на основе стандартной логики. Однако, управлять HD44780-совместимыми LCD-дисплеями можно даже по одной линии. Такую функцию гораздо удобнее возложить не на микросхемы жёсткой логики, а на программируемый микроконтроллер, сократив, таким образом, стоимость и занимаемую схемой на печатной плате площадь. Этим целям в полной мере удовлетворяют микроконтроллеры Microchip серии PIC10F в миниатюрном корпусе SOT23–6.
Схемотехническое решение, показанное на рисунке, может оказаться полезным для многих встраиваемых систем с ограниченным числом выводов, потому как способно управлять HD44780-совместимыми LCD-дисплеями посредством однопроводной линии передачи данных, задействуя простой асинхронный RS232 протокол на скорости 9600baud. В схеме применён PIC10F202, но подойдёт любой микроконтроллер из этого семейства, потому что хорошо оптимизированный программный код (прошивка 1) состоит из всего лишь 256 слов. Увеличить скорость выше 9600baud не представляется возможным, так как PIC10F202 содержит внутренний RC-генератор с точностью 1%, а LCD-дисплей требует задержку длиной 1.6ms для некоторых инструкций, таких как «очистка дисплея». Программный код представлен в виде исходников с комментариями для LCD232 модуля; основная программа состоит из дисплейной заставки на 2 секунды и дальнейшего бесконечного цикла для ожидания 1 байта команды, максимум 16 байт данных и нуля ASCII. В тестовых целях сопряжения дисплея с внешней встраиваемой PIC-системой можно воспользоваться простой прошивкой на ассемблере (прошивка 2).

 
Comment от vanchester
2008-11-03 16:49:23

DI HALT, а ты в ISIS Proteus делал управление LCD? Я попробовал с теми библиотеками, которые ты сделал - не пошло. Попробовал пример из книжки на C сделать по выводу инфы на LCD, тоже безрезультатно. Использовал компоненты LM016L, LM017L. как на 4-х проводах, так и на 8.

Comment от vanchester
2008-11-21 10:57:03

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

 
 
Comment от vanchester
2008-11-21 11:35:45

DI HALT, и еще вопрос. В библиотеке LCD.asm есть команда LCD_PORT_IN. Не могу понять, откуда она взялась и как копилятор ее понимает, ведь ни функций, ни макросов, ни определений, ни меток нет с таким названием, и уж тем более в системе команд такой нету… При этой команде программа перепрыгивает на метку PortIn, но почему? Растолкуй, пожалуйста.

Comment от DI HALT
2008-12-30 23:21:16

Макрос это. Он есть в разделе LCD_macro.inc (либо в LCD4_macro.inc для четырехпроводной версии.)

 
 
Comment от VICTOR
2008-12-20 16:09:23

Уважаемый DI HALT,
помогите п-ста новичку с решением проблемы с ЖКИ.
Купил WH0802 и решил его первоначально проверить. Подсветка работает нормально, а вот с контрастностью непонятки: в какое бы положение не встал движок переменного резистора, регулирующего контрастность, “загорается” только верхний ряд. Нижний ни при каких обстоятельствах не контрастирует.

Перепробовал много кода - ничего не появляется.

Заранее благодарен.

Comment от DI HALT
2008-12-20 17:04:51

У тебя проблема не в контрасте, а в неправильной инициализации. Активен только верхний ряд, т.е. ты заинциализировал его на однорядный дисплей.

Comment от VICTOR
2008-12-21 21:13:53

Спасибо за ответ, попробую еще раз все проверить.
Однако я был уверен в том, что после отключения питания LCD, вся информация инициализации стирается в модуле. Это не так?

Comment от DI HALT
2008-12-21 21:20:48

Стирается. При каждом включении питания его надо заново инитить.

Comment от VICTOR
2008-12-21 21:34:20

ОК. То есть если я его отключил от питания и от контроллера,а потом в отключенном состоянии запитал, и у меня все равно контрастирует только один ряд - это не проблема, а проблема с инициализацией? Я справшиваю потому, что, например, завтра-послезавтра могу пойти в магазин и обменять (недавно там купил). Если же это не признак брака, а мое неумение составить программу - то, понятно, в моем распоряжении целая вечность для исправления ошибок.

Comment от DI HALT
2008-12-21 22:16:44

Это не брак. Это неправильная инициализация. Ищи ошибку в коде :)

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

Comment от VICTOR
2008-12-21 22:44:28

Нет, по 8-ми проводной.
Мне представляется, что я запутался во фьюзах (точнее я их не трогал), а кварц на плате, которая мне попалась (с контроллером) на 3,6864. Для формирования задержки я использую delay_ms(). может в этом дело? Временные периоды не соответствуют требуемым?

Comment от DI HALT
2008-12-21 23:05:51

Вполне возможно. Если фузы не трогал, то тактовая частота (у контроллеров Мега и Тини) задается по дефолту от внутренней РС цепочки и может быть от 1 до 8 мгц в зависимости от типа МК.

Можешь увеличить временные интервалы раз так в 10. Чтобы наверняка.

Comment от VICTOR
2008-12-22 15:57:33

Простите, но у меня никак не получается. Теперь я выяснил, что на выводах LCD 11,12,13,14 всегда есть +3,76В. Даже если я принудительно устанавливаю 0 на всех выводах, то именно на этих всегда 1. Остальные же четыре линии устанавливаются в соответствии с командами.

 
Comment от VICTOR
2008-12-22 16:10:18

Нашел ошибку.
У меня в контроллере был установлен бит JTAGEN=0 (а порт для LCD - PORTF), а я подумал, что 0 - это снят. А оказывается нет. Убрал его и все заработало.

Спасибо большое.

 
 
 
 
 
 
 
 
 
Comment от ymn
2009-01-18 23:04:15

а схему макетки, простите за наглость, не выложите?

 
Имя (обязательно)
E-mail (required - never shown publicly)
Если ваш комментарий содержит ссылки, то он должен будет пройти премодерацию
Ваш комментарий (уменьшить поле | увеличить поле)
Вы можете использовать <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line=""> в комментариях.
[AD]

Материалы сайта являются авторскими. Копирование и публикация материалов без активной ссылки на первоисточник запрещено.

Реклама: