Реклама:

♦ устройства сопряжения выполняют определенные функции, каждая из которых реализуется в виде отдельного драйвера; на более низком уровне (управление отдельными разрядами отдельных регистров) разделения на программные модули не производится;

♦ большинство устройств имеют регистры управления или состояния, в которых каждый бит или группа битов соответствуют определенным режимам работы устройства; маски этих битов (позиции в байте или слове) определяются перед драйверами и используются в битовых операциях для установки или проверки;

♦ в качестве глобальной переменной определяется первый ("базовый") адрес устройства в адресном пространстве, а его остальные адреса вычисляются добавлением к базовому адресу смещения.

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

2.2.2. Программирование универсального контроллера параллельного обмена

Описанный в п.2.1.9 универсальный контроллер параллельного обмена (УКПО) содержит 7 программно-доступных байтовых двунаправленных портов и регистр управляющего слова. Таким образом, на нижнем уровне программирования УКПО необходимо реализовать три функции: запись управляющего слова, запись данных в любой порт и чтение данных из любого порта. На языке Си они выглядят так:

И *** функция записи управляющего слова

// CW_ADDR — адрес регистра управляющего слова

// cw — байт управляющего слова

outportb (CW_ADDR, cw);

// *** функция записи данных в порт

// BASE_ADDR — базовый адрес УКПО (адрес порта 0)

// port — номер порта (0...6)

// data — байт данных

outportb (BASE_ADDR + port, data);

// *** функция чтения данных из порта

// BASE_ADDR — базовый адрес УКПО (адрес порта 0)

// port — номер порта (0...6)

// data — байт данных

data = inportb (BASE_ADDR + port);

Напишем для примера простейшую программу тестирования УКПО. Будем последовательно записывать во все пор-тьі код 55Н и контролировать правильность записи. При этом все порты, кроме тестируемого, будем переводить в режим чтения.

// *** Программа тестирования УКПО ***

include <STDIO.H> "include <DOS.H>

#define NPORT 7 // Число портов УКПО

// Глобальные переменные

unsigned BASE_ADDR; // Базовый адрес УКПО unsigned CW_ADDR; // Адрес регистра управляющего

// слова

void main (void) {

unsigned і;

unsigned char data = 0x55;

for (i=0;i<NPORT;i++) {

outportb (CW_ADDR, 1 « і); // Установка

// конфигурации: // і—ый порт //на вывод, // остальные //на ввод

outportb (BASE + і, data); // Запись данных

if ( inportb (BASE + і) != data ) printf ("\n\tnopT %d неисправен"); else

printf ("\п\Шорт %d исправен");

} }

//*** Конец программы

Как уже отмечалось, каждому порту УКПО соответствует один бит управляющего слова. Единица в этом бите устанавливает порт в режим передачи данных, а ноль — в режим приема. Естественно, что когда порт находится в режиме передачи, ничто не мешает прочитать его содержимое, контролируя таким образом правильность вывода. Именно это свойство УКПО использовано в программе его тестирования. Поэтому, хотя мы и будем называть состояния портов "ввод" и "вывод", будем иметь в виду, что "вывод" на самом деле является "вводом/выводом"' В нашем примере для последовательной установки портов в режим вывода использовалась операция сдвига единицы на число разрядов, равное номеру порта. Очевидно, что при этом данный порт устанавливается на вывод, а все остальные — на ввод.


⇐ Предыдущая страница| |Следующая страница ⇒