Адаптер параллельного LPT порта компьютера на ПЛИС

Адаптер параллельного LPT порта компьютера на ПЛИСПараллельный LPT порт компьютера это великолепная возможность удаленного управления различными устройствами и модулями. В частности очень часто его применяют для управления различными имитаторами сигналов в различных областях электроники. На управлении через параллельный порт компьютера уже создано и создается сложнейшее электронное навигационное оборудование для надводных и подводных судов, имитаторы позволяюшие тестировать и отлаживать электронные блоки и модули такого оборудования, а также имитаторы для широкого круга задач по электронике.

Для связи с "внешним миром" через LPT порт используются различного рода адаптеры, позволяющие посредством параллельного порта сформировать шину адреса и шину данных для дальнейшего управления каким-либо электронным модулем или прибором. Проблема в том, что такого рода адаптеры, если они выполнены не корректно могут составлять проблему при работе в связке с LPT портом компьютера.

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

На сегодняшний день адаптер LPT порта легко выполняется на любой простейшей ПЛИС CPLD Altera либо Xilinx. В любом случае схема остается одинаковой для любой логичесой матрицы. В свое время драйвер управления адаптером был написан на Ассемблере в среде C++ Builder 5 и так и остался неизменным до сегодняшнего дня. Для работы адаптера в операционной среде Windows XP применяется дополнительное ухищрение о котором будет написано ниже.

Адаптер представлен ниже. Это снимок с экрана монитора схемы в среде Max+ Plus2 конечного модуля. В левой части снимка модуля реальные названия сигналов параллельного порта используемые в данном адаптере. Это данные data0...7, strobe, select, auto_feed. В правой части снимка модуля выходные сигналы адаптера. Это двунаправленная восьмиразрядная шина данных, сигналы read и write, два адресных сигнала addr0 и addr1, которые можно использовать для управления 16 разрядными таймерами, сигналы выбора кристалла cs0...cs4 для выора конкретных устройств для записи или чтения данных. Реально сигналов cs может быть до 14. Это хорошо видно на развернутой схеме модуля.

Адаптер LPT на ПЛИС

Ниже содержимое самого модуля. Ничего сложного он из себя не представляет. Шинный формирователь AP6 написан на VHDL. Регистр 743737 формирует addr0 addr1 и сигналы выбора кристалла cs. Тригер 7474 предназначен для перевода шинного формирователя AP6 в выключенное состояние при включении питания. Для этого необходимы всего два навесных элемента, резистор и конденсатор, которые сформируют короткий импульс сброса на S вход тригера при подаче питания на адаптер. Включение адаптера уже выполняет управляющая программа посредством последнего сигнала cs15 декодера 74154. Управление с LPT порта внешними устройствами осуществляется в два этапа. Сначала формируется cs или адрес устройства, а затем передаются в него или принимаются от него восьмиразрядные данные.

Структура адаптера LPT

Проект для Max+Plus2 можно откомпилировать под любую CPLD ПЛИС Altera. Драйвер для данного адаптера, представлен ниже и написан под C++ Builder 5 для операционной среды Windows 98 и представляет собой .cpp файл с функциями управления адаптером, который можно подключать в любой проект.

//---------------------------------------------------
#include <vcl.h>
#pragma hdrstop

const unsigned int LPTBase = 0x378;
const unsigned int LPTCR = 0x37A;

const char Strobe=1;
const char Strb=0;
const char AutoFeed=2;
const char SelectIn=8;
const char NoAktive=0;
const char Neitral=0x20;

#pragma package(smart_init)

void OutPortB(Word Paddr, Byte Pdata);
void InitLPT(void);
void WriteByte(int Address,int Info);
int ReadByte(int Address);
//------------------------------------------------------
void wait (int wt) { //задержка
//------------------------------------------------------
while (wt--);
}
//------------------------------------------------------
void InitLPT(void) {
//------------------------------------------------------
asm {
mov dx,LPTCR
mov al,Neitral
out dx,al //порт LPT на ввод
// outportb(LPTCR,Neitral);
mov dx,LPTBase
mov al,0xff
out dx,al //в LPTBase 0xff
}
// outportb(LPTBase, 0xFF);
ReadByte(0x3C); //разблокировка имитатора
}

