Страница 1 из 1
Atmega 8: генерация произвольных временных интервалов
Добавлено: Чт июл 02, 2009 10:59:02
litvinov_san
Доброго времени суток, уважаемые! Не могу понять почему не работает программа генератора случайных временных интервалов. Программирую в CodevisionAVR. Суть задачи в следующем: настроил прерывания таймера 1 атмеги на 1 с, по прерыванию увеличиваю переменную. При помощи команды rand генерирую целое число от 0 до 10. По идее контроллер должен сложить сгенерированное число с нужным мне временным интервалом(20 секунд) и сравнить с содержимым переменной в таймере,если таймер досчитал до 20+rand() то должен загореться светодиод. Вот только на практике что-то все не так. Прилагаю файлы проекта в Codevision и в Proteus. Помогите советом плиз, это мой первый проект,буду очень признателен за помощь

Добавлено: Чт июл 02, 2009 11:07:40
ikarab
Вы в PROTEUS "шагали" по проге ? Должно же видно быть что происходит не так как вы ожидали.
Для этого симляторы и есть что бы примерно показать процессы внутри микроконтроллера или схемы.
Добавлено: Чт июл 02, 2009 12:18:51
OBIVAN
Я думаю что рано или поздно Ваш светодиод всеж загорится:)) , только вероятность что переменная в 65535*1с при сравнивании с генерируемым числом все таки совпадет 1 из 10. Подсчитайте сколько должно пройти времени чтобы переменная достигла диапазона сравнения?
Добавлено: Чт июл 02, 2009 12:29:18
litvinov_san
В протеусе шагал, светодиод загарается, только загарается всегда через одинаковые промежутки времени. Такое ощущение что я просто не до конца понял как работает функция rand. Она генерирует всегда одно и то же число.
while (1)
{
// организация промежутка времени
srand(9);
i=rand()%11; // генерируется число от 0 до 10
if (sec==(10+i))
{
PORTB.1=0;
delay_ms(900);
PORTB.1=1;
sec=0;
}
Добавлено: Чт июл 02, 2009 12:33:40
litvinov_san
Пока таймер считает цикл while будет постоянно выполняться, т.е. rand всегда будет выдавать новые числа? Как можно еще реализовать генерацию случайных отрезков времени?
Добавлено: Чт июл 02, 2009 12:37:42
OBIVAN
допишите строчку ограничения интервала сек. If(sec>30)sec=0;
Добавлено: Чт июл 02, 2009 12:49:43
litvinov_san
OBIVAN писал(а):допишите строчку ограничения интервала сек. If(sec>30)sec=0;
Эффект тот же. Таймер отсчитывает 10 секунд как и положено+ 2с сгенерированные рандомом.Только этот рандом всегда генерирует 2 секунды.Либо сгенерировал один раз и дальше значение не изменяется:(. Пробовал вынести генерацию чисел за функцию While,пока все так же.
label:
srand(9);
i=rand()%11; // генерируется число от 0 до 10
while (1)
{
if (sec==(10+i))
{
PORTB.1=0;
delay_ms(900);
PORTB.1=1;
sec=0;
goto label;
}
if(sec>30)sec=0;
Добавлено: Чт июл 02, 2009 13:14:36
litvinov_san
Может быть для получения произвольных промежутков времени стоит использовать массив из произвольных чисел забитых ручками? Только как реализовать их перебор по кругу?
Добавлено: Чт июл 02, 2009 15:10:44
OBIVAN
unsigned char red1=1;
void vremia(int ms) {
int i;
for (i=0;i<ms;i++) _delay_ms(1);
}
srandom(red1);//
red1=random();//задаем случайную паузу между передачами
vremia(red1);//
Вот кусок кода со старого проекта в winavr все работало на ура. Я думаю переделать не сложно под то что вам нужно.
Добавлено: Чт июл 02, 2009 16:24:27
litvinov_san
Спасибо! Попробую
Добавлено: Пт июл 03, 2009 05:47:32
litvinov_san
А можно как-нибудь реализовать произвольную задержку по времени используя таймер, а не функцию delay? Не хотелось бы просто занимать вычислительные мощности контроллера
Добавлено: Пт июл 03, 2009 10:32:25
urry
Типа святое - именно так и нужно делать.
Добавлено: Пт июл 03, 2009 14:06:31
litvinov_san
Нормально заработал следующий вариант:
i=5; // задаю начальное значение переменной
srand(sec+(rand()));
while (1)
{
if (sec==(i)) // Если счетчик равен сгенерированному числу i +зедержке в 5с,то зажечь светодиод
{
i=0;
PORTB.1=0;
delay_ms(900);
PORTB.1=1;
sec=0;
i=rand()%11;
}
}
Правда получается псевдо случайные промежутки времени. После сброса МК выдаст те же самые интервалы. Спасибо всем за помощь
Добавлено: Сб июл 04, 2009 10:37:41
BCluster
для того чтоб этого не было перед rand() поставь srand(инт семечко).
Там где семечко - число с которого будет происходить рандомизация... другими словами - записывайте туда какое то число типа счетчика таймера - то есть то, что изначально случайно