Версия для печати
Программирование LCD - дисплея, на основе микросхемы HD44780
http://www.delphikingdom.com/asp/viewitem.asp?catalogID=1195Андрей Шишкин
дата публикации 24-01-2006 04:56Программирование LCD - дисплея, на основе микросхемы HD44780 Микросхема HD44780 - жидкокристаллический дисплейный модуль, который отображает две строки символов. Каждый символ может использовать 5х10 точек матрицы, из которых 5х7 разрешается выбирать программно. Дисплей имеет набор инструкций по выполнению различных функций.
В данном случае для ввода/вывода применяется восьмиразрядная двунаправленная шина данных. Кроме того, для работы дисплея, помимо шины данных, будем использовать - Выбор регистра (RS), Разрешение (Enable), вывод R/W - подключим на минус питания (будем использовать режим только записи в LCD).
Все выводы LPT (их нумерация) даны со стороны компьютера. Можно использовать LPT - кабель, отрезав разъем который подключается непосредственно к принтеру, и припаяв все по схеме. Питание +5V можно взять прямо из компьютера, или подать с внешнего блока питания.
Теперь непосредственно о программировании LPT - порта.
Для того чтобы можно было писать в LPT из под различных операционных систем семейства Windows, будем использовать драйвер LPTWDMIO.sys, предварительно скопировав его в папку Windows\System32\drivers, после чего устанавливаем LPTWDMIO.inf файл (Нажав на нем правой кнопкой мыши, и выбрав пункт меню Установить). Все что было нужно нам для работы, у нас есть. Теперь переходим непосредственно к программированию. Для работы с LPT и HD44780 был создан класс содержащий в себе все необходимое.
type THD44780 = class private CRValue,DRValue:byte; // Хранят значения регистров LPT Lpt: TLptPortConnection; // Указатель на объект LPT для работы procedure D0(Data:byte); //Установка битов порта LPT procedure D1(Data:byte); procedure D2(Data:byte); procedure D3(Data:byte); procedure D4(Data:byte); procedure D5(Data:byte); procedure D6(Data:byte); procedure D7(Data:byte); procedure Strobe(Data:byte); procedure Init(Data:byte); procedure AutoLF(Data:byte); procedure SelectIn(Data:byte); procedure OutData(Data:byte); //Вывод данных в LPT procedure ResetLPT(PortNum: integer); //Сброс LPT в начальное состояние public BlinkCursor:boolean; //Признак мерцания курсора VisibleCursor:boolean; //Признак видимости курсора procedure InitializationLPT; //Инициализация порта procedure _Control(Command:byte); //Вывод управляющего слова для LCD procedure _Clear; //Очистка LCD procedure _Home; //Установка курсора на первую позицию, первой строки procedure _Line1; //Выбор строки 1 procedure _Line2; //Выбор строки 2 procedure _Data(Ch:char); //Вывод символа procedure _Initialization; //Инициализация LCD procedure _Test; //Тест LCD procedure _MoveCursor(Position:byte); //Переместить курсор в опред. позицию end;В секции USES не забываем подключить LPTIO. В нем содержится реализация обращения к драйверу.
Реализация класса:
{ THD44780 } procedure THD44780.ResetLPT(PortNum: integer); begin DRValue:=00; // Сбрасываем регистр DR CRValue:=203; // Сбрасываем регистр CR if PortNum = 01 then begin Lpt.WritePort(LPT2,LPT_DATA_REG,DRValue); Lpt.WritePort(LPT2,LPT_CONTROL_REG,CRValue); end else begin Lpt.WritePort(LPT3,LPT_DATA_REG,DRValue); Lpt.WritePort(LPT3,LPT_CONTROL_REG,CRValue); end; { В модуле LPTIO под LPT1 понимается параллельный порт с базой $3BC, под LPT2 - с базой $378, под LPT3 - порт с базой $278. } end; procedure THD44780._Clear; begin _Control(1); end; procedure THD44780._Control(Command: byte); begin OutData(Command); Strobe(1); Init(1); Strobe(0); Init(1); Strobe(1); Init(1); end; procedure THD44780._Data(Ch: char); begin OutData(Ord(ch)); Strobe(1); Init(0); Strobe(0); Init(0); Strobe(1); Init(0); end; procedure THD44780._Home; begin _Control(2); end; procedure THD44780._Initialization; var ILCD:byte; begin _Control(16+32); //8 бит данных, 2 строки, 5*7 точек _Control(16+32); _Control(16+32); _Control(16+32+8+4); ILCD:=8+4; if BlinkCursor then ILCD:=ILCD+1; //1 - курсор мигает if VisibleCursor then ILCD:=ILCD+2; //2 - включение курсора _Control(ILCD); _Clear; _Control(4+2+0); end; procedure THD44780._Line1; begin _Control(128); end; procedure THD44780._Line2; begin _Control(128+64); end; procedure THD44780._Test; var s,s1:string; i:byte; begin s:='Stroka 1'; s1:='Stroka 2'; _Line1; for i:=1 to length(s) do _Data(s[i]); _Line2; for i:=1 to length(s1) do _Data(s1[i]); end; procedure THD44780._MoveCursor(Position: byte); begin _Control(128+Position); end; { THD44780 } procedure THD44780.AutoLF(Data: byte); begin CRValue:=Lpt.ReadPort(LPT2,LPT_CONTROL_REG); if Data=1 then begin CRValue:=CRValue and (255-2); end else CRValue:=CRValue or 2; Lpt.WritePort(Lpt2,LPT_CONTROL_REG,CRValue); end; procedure THD44780.D0(Data: byte); begin DRValue:=Lpt.ReadPort(LPT2,LPT_DATA_REG); if Data=0 then begin DRValue:=DRValue and (255-1); end else DRValue:=DRValue or 1; Lpt.WritePort(Lpt2,LPT_DATA_REG,DRValue); end; procedure THD44780.D1(Data: byte); begin DRValue:=Lpt.ReadPort(LPT2,LPT_DATA_REG); if Data=0 then begin DRValue:=DRValue and (255-2); end else DRValue:=DRValue or 2; Lpt.WritePort(Lpt2,LPT_DATA_REG,DRValue); end; procedure THD44780.D2(Data: byte); begin DRValue:=Lpt.ReadPort(LPT2,LPT_DATA_REG); if Data=0 then begin DRValue:=DRValue and (255-4); end else DRValue:=DRValue or 4; Lpt.WritePort(Lpt2,LPT_DATA_REG,DRValue); end; procedure THD44780.D3(Data: byte); begin DRValue:=Lpt.ReadPort(LPT2,LPT_DATA_REG); if Data=0 then begin DRValue:=DRValue and (255-8); end else DRValue:=DRValue or 8; Lpt.WritePort(Lpt2,LPT_DATA_REG,DRValue); end; procedure THD44780.D4(Data: byte); begin DRValue:=Lpt.ReadPort(LPT2,LPT_DATA_REG); if Data=0 then begin DRValue:=DRValue and (255-16); end else DRValue:=DRValue or 16; Lpt.WritePort(Lpt2,LPT_DATA_REG,DRValue); end; procedure THD44780.D5(Data: byte); begin DRValue:=Lpt.ReadPort(LPT2,LPT_DATA_REG); if Data=0 then begin DRValue:=DRValue and (255-32); end else DRValue:=DRValue or 32; Lpt.WritePort(Lpt2,LPT_DATA_REG,DRValue); end; procedure THD44780.D6(Data: byte); begin DRValue:=Lpt.ReadPort(LPT2,LPT_DATA_REG); if Data=0 then begin DRValue:=DRValue and (255-64); end else DRValue:=DRValue or 64; Lpt.WritePort(Lpt2,LPT_DATA_REG,DRValue); end; procedure THD44780.D7(Data: byte); begin DRValue:=Lpt.ReadPort(LPT2,LPT_DATA_REG); if Data=0 then begin DRValue:=DRValue and (255-128); end else DRValue:=DRValue or 128; Lpt.WritePort(Lpt2,LPT_DATA_REG,DRValue); end; procedure THD44780.Init(Data: byte); begin CRValue:=Lpt.ReadPort(LPT2,LPT_CONTROL_REG); if Data=1 then begin CRValue:=CRValue and (255-4); end else CRValue:=CRValue or 4; Lpt.WritePort(Lpt2,LPT_CONTROL_REG,CRValue); end; procedure THD44780.OutData(Data: byte); begin DRValue:=Data; Lpt.WritePort(Lpt2,LPT_DATA_REG,DRValue); end; procedure THD44780.SelectIn(Data: byte); begin CRValue:=Lpt.ReadPort(LPT2,LPT_CONTROL_REG); if Data=1 then begin CRValue:=CRValue and (255-8); end else CRValue:=CRValue or 8; Lpt.WritePort(Lpt2,LPT_CONTROL_REG,CRValue); end; procedure THD44780.Strobe(Data: byte); begin CRValue:=Lpt.ReadPort(LPT2,LPT_CONTROL_REG); if Data=1 then begin CRValue:=CRValue and (255-1); end else CRValue:=CRValue or 1; Lpt.WritePort(Lpt2,LPT_CONTROL_REG,CRValue); end; procedure THD44780.InitializationLPT; var msg: AnsiString; begin Lpt:=TLptPortConnection.Create; // Создаем объект связи с портом if not Lpt.Ready then // Если объект не готов, покажем begin // код ошибки и закроем программу msg:='Ошибка при создании объекта Lpt, код = ' + IntToStr(GetLastError()); Application.MessageBox(PChar(msg),'ERROR',MB_OK); Application.Terminate; end; ResetLPT(1); //LPT 1 end;Запись данных в LCD производится по отрицательному фронту на входе Enable.
Данный перепад описывается следующим образом:Strobe(1); Strobe(0); Strobe(1);Для указания вида операции над LCD используется вход RS. По документации: при логической 1, вывод данных (текст), при 0 - управляющее слово.
Команды LCD дисплея приведены в таблице:Данный пример был испытан на LCD: LE-1602T.
Внимание: Каждый контроллер LCD содержит в себе свой знакогенератор, обычно поддерживающий два языка. При выборе индикатора будьте внимательнее. Официальную документацию по интересующему вас дисплею найти не сложно.
Наиболее полная документация: HD44780.
К материалу прилагаются файлы:
- Исходные коды проекта (78 K) обновление от 1/24/2006 4:59:00 AM
- Исходные коды и исполняемый файл (253 K) обновление от 1/24/2006 4:59:00 AM