роботы робототехника микроконтроллеры


 Страниц (2): [1] 2 »   

> Описание: Создание "эфекта" бегущих огней
dimamukhin Post Id



Лейтенант


Сообщений всего: 32
Дата рег-ции: Март 2009  



Предлагаю в этой теме обсуждать принципы построение БЕГУЩИХ ОГНЕЙ !


У меня сразу вопросик . Увидел - теперь голову ломаю!

Смысл : Atmega , 8 светодиодов ,CVAVR.
Бежит точка с 1 на 8 светодиод и там остается гореть . Следующая точка бежит с 1 на 7 и остается гореть и т.д. , пока все светодиоды не загорятся .

Бег получился, но как заставить оставаться гореть ?

#include <mega8.h>
#include <delay.h>

int i=8;
int k;
int h=0;

void main(void)
{
PORTB=0x00;
DDRB=0xFF;

while (1)
{
for(k=0 ; k<i; k++)
{
PORTB=(1<<h);
h++;
delay_ms(100);
}
i--;
h=0;
};
}
 
 Top
redcat Post Id



Главнокомандующий


Сообщений всего: 387
Дата рег-ции: Янв. 2009  



Поменяй PORTB=(1<<h); на PORTB|=(1<<h);

... не нужно менять все биты порта, меняй только нужный.
 
 Top
dimamukhin Post Id



Лейтенант


Сообщений всего: 32
Дата рег-ции: Март 2009  



Не подходит Подмигивающий
 
 Top
СКАЗОЧНИК Post Id



Главнокомандующий


Сообщений всего: 377
Дата рег-ции: Нояб. 2009  



Вот так. Один из вариантов:

CODE:
// Указать на какой частоте работает МК в Гц
#define F_CPU 8000000UL // Частота 8 MHz

#include <avr/io.h> // библиотека I/O
#include <util/delay.h> // библиотеки пауз

char n, k;

int main(void)
{
DDRD = 0xFF; // все выводы порта D сконфигурировать как вЫходы

while (!0) // Бесконечный цикл
{
PORTD = 0x00;
for(n=0; n<8; n++)
{
for(k=0; k<(8-n); k++)
{
PORTD |=1<<k; // зажигаем
_delay_ms(250); // Пауза
PORTD &=~(1<<k); // гасим
}
PORTD |=1<<(7-n); //зажигаем последний...
}
} // закрывающая скобка бесконечного цикла

} // закрывающая скобка основной программы


В Протеусе все работает.
(Добавление)
Прошу прощения, что на порт Д, просто в Протеусе на порте Б надо кварц отключать, у меня фъюзы там расставлены... Подмигивающий

(Отредактировано автором: 13 Марта, 2010 - 13:06:57)

 
 Top
lamakazzz Post Id



Главнокомандующий


Сообщений всего: 328
Дата рег-ции: Янв. 2010  



dimamukhin
если Вы программист, то должны знать, что все задачи, которые не понимаете, - надо рисовать.
Вообще, после того, как Вы уяснили себе задачу - нарисуйте на бумаге блок-схему, некий алгоритм работы вашей программы и Вам будет намного легче, чем прокручивать всё это в голове. Будет виден каждый шаг и Вы поймете, где чего не додумали.
На свой старый код не смотрите, давайте попробуем с нуля. Постановка задачи у Вас есть, теперь разберемся с алгоритмом.

1) Объявляем переменные.

CODE:
int i, j; // объявления переменных;


2) Начало Цикла1 (забегая вперед скажу, что нам понадобятся два цикла, при чем второй цикл будет внутри первого, поэтому обозначим их как Цикл1 и Цикл2) .
Итак, в этом цикле мы будем производить итерации и зажигать и оставлять соответствующие диоды, начиная с 8, потом 7, потом 6 и так до 1го. Поэтому в этом цикле будем использовать декремент, что в языке С соответствует i--, где i это переменная (а еще есть --i, но в данном случае это не подходит. и если интересно почему - почитайте литературу).
Получается что-то типо

CODE:
for (i = 8; i >= 1; i--) // начало цикла1;
{


3) Начало Цикла2. В этом цикле будем мигать диодами, начиная с 1го и пока не достигнем диода, который уже светит, то есть до i-1. Поэтому в этом цикле будем использовать инкремент j++ и в каждой итерации будем зажигать j-ый светодиод.

CODE:
for (j = 1; j <= i-1; j++) // начало цикла2;
{


4) Собсна, что мы должны ща делать? Мигать диодом! для удобства понимания определим некоторую функцию (почему функцию - расскажу позже), с помощью которой будем подавать лог. 1 на порт, соответствующий порядковому номеру нужного диода. Номер этого диода у нас будет как входной параметр:
CODE:
Turn_on_LED(j); // Зажигаем светик под номером j. эту функцию напишете сами, думаю, труда не составит. функции вообще для тренировки, можно и без них обойтись


5) чтобы диод погорел - нужно поставить некоторую задержку, поэтому:
CODE:
delay_ms(100); // задержка


6) теперь необходимо потушить светик. Вообще говоря, можно использовать ту же самую функцию, что и включение диода - просто инвертировать значения порта и это будет самый лучший вариант в данном случае. Но можно и написать другую функцию, тут уж зависит от полета фантазии. для простоты обозначим функцию так:
CODE:
Turn_off_LED(j); // тушим светик под номером j


7) чтобы диод горел с одинаковой периодичностью - нужно поставить такую же задержку, поэтому:
CODE:
delay_ms(100); // задержка