//------------------------------------------------------
void WriteByte(int Address,int Info) {
//------------------------------------------------------
// Запись байта информации Info по адресу Address
//-------------------------------------------------------
asm mov dx,LPTCR
asm mov al,NoAktive
asm out dx,al //запись в регистр управл. 0x00
// outportb(LPTCR,NoAktive);

asm mov dx,LPTBase
_AX=Address;
//asm mov al, Address
asm out dx,al //запись адреса в LPTBase
// outportb(LPTBase, Address);

asm mov dx,LPTCR
asm mov al,NoAktive
asm or al,SelectIn
asm out dx,al //формирование сигнала записи адреса
//во внешний регистр адреса
// outportb(LPTCR,NoAktive | SelectIn);
wait (5);

asm mov dx,LPTCR
asm mov al,NoAktive
asm out dx,al //сброс сигнала записи адреса
// outportb(LPTCR,NoAktive);

wait (5);

asm mov dx,LPTBase
_AX=Info;
//asm mov al,Info
asm out dx,al //запись байта информации в базовый
//регистр
// outportb(LPTBase, Info);

asm mov dx,LPTCR
asm mov al,NoAktive
asm or al,Strobe
asm out dx,al //формирование сигн.записи во внешние у-ва.
// outportb(LPTCR,NoAktive | Strobe);

asm nop
asm nop
asm nop

asm or al,AutoFeed
asm out dx,al //формирование выбора кристалла внешн.у-в.
// outportb(LPTCR,NoAktive | Strobe | AutoFeed);
wait (10);

asm mov dx,LPTCR
asm mov al,NoAktive
asm or al,Strobe
asm out dx,al //состояние внешнего порта -на передачу
// outportb(LPTCR,NoAktive | Strobe);

wait (3);

asm mov al,NoAktive
asm out dx,al //возвратить внешний порт в исходное сост.
// outportb(LPTCR,NoAktive);

asm mov al,Neitral //LPT_порт в исходное состояние
asm out dx,al
// outportb(LPTCR,Neitral);
}
//------------------------------------------------------
int ReadByte(int Address) {
//------------------------------------------------------
unsigned char Indat;

asm mov dx,LPTCR
asm mov al,NoAktive
asm out dx,al
// outportb(LPTCR,NoAktive);
//порт на запись
asm mov dx,LPTBase
_AX=Address;
//asm mov al,Address
asm out dx,al //в LPTBase Address
// outportb(LPTBase, Address);

asm mov dx,LPTCR
asm mov al,NoAktive
asm or al,SelectIn
asm out dx,al //фронт импульса записи адреса
// outportb(LPTCR,NoAktive | SelectIn);

wait (5);

asm mov dx,LPTCR
asm mov al,NoAktive
asm out dx,al //сброс сигнала записи адреса
// outportb(LPTCR,NoAktive);

wait (3);

asm mov dx,LPTCR
asm mov al,Neitral
asm out dx,al //спад имп.записи.адр.и перевод порта на ввод
// outportb(LPTCR,NoAktive);

asm nop
asm nop
asm nop

asm or al,AutoFeed
asm out dx,al //вывод сигнала CS
// outportb(LPTCR,NoAktive | AutoFeed);

wait (10);

asm mov dx,LPTBase
asm in al,dx //ввод данных из LPTBase в al
Indat = _AL; //передача считанных данных в Indat
// Indat = inportb(LPTBase);

asm mov dx,LPTCR
//asm mov al,NoAktive
//asm out dx,al // outportb(LPTCR,NoAktive);

asm mov al,Neitral
asm out dx,al //подтверждение порта на ввод
// outportb(LPTCR,Neitral);
return Indat; //Indat наружу
}

Для того, чтобы драйвер работал в операционной системе типа Windows XP используется дополнительная примочка в виде файла с расширением .sys, которую можно установить в операционку. Проект со всеми необходимыми файлами можно скачать и смело применять для управления внешним железом посредством параллельного порта компьютера. Если нет возможности применить ПЛИС схему можно выполнить на старой доброй жесткой логике.

комментариев: ()

Перейти и растаять в своей любимой социалке