Params int ticrs - величина задержки в тиках таймера (за 1 сек таймер тикает 18,2 раза).
Return ничего
Sample tm_samp 1.c
**/
# include <dos.h>
# include <conio.h>
void tm_delay (int ticks) {
- asm {
Push si
Mov si, ticks
Mov ah, 0
Int 1ah
Mov bx, dx
Add bx, si
delay_loop;
Int 1ah
Cmp dx, bx
Jne delay_loop
Pop si
}
}
Функция использует только одно слово регистра таймера, что позволяет формировать задержки длительностью до 65536 тиков таймера.
Пример программы, демонстрирующей 10 секундную задержку (приблизительно):
# include <stdio.h>
# include “sysp.h”
main () {
printf (“\n Для выполнения программной задержки примерно”
“\n на 10 секунд нажмите любую клавишу. ”);
getch ();
printf (“\n Время пошло... ”);
tm_gelay (18*10);
printf (“\n Готово! ”);
exit (0);
}
BIOS IBM AT содержит еще две фукнции для работы с таймером: 83 h и 86h, реализуемые через прерывание INT 15h.
Функция 83 h позволяет запустить таймер на счет, указав адрес некоторого байта в оперативной памяти. Программа, запустившая таймер, сразу после запуска получает управление. По истечении времени, заданного при запуске таймера, функция устанавливает старший байт указанного байта в единицу, сигнализируя таким образом программе о завершении указанного временного интервала. Прогамма не может также отменить работу таймера в этом режиме.
Эту функцию удобно использовать для организации выполнения каких-либо действий параллельно с отчетом времени, например, можно организовать время для ввода пароля.
Формат вызова функции 83h, прерывания INT 15h:
На входе: AH = 83h;
AL = код подфункции;
0 - установить интервал, запустить таймер;
1 - отменить работу таймера;
CX = старший байт времени работы счетчика, задается в микросекундах;
ES:BX = адрес байта, в котором по истечении интервала времени старший
бит будет установлен в единицу.
На выходе: Не используются.
Функция 86 h предназначена для формирования задержек. Она позволяет определить время задержки в микросекундах, что удобно для многих задач. Во время задержки разрешены прерывания. Формат вызова фугкции:
На входе: АН = 86 h
СХ = старший байт времени задержки, задается в мкс;
DX = младший байт времени задержки
На выходе: Не используются
5. Средства MS-DOS для работы с таймером
Для работы с ситемным таймером MS-DOS использует четыре функции прерывания INT 21h. Эти функции позволяют узнать и установить текущую дату и время. При установке даты и времени можно изменить также показания часов реального времени.
Функция 2А h - используется для получения текущей даты:
На входе: АН = 2А h
На выходе: DL = день (0...31);
DH = месяц (1...12);
СХ = год (1980...2099);
AL = номер дня недели;
0- воскресенье;
1- понедельник;
- - - - - - - - - - -
6 - суббота
Функция возвращает Вам номер дня недели, который она вычисляет на основе даты.
Функция 2В h - установка даты:
На входе: АН = 2В h;
DL = день (0...31);
DH = месяц (1...12);
СХ = год (1980...2099).
На выходе: AL = 0, если установка выполнена правильно
AL = FFh, если при установке были заданы неправильные параметры.
Функция 2 Ch - определение текущего времени:
На входе: AH = 2Ch;
На выходе: CH = часы (0...24);
CL = минуты (0...59);
DH = секунды (0...59);
DL = сотые доли секунды (0...99).
Функция 2 Dh - установка времени:
На входе: AH = 2Dh;
CH = часы (0...24);
CL = минуты (0...59);
DH = секунды (0...59);
DL = сотые доли секунды (0...99).
На выходе: AL = 0, если установка выполнена правильно;
AL = FFh, если при установке были заданы неправильные параметры.
6.Таймер и музыка
Одно из наиболее распространенных применений таймера – генерация звуковых сигналов и воспроизведение музыки. Таймер позволяет воспроизводить музыку в фоновом режиме, т.е. во время работы программы может звучать музыка.
Как уже говорилось, канал 2 микросхемы 8254 связан с громкоговорителем компьютера. однако громкоговоритель не просто соединен с выходом OUT канала 2. Порт вывода 61h также используется для управления громкоговорителем. Младший бит порта 61h подключен ко входу GATE канала 2 таймера. Этот бит при установке в 1 разрешает работу канала, т.е. генерацию импульсов для громкоговорителя.
Дополнительно для управления громкоговорителем используется бит 1 порта 61h. Если этот бит установлен в 1, импульсы от канала 2 таймера смогут проходить на громкоговоритель.
Таким образом для включения звука надо выполнить следующие действия:
n запрограммировать канал 2 таймера на нужную частоту (т.е. загрузить регистр счетчика канала нужным значением);
n для включения звука установить в 1 2 младших бита порта 61h.
Так как остальные 6 битов порта 61h используются для других целей, установка младших битов должна выполняться таким образом, чтобы значения остальных битов не изменялись. Очевидно, что для выключения звука надо сбросить 2 младших бита порта 61h в 0.
Пример программы:
/**
Name tm_sound
Title Формирование тона заданной длительности.
Descr Эта функция предназначена для генерции на громкоговорителе тона заданной длительности и частоты.
Proto void tm_sound(int freq, int time);
Params int freq – частота в герцах;
int time – длительность в тиках таймера;
Return Nothing
Sample play.c
**/
#include <stdio.h>
#include <conio.h>
#include “sysp.h”
void tm_sound(int freq,int time){
int cnt, i
//Задаем режим канала 2 таймера
outp(0x43, 0xb6);
//Вычисляем задержку для загрузки
// в регистр счетчика таймера
cnt=1193180 / freq;
//Загружаем регистр счетчика таймера-
//сначала младший, затем старший байт
outp(0x42, cnt&0x00ff);
outp(0x42, (cnt&0xff00)>>8);
//Включаем громкоговоритель. сигнал от
//канала 2 таймера будет прохолить
//на вход громкоговорителя
outp(ox61,inp(0x61) | 3);
//Выполняем задержку
tm_delay(time); //см. п. 4
//Выключаем громкоговоритель
outp(0x61, inp(0x61) & 0xfc);
}
void main(void){
//Массив частот для мелодии
int mary[ ]={
330, 294, 262, 294, 330, 330, 330, 294, 294, 294, 330,
392, 392, 330, 294, 262, 294, 330, 330, 330, 330, 294,
294, 330, 294, 262, 0
};
//Массив длительностей.
int del[ ]={
5, 5, 5, 5, 5, 5, 10, 5, 5, 10, 5, 5, 10, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 20
};
for (int i=0; mary[ i ]!=0; i++_
tm_sound(mary[ i ], del[ i ]);
}
При написании собственных мелодий, можно воспользоваться следующей таблицей, в которой приведены частоты второй октавы. Для других октав при повышении или понижении тона значения частот надо умножать (при повышении) или делить (при понижении тона) на 2.
До | до-диез | Ре | ре-диез | Ми | Фа |
261.7 | 277.2 | 293.7 | 311.1 | 329.6 | 349.2 |
фа-диез | Соль | соль-диез | Ля | ля-диез | Си |
370.0 | 392.0 | 415.3 | 220.0 | 466.2 | 493.9 |
Генерация случайных чисел
Для генерации случайных чисел лучше всего использовать канал 2 в режиме 3. В регистр счетчика канала занесем значение, равное диапазону нужных случайных чисел. Например, если занести в регистр 80 и запустить канал таймера, получаемые случайные числа будут лежать в диапазоне от 0 до 79.
Пример программы:
#include <stdio.h>
#include <conio.h>
#include <sysp.h>
/**
Name rnd_set
Title Инициализация генератора случайных чисел
Descr Эта функция инициализирует канал 2 таймера для использования в качестве генератора случайных чисел
Proto void rnd_set(int bound)
Params int bound – верхняя граница для генерируемых случайных чисел
Return Nothing
Sample random.c
**/
void rnd_set(int bound){
//Устанавливаем режим 3 для второго канала таймера.
outp(0x43, 0xb6);
//Загружаем рагистр счетчика таймера - сначала
//младший, затем старший байт
outp(0x42, bound & 0x00ff);
outp(0x42, (bound & 0xff00)>>8);
//Разрешаем работу канала
outp(0x61, inp(0x61) | 1);
}
/**
Name rnd_get
Title Получение от таймера случайного числа
Descr Эта функция получает случайное число от таймера, который был предварительно проинициализирован функцией rnd_set
Proto int rnd_get(void)
Params Отсутствуют
Return Случайное число в диапазоне от 0 до уменьшенного на 1значения заданного в качестве параметра функции rnd_set()
Sample random.c
**/
int rnd_get(void){
int i;
//Выдаем команду CLC для фиксирования
//текущего значения регистра канала2 таймера
outp(0x43,0x86);
//Вводим младший и старший байты счетчика
i=inp(0x42);
i+=(inp(0x42)<<8);
return i
}
void main(){
int i, j;
printf(“\nГенератор случайных чисел.”
“\nНажмите любую клавишу.”
“\nдля завершения работы нажмите ctrl+C\n”);
for(;;){
//Устанавливаем диапазон генерации случайных
//чисел и инициализируем таймер
rnd_set(80);
//Ожидаем нажатия клавиши
getch();
//После нажатия на клавишу
//получаем случайное число
j=rnd_get();
//Выводим на экран строку символов “g”,
//длина которой равна полученному
//случайному числу
for (i=0; i<j; i++) putchar(219);
printf(“\n”);
}
}
Программа получает случайные числа и отображает их в наглядном виде с помощью столбчатой диаграммы.
В ходе работы должна быть разработана программа, основанная на принциах действия системного таймера, которая будет реализовывать следующие возможности:
1. Составить программу для генерации случайных чисел с помощью системного таймера в диапазоне, указанном в таблице №1.
2. Составить программу для генерации звукового сигнала заданной частоты, используя системный таймер.
Варианты заданий в таблице № 1.
3. С помощью функции 83h прерывания 15h организовать задержку на указанное в таблице № 1 количество секунд и проконтролировать уходящее время.
4. Выполнить задание согласно таблицы № 2
Варианты индивидуальных заданий к лабораторной рабо“СИСТЕМНЫЙ ТАЙМЕР”.
Таблица № 1
Вариант | Частота1, в Гц | Частоата2, в Гц | Диапазон Начало | Конец | Задержка, в мс | |
Таблица № 2
Вариант | Задание | Примечание |
а. Отображение слова состояния и содержимого счетчика для 1 порта б. Часы реального времени | программирование на уровне портов использование int 1 Ch | |
а. Формирование задержки б. Генерация случайных чисел | функции 00h и 01прерывания int 1 Ah BIOS | |
а. Получение и установка текущей даты б. Отображение слова состояния и содержимого счетчика для 2 порта | средства MS DOS - int 21h программирование на уровне портов | |
а. Получение и установка текущего времени б. Генерация звука с использованием таймера | средства MS DOS - int 21h | |
а. Отображение слова состояния и содержимого счетчика для 3 порта б. Часы реального времени | программирование на уровне портов использование int 1 Ch | |
а. Генерация звука с использованием таймера б. Часы реального времени | использование int 1Ch | |
а. Отображение слова состояния и содержимого счетчика для 3 порта б. Получение и уствновка текущей даты | программирование на уровне портов средства MS DOS - int 21 h | |
а. Получение и установка текущего времени б. Отображение слова состояния и содержимого счетчика для 2 порта | средства MS DOS - int 21h программирование на уровне портов | |
а. Генерация случайных чисел б. Формирование задержки | функции 00h и01h прерывания int 1 Ah BIOS | |
а. Получение и установка текущей даты б. Отображение слова состояния и содержимого счетчика для 1 порта | средства MS DOS - int 21h программирование на уровне портов |