Работа с символьным жидкокристаллическим индикатором
Методическое указание к лабораторной работе на учебном стенде LESO1.
1 Цель работы
- Изучить схему подключения жидкокристаллического индикатора (ЖКИ) к микроконтроллеру.
- Изучить особенности работы символьного ЖКИ.
- Изучить особенность параллельной синхронной передачи данных.
- Научится выводить на ЖКИ информацию.
2 Предварительная подготовка к работе
- По конспекту лекций и рекомендуемой литературе изучить принцип работы символьного жидкокристаллического индикатора.
- По конспекту лекций и рекомендуемой литературе изучить принцип работы параллельных портов ввода-вывода микроконтроллера.
- Составить алгоритм работы программы, соответственно заданию.
- Составить программу на языке программирования С.
3 Краткие теоретические сведения
3.1 Устройство и принцип работы символьного жидкокристаллического индикатора
В настоящее время в микропроцессорных системах для отображения широко используют жидкокристаллические индикаторы (ЖКИ). Условно все ЖКИ можно разделить на две категории: символьные, или знакосинтезирующие, и графические. Графические индикаторы представляют собой матрицу из m строк и n столбцов, на пересечении которых находятся пиксели. Пиксель представляет собой неделимый объект прямоугольной или круглой формы, обладающий определённым цветом; пиксель – наименьшая единица растрового изображения. Если на определенный столбец и строку подать электрический сигнал, то пиксель на их пересечении изменит свой цвет. Подавая группу сигналов на столбцы и строки можно формировать по точкам произвольное графическое изображение. Так работает графический ЖКИ. В символьном же ЖКИ матрица пикселей разбита на подматрицы, каждая подматрица предназначена для формирования одного символа: цифры, буквы или знака препинания. Как правило, для формирования одного символа используют матрицу из восьми строк и пяти столбцов. Символьные индикаторы бывают одно-, двух- и четырехстрочными.
Для упрощения взаимодействия микропроцессорной системы и ЖКИ используют специализированную микросхему – контроллер (драйвер) ЖКИ. Он управляет пикселями жидкокристаллического дисплея и интерфейсной частью индикатора. Обычно такой контроллер входит в состав индикатора. В целом жидкокристаллический индикатор представляет собой печатную плату, на которой смонтирован сам дисплей, контроллер и необходимые дополнительные электронные компоненты. Внешний вид ЖКИ показан на рисунке ниже.
В учебном стенде LESO1 использован двухстрочный восьмисимвольный ЖКИ. Структурная схема показана на рисунке 2.
В состав контроллера ЖКИ входят три вида памяти: CGROM, CGRAM, DDRAM. Когда микроконтроллер передает в контроллер ЖКИ ASCII-коды символов, то они записываются в DDRAM (Display data RAM – ОЗУ ASCII-кодов отображаемых символов), такую память называют видеопамятью или видеобуфером. Видеобуфер в символьных индикаторах обычно содержит 80 ячеек памяти – больше, чем число знакомест дисплея. У двухстрочных индикаторов ячейки с адресами от 0x00 и до 0x27 отображаются на верхней строке дисплея, а ячейки с адресами 0x40 … 0x67 – на нижней строке. Смещая видимое окно дисплея относительно DDRAM, можно отображать на дисплее различные области видеопамяти. Сдвиг окна индикатора относительно видеобуфера для верхней и нижней строк происходит синхронно, как это показано на рисунке 3. Курсор будет виден на индикаторе только в том случае, если он попал в зону видимости дисплея (и если предварительно была подана команда отображать курсор).
Матрицы начертания символов хранятся в памяти знакогенератора. Память знакогенератора включает в себя CGROM (Character generator ROM – ПЗУ знакогенератора), в которую на заводе-изготовителе загружены начертания символов таблицы ASCII. Содержимое CGROM изменить нельзя. Для того, чтобы пользователь смог самостоятельно задать начертание нужных ему символов, в знакогенераторе имеется специальное ОЗУ – CGRAM (Character generator RAM). Под ячейки CGRAM отведены первые (младшие) 16 адресов таблицы кодов.
Схема подключения ЖКИ к микроконтроллеру ADuC842 показана ниже на рисунке:
Интерфейс подключения – параллельный. Для соединения индикатора с микроконтроллером используется 11 линий — восемь для передачи данных (D0 - D7) и три линии управления. Линия RS служит для сообщения контроллеру индикатора о том, что именно передается по шине: команда или данные (RS = 1 — данные, RS = 0 — команда). По линии Е передается строб-сигнал, сопровождающий запись или чтение данных: по переходу сигнала на линии E из 1 в 0 осуществляется запись данных во входной буфер микроконтроллера индикатора. Запись информации в ЖКИ происходит по спаду этого сигнала. Потенциал на управляющем выводе R/W (Read/Write) задает направление передачи информации, при R/W = 0 осуществляется запись в память индикатора, при R/W = 1 – чтение из нее. Еще три линии предназначены для подачи питающего напряжения (VDD, GND) и напряжения смещения, которое управляет контрастностью дисплея.
Диаграммы передачи данных от управляющего микроконтроллера к контроллеру ЖКИ и от контроллера ЖКИ в управляющий микроконтроллер показаны на рисунках 5 и 6 соответственно. После приема информации контроллеру ЖКИ требуется некоторое время на выполнение команд, в это время управляющий контроллер не должен давать следующую команду или пересылать данные.
В таблице 1 приведены команды контроллера ЖКИ и время, необходимое для выполнения этих команд. Для того чтобы можно было определить, когда ЖКИ закончит свои внутренние операции, контроллер ЖКИ содержит специальный флаг занятости – BUSY-флаг (BF). Если контроллер занят выполнением внутренних операций, то BF установлен (BF = 1), если же контроллер готов принять следующую команду, то BF сброшен (BF = 0). Более простой способ организации обмена заключается в том, что управляющий микроконтроллер, зная, сколько времени требуется ЖКИ на обработку той или иной команды, после каждой передачи информации ждет соответствующее время.
Таблица 1 – Команды контроллера ЖКИ
Команда | Код | Описание | Время исполнения команды | |||||||||
RS | R/W | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | |||
Очистка дисплея | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | Записывает код 0x20 (пробел) во все ячейки DDRAM, устанавливает счетчик адреса DDRAM в 0x00. | 1,5 мс |
Возврат в начальную позицию | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | х | Устанавливает счетчик адреса DDRAM в 0x00 и возвращает курсор в начальную позицию. Содержимое DDRAM не изменяется. | 1,5 мс |
Режим ввода | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | L/R | SH | Задает направление перемещения курсора (L/R) и разрешает сдвиг сразу всех символов (SH). | 38 мс |
Включение-выключение дисплея | 0 | 0 | 0 | 0 | 0 | 0 | 1 | D | C | B | Устанавливает/ отключает биты, отвечающие за включения дисплея (D), отображение курсора (C), мерцание курсора (B). | 38 мкс |
Сдвиг курсора или видимой области дисплея | 0 | 0 | 0 | 0 | 0 | 1 | D/C | R/L | x | x | Бит D/C определяет то, что будет перемещаться – видимая область дисплея или курсор (при D/C = 1 перемещается видимая область, при D/C = 0 – курсор), R/L задает направление перемещения. DDRAM не изменяется | 38 мкс |
Начальные установки | 0 | 0 | 0 | 0 | 1 | DL | N | F | x | x | Определяет разрядность шины интерфейса (DL = 1 8-бит, DL = 0 4-бита), количества строк на дисплее (N = 1 – две строки, N = 0 – одна строка) и размера символов (F = 1 – 5×11 точек, F = 0 5×8 точек). | 38 мкс |
Установка адреса CGRAM | 0 | 0 | 0 | 1 | A5 | A4 | A3 | A2 | A1 | A0 | Установка счетчика адреса CGRAM | 38 мкс |
Установка адреса DDRAM | 0 | 0 | 1 | A6 | A5 | A4 | A3 | A2 | A1 | A0 | Установка счетчика адреса DDRAM | 38 мкс |
Чтение BF и счетчика адреса | 0 | 1 | BF | A6 | A5 | A4 | A3 | A2 | A1 | A0 | Если BF = 1 то контроллер ЖКИ выполняет внутреннюю операцию. А6 - А0 – текущее значение адреса DDRAM. | 0 |
Запись данных в RAM | 1 | 0 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | Запись данных в ОЗУ (DDRAM или CGRAM) | 38 мкс |
Чтение данных из RAM | 1 | 1 | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | Чтение данных из ОЗУ (DDRAM или CGRAM) | 38 мкс |
Перед началом работы требуется произвести инициализацию ЖКИ согласно алгоритму, показанному на рисунке 7.
3.2 Рекомендации по программному управлению ЖКИ
Программу для работы с ЖКИ следует организовать в виде функций, выполняющих определенные действия, причем более сложные функции могут включать в себя простейшие. Простейшими могут быть такие подпрограммы, как функция, отправляющая команду контроллеру дисплея; функция, устанавливающая счетчик адреса; или функция, записывающая данные в DDRAM. В любом случае, общий алгоритм передачи информации контроллеру не изменится. Руководствуясь диаграммой передачи информации (рисунок 5), определим последовательность действий при передаче информации в ЖКИ следующим образом: устанавливаем требуемое значение RS, на линию R/W подаем логический ноль, затем на линию E выводим логическую единицу, после чего подаем на шину D значение передаваемого байта. Контроллер ЖКИ считает этот байт и состояние управляющих линий (RS, R/W) только после подачи на линию E логического ноля. При этом, если временные задержки, указные на диаграмме, меньше длительности машинного цикла, то ими можно пренебречь. Код программы, реализующей запись в память ЖКИ байта данных, показан ниже:
RS = 1; // выбираем команды или данные
RW = 0; // выбираем направление передачи
E = 1;
Data = symbol; // выводим байт данных на шину D
E = 0; // переводим сигнал на линии E из 1 в 0
delay (); /* ждем, пока контроллер выполняет внутренние операции*/
В приведенном участке программы подразумевается, что переменные RS, RW и E объявлены как sbit, а переменная Data – как sfr. Аналогично будет происходить передача любой команды контроллеру ЖКИ.
При реализации чтения информации из контроллера необходимо пользоваться диаграммой, приведенной на рисунке 6. Следует помнить, что для того, чтобы ввести информацию с параллельного порта, в него предварительно должны быть записаны логические единицы.
Для того, чтобы не загромождать основную программу алгоритм инициализации (рисунок 7) можно реализовать в виде отдельной подпрограммы. Временные задержки, указанные в алгоритме, следует задавать с помощью таймеров, как это делалось в лабораторной работе «Изучение таймеров микроконтроллера».
4 Задание к работе в лаборатории
SFR таймеров SFR UART |
4.1 Вывод символа на ЖКИ
- Разработайте алгоритм программы, выводящей на экран ЖКИ ваше имя в заданной строке. Режим работы ЖКИ и номер строки определяется согласно варианту задания (таблица 2).
- По принципиальной схеме учебного стенда LESO1 определите, к каким выводам микроконтроллера ADuC842 подключен ЖКИ. По таблице SFR определите адреса используемых портов ввода-вывода.
- Разработайте и введите текст программы в соответствии с созданным алгоритмом.
- Оттранслируйте программу, и исправьте синтаксические ошибки.
- Загрузите полученный *.hex файл в лабораторный стенд LESO1.
- Убедитесь, что на экране дисплея в заданной позиции появился требуемый символ.
4.2 Управление ЖКИ через последовательный порт персонального компьютера (дополнительно)
- Измените программу таким образом, что бы на экране ЖКИ выводилась информация, переданная с персонального компьютера через UART. Передача команды осуществляется через терминал nwFlash. Выбор источника синхронизации и скорости передачи данных осуществляется по усмотрению студента.
- Загрузите полученный *.hex файл в лабораторный стенд LESO1.
- Через терминал nwFlash передайте коды символов, убедитесь, что соответствующие символы выводятся на экране индикатора.
Таблица 2 – Варианты заданий
номер варианта | номер строки | режим курсора |
1 | первая | выключен |
2 | вторая | включен, мерцает |
3 | первая | включен, не мерцает |
4 | вторая | выключен |
5 | первая | включен, мерцает |
6 | вторая | включен, не мерцает |
7 | первая | выключен |
8 | вторая | включен, мерцает |
9 | первая | включен, не мерцает |
10 | вторая | выключен |
11 | первая | включен, мерцает |
12 | вторая | включен, не мерцает |
13 | первая | выключен |
14 | вторая | включен, мерцает |
15 | первая | включен, не мерцает |
5 Указания к составлению отчета
Отчет должен содержать:
- Цель работы.
- Принципиальную схему подключения ЖКИ к управляющему микроконтроллер.
- Структурную схему ЖКИ.
- Диаграммы передачи данных по параллельному интерфейсу.
- Расчет параметров таймера.
- Графическую схему алгоритма работы программы.
- Исходный текст программы.
- Содержимое файла листинга программного проекта.
- Выводы по выполненной лабораторной работе.
Схемы, а также отчет в целом, выполняются согласно нормам ЕСКД.
Комментарии:
пт, 01/26/2018 - 18:33
Постоянная ссылка (Permalink)
Столкнулся с однйо проблемой что значения из массива не читаются.
Не буду копировать весь код приведу не большой отрывок:
сб, 01/27/2018 - 11:40
Постоянная ссылка (Permalink)
Сразу бросается в глаза: функция
symbol
принимает на вход переменную типаchar
(если смотреть на реализацию в приложенном файле), а на вход при вызове подаете значение превышающее диапазонchar
. Что за константа 512 и зачем она нужна?сб, 01/27/2018 - 12:01
Постоянная ссылка (Permalink)
Если изменить тип данных на int то особой разницы я не заметил. Функция symbol(512 + 1) работает без проблем. Еще одна маленькая странность. Константа 512 это есть 10 000 00000 то есть "Запись данных в RAM" к которой мы прибавляем 1 и получаем "10 000 00001"и закрашиваем 1 пиксель. А это самое "1" я не могу почему то взять из массива AA[0]. то есть вариант symbol(512+AA[0]); не хочет работать. Работает только если symbol(512+1);
сб, 01/27/2018 - 15:06
Постоянная ссылка (Permalink)
Вы что пытаетесь сделать? Вывести символ из стандартной таблицы или определить новый символ?
1. Функция
symbol
ожидает переменную типаchar
, это восемь бит. Значение 512+1 -- это уже 9 значащих бит. Компилятор неявням образом производит преобразования типов, и следовательно, отбрасывает старшие биты у аргумента. В функцию попадает не 513d (1000000001b), как вы ожидали, а 1d (00000001b), а это просто запись в память RAM . Все таки, зачем вам эти 512?2. В подцепе библиотека работы с этим LCD и файл с примером использования. В примере задется символ градуса для вывода температуры. Правда, писалось это для leso6, а там стоит AVR микроконтроллер.
сб, 01/27/2018 - 22:44
Постоянная ссылка (Permalink)
Я пытаюсь нарисовать свой символ, но сталкиваюсь с проблемой, что значения из массива не читаются или не передаются в функцию. Например:
на экран ничего не выводится. А если в функцию написать просто symbol(0x15); то закрашиваются нужные пиксели (10101). Что я делаю не так?
вс, 01/28/2018 - 16:10
Постоянная ссылка (Permalink)
Массив следует объявить того же типа, что и входной параметр функции , а именно:
Я понимаю, что в данном случае скорее всего приведение типов будет адекватным, но это зависит от типа и настроек компилятора. Зачем без необходимости подставляться?
А если не через массив передать значение, а через переменную? Тоже не работает?
P.S.: что бы не вводить капчу, лучше один раз зарегистрироваться. Капчи не будет и коменты появляются сразу, а не ждут одобрения.
пн, 01/29/2018 - 20:43
Постоянная ссылка (Permalink)
Вообще изначально мне нужно было создать char массив[16][20]; Но столкнулся с проблемой что в Kell появилась ошибка "TEXT1.C(77): error C241: 'main': auto segment too large" . Я подумал.."Странно.. вроде же есть 62кб памяти." Немного по искав в интернете и немного методом "тыка" в настройках во вкладке Target в поле Memory Model изменил с Small: variables in DATA на Large: variables in XDATA. Вроде бы стало компилироваться. Но именно в этом режиме как раз не были видны значения массива. Например:
char a[1] = {0x15};
symbol(a[0]);
Далее еще покапавшись в интернете и глянув код DEMO прошивки увидел что некоторые переменные можно объявлять как char xdata. Вернув значение Memory Model на исходное и попытавшись обявить переменную как char xdata ничего собственно не изменилось. Значение из массива так же не были видны. Хотя такая запись как
int xdata s = 0x15;
symbol(s);
спокойно работает и функция выводит 3 точки.
как мне создать этот
гребаныймассив 16х20....пн, 01/29/2018 - 21:24
Постоянная ссылка (Permalink)
Блин, у меня железяки под рукой нет. А так, весьма заинтригован.
Ну что вы хотите от старичка Адука? У него только 256 байта general-purpose RAM (далее просто RAM), причем, нельзя что бы объект занимал разом более 128 байт, так как эта память состоит из двух сегментов по 128 б. Остается только "2 kBytes of internal XRAM". Но это особая память и в первую очередь она предназначена для работы с АЦП в режиме DMA. Но с ней можно работать и как с основной. По умолчанию у 8052 переменные хранятся в RAM (адреса с 00h - FFh), но возможно перенаправить стек в XRAM, но для этого в регистре CFG842 нужно установить 7-ой бит. Почитайте даташиту на ADUC842, страница 27, 28 и 44.
Жду продолжения!
P.S.: Может пора зарегистрироваться?
вт, 01/30/2018 - 10:13
Постоянная ссылка (Permalink)
Ну а как же FLASH-ЭРПЗУ на 62КБ. ? Я не понимаю они есть или их нету? По даташиту трудно что то понять. Еще нашел книгу именно по серии 8051 https://yadi.sk/i/KtR4S8lm3RuD9Q Там вроде даже есть пример с использованием переменной XDATA. Но не с массивом. Одно значение переменной работает и у меня.
вт, 01/30/2018 - 13:29
Постоянная ссылка (Permalink)
FLASH -- это память программа. В 8052 используется гарвардская архитктура. Память программ и память данных разделены. Попробуйте поиграться с регистром CFG842. Может получится.
Еще полезно посмотреть Разработка программной части осциллографа-приставки
ср, 01/31/2018 - 11:15
Постоянная ссылка (Permalink)
Ну а тогда 4 Кб встроенной памяти данных, которые там имеются, как использовать?
ср, 01/31/2018 - 15:05
Постоянная ссылка (Permalink)
Просто с помощью модификатора поместить туда переменную при объявлении не получится. Есть специальная процедура записи и чтения в эту память. Подробнее на странице 42 (и далее) даташиты на ADUC842. Это немножко не просто и если вы не знаете, зачем вам это нужно, то скорее всего вам это не нужно. Если будете разбираться, то я вам помогу.
Эксперименты с регистром CFG842 ник чему не привели?