Assembler - язык неограниченных возможностей


Таймер - часть 3


  1. Вывести в регистр 43h команду (для канала 0) 0011011h, то есть установить режим 3 для канала 0, и при чтении/записи будет пересылаться сначала младшее слово, а потом старшее.
  2. Послать младший байт начального значения счетчика в порт, соответствующий выбранному каналу (42h для канала 2).
  3. Послать старший байт начального значения счетчика в этот же порт.

После этого таймер немедленно начнет уменьшать введенное число от начального значения к нулю со скоростью 1 193 180 раз в секунду (четверть скорости процессора 8088). Каждый раз, когда это число достигает нуля, оно снова возвращается к начальному значению. Кроме того, при достижении счетчиком нуля таймер выполняет соответствующую функцию — канал 0 вызывает прерывание IRQO, а канал 2, если включен динамик, посылает ему начало следующей прямоугольной волны, заставляя его работать на установленной частоте. Начальное значение счетчика для канала 0 по умолчанию составляет 0FFFFh (65 535), то есть максимально возможное. Поэтому точная частота вызова прерывания IRQ0 равна 1 193 180/65 536 = 18,20648 раза в секунду.

Чтобы прочитать текущее значение счетчика, надо:

  1. Послать в порт 43h команду фиксации значения счетчика для выбранного канала (биты 5 – 4 равны 00h).
  2. Послать в порт 43h команду перепрограммирования канала без изменения режима его работы, если нужно изменить способ чтения/записи (обычно не требуется).
  3. Прочитать из порта, соответствующего выбранному каналу, младший байт зафиксированного значения счетчика.
  4. Прочитать из того же порта старший байт.

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

Посмотрим в качестве примера, как при помощи таймера измерить, сколько времени проходит между реальным аппаратным прерыванием и моментом, когда обработчик этого прерывания получает управление (почему это важно, см. пример программ вывода звука из глав 5.10.8 и 5.10.9). Так как IRQ0 происходит при нулевом значении счетчика, нам достаточно прочитать его значение при старте обработчика и обратить его знак (потому что счетчик таймера постоянно уменьшается).

; latency.asm ; измеряет среднее время, проходящее между аппаратным прерыванием и запуском ; соответствующего обработчика. Выводит среднее время в микросекундах после ; нажатия любой клавиши (на самом деле в 1/1 193 180). ; Программа использует 16-битный сумматор для простоты, так что может давать ; неверные результаты, если подождать больше нескольких минут




Начало  Назад  Вперед