logo search
несколько программ / bsp33

ПрограммаRandom

Последнее, что мы сделаем с таймером - научимся получать от него случайные числа.

Для генерации случайных чисел лучше всего использовать канал 2 в режиме 3. В регистр счетчика канала мы занесем значение, равное диапазону нужных нам случайных чисел. Например, если мы запишем в регистр число 80 и запустим канал таймера, получаемые случайные числа будут лежать в диапазоне от 0 до 79.

Программа RANDOM(листинг 5.4) получает случайные числа и отображает их в наглядном виде с помощью столбчатой диаграммы.

Листинг 5.4. Файл random\random.с

// =====================================================

// Генерация случайных чисел

//

// (C) Фролов А.В, 1997

//

// E-mail: frolov@glas.apc.org

// WWW: http://www.glasnet.ru/~frolov

// или

// http://www.dials.ccas.ru/frolov

// =====================================================

#include <stdio.h>

#include <conio.h>

#include <dos.h>

void rnd_set(int bound);

int rnd_get(void);

int main(void)

{

int i, j;

printf("\nГенератор случайных чисел."

"\nНажмите любую клавишу,"

"\nдля завершения работы нажмите <Control+C>"

"\n");

for(;;)

{

// Устанавливаем диапазон генерации случайных

// чисел и инициализируем таймер

rnd_set(80);

// Ожидаем нажатия клавиши

getch();

// После нажатия на клавишу получаем

// случайное число

j = rnd_get();

// Выводим на экран строку символов "-",

// длина которой равна полученному случайному числу

for(i=0; i < j; i++)

putchar(219);

printf("\n");

}

return 0;

}

/**

*.Name rnd_set

*.Title Инициализация генератора случайных чисел

*

*.Descr Эта функция инициализирует канал 2 таймера

* для использования в качестве генератора

* случайных чисел

*

*.Proto void rnd_set(int bound)

*

*.Params int bound - верхняя граница для генерируемых

* случайных чисел.

**/

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().

**/

int rnd_get(void)

{

int i;

// Выдаем команду CLC для фиксирования

// текущего значения регистра канала 2 таймера

outp(0x43, 0x86);

// Вводим младший и старший байты счетчика

i = inp(0x42);

i = (inp(0x42) << 8) + i;

return(i);

}