§ 6. Запись/чтение данных в LPT порт. (Часть 3) Пишем программу |
Вот мы и добрались до этапа, на котором напишем полноценую программу для чтения и записи данных в LPT порт. До этого мы рассмотрели внутренне устройство порта и сделали простенькое устройство из светододов для проведения опытов с портом LPT.
Давайте напишем программу, для проведения чтения и записи данных в порт. Программа предназначена для работы как под ОС Windows 9x так и под Windows NT. Для обеспечения такой функциональности будем использовать библиотеку inpout32.dll.
Скачать ее можно по ссылке ниже:
|
Итак, создаем пустой проект консольного приложения в VS++, создаем пустой файл *.cpp и копируем туда ниже следующий код:
#include <iostream.h> #include <stdio.h> #include <conio.h> #include "h.h" void WriteToDataRegister() { cout<<"Write data to DATA register.\n"<<endl; int b=0; cout<<"Enter data: "<<endl; cin>>b; if (b<0||b>255) cout<<"Error! You can take data only from diaposon 0-255."<<endl; else { Out32(888, b); cout<<"Write done.\n"<<endl; } cout<<"Press any key to back to Main menu..."<<endl; getch(); system("cls"); } void ReadDataRegister() { cout<<"Read data from DATA register.\n"<<endl; int data; data = Inp32(888); cout<<"10: "<<data<<endl; char number[20]; itoa(data,number,2); cout<<" 2: "<<number<<endl; cout<<"\nPress any key to back to Main menu..."<<endl; getch(); system("cls"); } void WriteToControlRegister() { cout<<"Write data to CONTROL register.\n"<<endl; int b=0; cout<<"Enter data: "<<endl; cin>>b; if (b<0||b>16) cout<<"Error! You can take data only from diaposon 0-16."<<endl; else { Out32(890, b); cout<<"Write done.\n"<<endl; } cout<<"Press any key to back to Main menu..."<<endl; getch(); system("cls"); } void ReadControlRegister() { cout<<"Read data from CONTROL register.\n"<<endl; int data; data = Inp32(890); cout<<"10: "<<data<<endl; char number[20]; itoa(data,number,2); cout<<" 2: "<<number<<endl; cout<<"\nPress any key to back to Main menu..."<<endl; getch(); system("cls"); } void ReadStatusRegister() { cout<<"Read data from STATUS register.\n"<<endl; int data; data = Inp32(889); cout<<"10: "<<data<<endl; char number[20]; itoa(data,number,2); cout<<" 2: "<<number<<endl; cout<<"\nPress any key to back to Main menu..."<<endl; getch(); system("cls"); } void Menu() { cout<<"Select operation:"<<endl; cout<<"1 - write data to DATA register."<<endl; cout<<"2 - read data from DATA register"<<endl; cout<<"3 - write data to CONTROL register."<<endl; cout<<"4 - read data from CONTROL register"<<endl; cout<<"5 - read data from STATUS register\n"<<endl; cout<<"0 - exit"<<endl; } int main() { Menu(); while(1){ switch(getch()) { case '1': system("cls"); WriteToDataRegister(); Menu(); break; case '2': system("cls"); ReadDataRegister(); Menu(); break; case '3': system("cls"); WriteToControlRegister(); Menu(); break; case '4': system("cls"); ReadControlRegister(); Menu(); break; case '5': system("cls"); ReadStatusRegister(); Menu(); break; case '0': exit(0); break; } } return true; }
От автора |
Спустя много лет, просматривая этот код, бросается в глаза ряд мелочей которые выдают начинающего программиста. Но оставляю код как есть, редактировать его не буду, пусть останется для истории. |
Незабываем скопировать файлы h.h, inpout32.lib, inpout32.dll в папку проекта, а файл inpout32.dll еще и в папку Debug, где будет располагаться откомпилированная программа. Далее выбираем Project -> Add to Project -> Files... В открывшемся окне отыскивайте папку вашего проекта, выбираете там только что помещенный туда файл h.h и нажимайте Ок. Файл добавится в проект. Проделывайте такую же операцию и для файла inpout32.lib.
Ну все, компилируем, запускаем. Вы должны увидеть нижеследующее окно. Перед нами, так называемое DOS-меню, реализованное на операторе switch-case. Нажатием клавиш от 0 до 5 мы вызываем соответствующий обработчик case.
Нажмем, например, клавишу 1. Будет вызвана функция WriteToDataRegister(), в которой осуществляется ввод данных с клавиатуры и запись их в регистр DATA LPT порта. Перед вызовом этой функции, камандой system("cls"); проводим очистку экрана: так работать удобней. Вводим число в диапозоне от 0 до 255 для записи в порт. Если число выходит за эти пределы, запись не проводим (т.к. регистр DATA 8-ми битный, и болеше в него "не влезет"). Запись проводим с помощью функции Out32() библиотеки inpout32.dll. Первым параметром этой функции передается адрес порта, куда надо записать данные, вторым параметром - сами данные.
Нажатием клавиши 3, вызовем аналогичную операцию ввода и записи данных в регистр CONTROL. Следует обратить внимание, на то, что границы вводимых чисел ограничены диапозоном 0-16, т.к., хотя CONTROL и 8-ми битный, но реально в нем используется только первые четыре бита.
Если нажмем 2, то будем читать данные из регистра DATA. Чтение проводим с помощью функции Inp32() библиотеки inpout32.dll. Единственным параметром этой функции передается адрес порта, откуда надо произвести чтение. Функция возвращает прочитанные данные в десятичной форме, которые мы тут же и выводим на экран. Для большего удобства восприятия с помощью стандартной функции itoa() проводим преобразование в двоичную систему счисления. Согласитесь, так гораздо удобнее: смотришь на блок светодиодов и сверяешь с результатом чтения, представленном в виде нулей и едениц (горит - негорит).
С помощью клавиш 4 и 5 аналогично проводим чтение данных из регистра CONTROL и STATUS.
О регистре STATUS следует поговорить подробнее. В него, как мы знаем, данные можно записать только "снаружи". Вот это мы сейчас и сделаем. Собрав устройство по схеме из предыдущей статьи, мы сможем писать данные в регистр. Используя набор ключей (замыкателей), будем устанавливать на соответствующем выводе регистра STATUS логическую ноль или еденицу. Попробуйте, установите какую-нибудь произвольную комбинацию переключателей и прочтите состояние регистра с помощью программы. Потом установите другую комбинацию. При этом, прочитав снова, вы получите другое число.
Вот так вот пограмма может узнать о изменении состояния внешнего устройства. |
К сожалению, при работе с регистром STATUS может возникнуть неприятная ситуация - "помигивание" других битов порта при первом замыкании на землю (подробнее, смотри статью Запись/чтение данных в LPT порт. (Часть 1) Основы.