Atmega 8: генерация произвольных временных интервалов

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Родился
Сообщения: 8
Зарегистрирован: Чт июл 02, 2009 07:12:04
Откуда: Челябинск

Сообщение litvinov_san »

Доброго времени суток, уважаемые! Не могу понять почему не работает программа генератора случайных временных интервалов. Программирую в CodevisionAVR. Суть задачи в следующем: настроил прерывания таймера 1 атмеги на 1 с, по прерыванию увеличиваю переменную. При помощи команды rand генерирую целое число от 0 до 10. По идее контроллер должен сложить сгенерированное число с нужным мне временным интервалом(20 секунд) и сравнить с содержимым переменной в таймере,если таймер досчитал до 20+rand() то должен загореться светодиод. Вот только на практике что-то все не так. Прилагаю файлы проекта в Codevision и в Proteus. Помогите советом плиз, это мой первый проект,буду очень признателен за помощь :)
Вложения
REAL.rar
(75 КБ) 199 скачиваний
Контактная информация:
Реклама
Опытный кот
Аватара пользователя
Сообщения: 828
Зарегистрирован: Пн мар 16, 2009 21:40:57

Сообщение ikarab »

Вы в PROTEUS "шагали" по проге ? Должно же видно быть что происходит не так как вы ожидали.

Для этого симляторы и есть что бы примерно показать процессы внутри микроконтроллера или схемы.
Контактная информация:
Реклама
Встал на лапы
Аватара пользователя
Сообщения: 84
Зарегистрирован: Вт ноя 25, 2008 18:56:41

Сообщение OBIVAN »

Я думаю что рано или поздно Ваш светодиод всеж загорится:)) , только вероятность что переменная в 65535*1с при сравнивании с генерируемым числом все таки совпадет 1 из 10. Подсчитайте сколько должно пройти времени чтобы переменная достигла диапазона сравнения?
Родился
Сообщения: 8
Зарегистрирован: Чт июл 02, 2009 07:12:04
Откуда: Челябинск

Сообщение 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;
}
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Родился
Сообщения: 8
Зарегистрирован: Чт июл 02, 2009 07:12:04
Откуда: Челябинск

Сообщение litvinov_san »

Пока таймер считает цикл while будет постоянно выполняться, т.е. rand всегда будет выдавать новые числа? Как можно еще реализовать генерацию случайных отрезков времени?
Контактная информация:
Реклама
Встал на лапы
Аватара пользователя
Сообщения: 84
Зарегистрирован: Вт ноя 25, 2008 18:56:41

Сообщение OBIVAN »

допишите строчку ограничения интервала сек. If(sec>30)sec=0;
Реклама
Родился
Сообщения: 8
Зарегистрирован: Чт июл 02, 2009 07:12:04
Откуда: Челябинск

Сообщение 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;
Контактная информация:
Родился
Сообщения: 8
Зарегистрирован: Чт июл 02, 2009 07:12:04
Откуда: Челябинск

Сообщение litvinov_san »

Может быть для получения произвольных промежутков времени стоит использовать массив из произвольных чисел забитых ручками? Только как реализовать их перебор по кругу?
Контактная информация:
Встал на лапы
Аватара пользователя
Сообщения: 84
Зарегистрирован: Вт ноя 25, 2008 18:56:41

Сообщение 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 все работало на ура. Я думаю переделать не сложно под то что вам нужно.
Родился
Сообщения: 8
Зарегистрирован: Чт июл 02, 2009 07:12:04
Откуда: Челябинск

Сообщение litvinov_san »

Спасибо! Попробую
Контактная информация:
Родился
Сообщения: 8
Зарегистрирован: Чт июл 02, 2009 07:12:04
Откуда: Челябинск

Сообщение litvinov_san »

А можно как-нибудь реализовать произвольную задержку по времени используя таймер, а не функцию delay? Не хотелось бы просто занимать вычислительные мощности контроллера
Контактная информация:
Сверлит текстолит когтями
Аватара пользователя
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница

Сообщение urry »

Типа святое - именно так и нужно делать.
Контактная информация:
Родился
Сообщения: 8
Зарегистрирован: Чт июл 02, 2009 07:12:04
Откуда: Челябинск

Сообщение 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;
}
}

Правда получается псевдо случайные промежутки времени. После сброса МК выдаст те же самые интервалы. Спасибо всем за помощь
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев

Сообщение BCluster »

для того чтоб этого не было перед rand() поставь srand(инт семечко).
Там где семечко - число с которого будет происходить рандомизация... другими словами - записывайте туда какое то число типа счетчика таймера - то есть то, что изначально случайно
Контактная информация:
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»