Использование порта
Использование порта
Существуют две операции, которые могут выполняться с помощью порта: микропроцессор 8088 может послать информацию в подсоединенное устройство или прочитать данные из него. В языке Асемблера эти операции выполняются при помощи команд OUT и IN, а в языке Си использование указанных средств зависит от компилятора. Некоторые из них предоставляют возможность вызова специальных функций (в соответствии с тем, как это обычно делается в языке Си). В компиляторах Lattice С и Supersoft С, например с этой целью применяются функции outp( ) и inp( ), в других же аналогичные функции могут носить другие имена. Если вы работаете с компилятором, в котором такие возможности отсутствуют для задания указанных функций можно либо воспользоваться ассемблером, либо просто включить в свою программу соответствующий ассемблерный код (что очень просто). В любом случае вам необходимо ознакомиться с документацией по вашему компилятору. Пока же будем предполагать, что у вас имеется возможность вызова функций outp( ) и inp( ).
Приведем пример программы, представляющей собой первую попытку извлечь звуковой сигнал из громкоговорителя:
/* сигнал1 */
/* заставляет громкоговоритель подавать сигнал */
main( )
{
int store;
store = inp (97); /* запоминание начального значения с помощью порта 97 */
printf("пopт 97 = %d ", store); /* проверка результатов*/
outp(97, 79); /* посылает 79 в порт 97; включение громкоговорителя */
outp(97, store); /* восстановление начального значения */
}
Несмотря на то что, по-видимому, вы и сами можете догадаться, что выполняют функции inp( ) и outp( ), ниже приведем их формальное описание:
inр(номер порта)
Эта функция возвращает (т. е. формирует) 8-разрядное целое значение (которое преобразуется в 16-разрядное число типа int путем добавления нулей слева), полученное из порта ввода с указанным номером. Обращение к ней не зависит от номера подключенного порта.
оuр(номер порта, значение)
Эта функция передает 8-разрядное целое значение в порт вывода с указанным номером.
Заметим, что один и тот же порт может быть как портом ввода, так и портом вывода в зависимости от того, как он используется.
Давайте теперь выполним программу. В итоге вы можете быть не совсем удовлетворены, поскольку компьютер выключает громкоговоритель довольно быстро после включения. Было бы лучше если бы мы смогли заставить компьютер подождать немного, прежде чем выключить громкоговоритель. Как это можно сделать? Довольно просто! Нужно только дать компьютеру какую-нибудь работу" на это время. Приведенная ниже программа показывает, как этого достичь.
/* сигнал2 */
/* более длинный сигнал */
#define LIMIT 10000
int store;
int count = 0; /* счетчик для организации задержки */
store= inp (97);
outp (97, 79);
while (count++ < LIMIT); /* задержка на время работы пустого цикла */
outp (97, store);
Заметим, что вся работа оператора while состоит в увеличении на каждом шаге цикла) значения переменной count до тех пор, пока оно не станет равным величине константы LIMIT. Символ "точка с запятой", следующий за оператором while, - это "пустой" оператор, который не выполняет никаких действий. Поэтому программа сигнал2 включает громкоговоритель, считает до 10000, а затем выключает его. Вы можете изменять значение константы LIMIT чтобы регулировать продолжительность звучания, или можете заменить константу LIMIT переменной и использовать функцию scanf( ) для ввода соответствующего значения, определяющего продолжительность сигнала.
Было бы прекрасно иметь возможность регулировать и высоту тона. Это и в самом деле осуществимо. После того как мы изучим функции более полно, в приложении в конце книги вы сможете познакомиться с программой, которая превращает клавиатуру терминала в клавиатуру музыкального инструмента.