8) на этом Цикл2 заканчивается, поэтому:
CODE:
} // конец Цикла2


9) итак, отработая все итерации Цикла2, последний мигнувший диод у нас окажется под номерм i-1. Что нам теперь нужно? Теперь необходимо диод с номером i добавить в список постоянно горящих диодов, поэтому определим некоторую функцию:
CODE:
Add_LED_to_List(i); // функцию тоже напишете сами - это домашнее задание :)) (можно ведь и совсем без функции, просто биты соответствующие выставить:)


10) Ну и теперь собсна светим диодами, которые находятся в нашем списке. Опять же, определяем функцию:
CODE:
Turn_on_List_LEDs(); // я ленивый, писать тут тоже не хочу, поэтому Вам придется потрудиться XDD


11) Усё, конец Цикла1.

CODE:
} // конец Цикла1


Я бы Вам блок-схему показал, но рисовал на бумаге, а фоткать щас нечем. так что звыняйтэ, бананив нэма XDD

(Отредактировано автором: 13 Марта, 2010 - 12:43:03)

 
 Top
СКАЗОЧНИК Post Id



Главнокомандующий


Сообщений всего: 377
Дата рег-ции: Нояб. 2009  




Подмигивающий Я же говорю, что один из вариантов.

Кстати, не забудьте настроить Мэйкфайл и светодиоды подключить катодами на землю.
(Добавление)
lamakazzz пишет:
dimamukhin
если Вы программист, то должны знать, что все задачи, которые не понимаете, - надо рисовать.

Улыбка Я тоже сидел рисовал алгоритм.

(Отредактировано автором: 13 Марта, 2010 - 15:14:48)

 
 Top
lamakazzz Post Id



Главнокомандующий


Сообщений всего: 328
Дата рег-ции: Янв. 2010  



Правильно Улыбка всегда помогает Улыбка даже в школе в 5м классе нам учитель математики говорила, что надо рисовать, я как сейчас помню Улыбка)
 
 Top
dimamukhin Post Id



Лейтенант


Сообщений всего: 32
Дата рег-ции: Март 2009  



lamakazzz , огромное спасибо !
Честно говоря, некоторые за деньги не дают такие исчерпывающие ответы .
По поводу программы - все равно придется переделывать под CodeVisionAVR - она для меня проще , да и генератор начального кода меня там устраивает .

По поводу блок схем , функций и т.п. : школу и институт я честно сказать про....бал Подшучивать, дразнить . Паяю с малых лет , но чисто практик. Где можно почитать как строить блок схемы и САМОЕ важное - как их в программу перевести . Буду очень благодарен .
 
 Top
dimamukhin Post Id



Лейтенант


Сообщений всего: 32
Дата рег-ции: Март 2009  



После некоторых раздумий - получилось что хотелось ! Подшучивать, дразнить

Не знаю, на сколько правильно код написал, но работает .

#include <mega8.h>
#include <delay.h>

char j;
int h=0,z,k,i=8;
void main(void)
{
PORTB=0x00;
DDRB=0xFF;

while (1)
{

for(z=0; z<8; z++)
{
for(k=0 ; k<i; k++)
{
PORTB=(1<<h)|j;
h++;
delay_ms(100);
};
h=0;
i--;
j=PORTB;
};

h=0;
i=8;
z=0;
k=0;
j=0;
};
}

Но вопрос про литературу остается открытый!
Скачать файл: 1.rar
Скачан раз: 242

(Отредактировано автором: 13 Марта, 2010 - 23:41:15)

 
 Top
redcat Post Id



Главнокомандующий


Сообщений всего: 387
Дата рег-ции: Янв. 2009  



Мне код не нравится, слишком много переменных.
 
 Top
dimamukhin Post Id



Лейтенант


Сообщений всего: 32
Дата рег-ции: Март 2009  



Давайте подправим ! Критика только приветствуется Улыбка
 
 Top
nest Администратор Post Id



Администратор


Сообщений всего: 4866
Дата рег-ции: Сент. 2009  



сдвиг одного огня с остановкой и сохранением последнего бита, я бы сделал так.
Но тоже без претензий к совершенству :)

$a=0b00000001
while($a=0b10000000){
$b=$a OR $b
PORTB=$b
delay_ms(100);
$a=$a*2
}
 
 Top
redcat Post Id



Главнокомандующий


Сообщений всего: 387
Дата рег-ции: Янв. 2009  



Математика нам поможет.
 
 Top
СКАЗОЧНИК Post Id



Главнокомандующий


Сообщений всего: 377
Дата рег-ции: Нояб. 2009  



nest пишет:
сдвиг одного огня с остановкой и сохранением последнего бита

А можно подробнее???
Не очень понятные для меня конструкции... Код очень простой, но обозначения... и как они работают? Все что я смог за час выродить - оно несколькими постами выше. Ламер
(Добавление)
Вообще-то понятно, как цикл работает, но обозначения перменных почему с долларом?
 
 Top
redcat Post Id



Главнокомандующий


Сообщений всего: 387
Дата рег-ции: Янв. 2009  



$ в некоторых языках ставится перед переменной.
 
 Top
Страниц (2): [1] 2 »
« Программирование микроконтроллеров »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 





Powered by Exclusive Bulletin Board
ExBB FM 1.0 RC1 Smiles by Fool from Foolstown
  Яндекс.Метрика   Рейтинг@Mail.ru