Easyelectronics.ru

Электроника для всех
Текущее время: 06 дек 2019, 18:16

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/10pcs (Любой цвет!)
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 24 ] 
Автор Сообщение
 Заголовок сообщения: алгоритм
СообщениеДобавлено: 27 ноя 2011, 22:57 
Заглядывает иногда

Зарегистрирован: 27 ноя 2011, 22:54
Сообщения: 35
Немного глупый, а возможно и просто вопрос. Как сделать так, чтобы при нажатии на кнопку, огоньки светодиодной ленты бежали в одну сторону, при другом нажатии в другую сторону? Просто я написал алгоритм, по которому при нажатой кнопке огоньки бегут в одну сторону, а при отпущенной в другую. А вот над такой задаче голову ломаю, и ничего не получается...надеюсь на вашу помощь...заранее благодарен )


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 27 ноя 2011, 23:04 
Старожил
Аватара пользователя

Зарегистрирован: 26 янв 2010, 21:55
Сообщения: 5458
Откуда: Уругвайская АССР
Элементарно, Ватсон!
Берём ваш алгоритм, и проверку состояния кнопки меняем на проверку состояния бита переменной. А при нажатии на кнопку этот бит меняем на противоположный. Главное, антидребезг не забыть приделать, а то нечетко переключаться будет.

_________________
Без гнева и жестокости, сегодня Смерть взмахнёт косой, и ангел тайными дорогами мой милый Кубик унесёт с собой.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 27 ноя 2011, 23:09 
Заглядывает иногда

Зарегистрирован: 26 янв 2010, 22:01
Сообщения: 33
Откуда: Санкт-Петербург
В какую-нибудь отдельную переменную запомнить направление бегущих сейчас огоньков.

Тогда алгоритм работы прогаммы будет примерно такой:
10 Направление = 0
20 Если (кнопка_не_нажата), то 80
30 Если направление = 1, то 60
40 Огоньки бегут вправо
50 Переход к 20
60 Огоньки бегут влево
70 Переход к 20
80 Если направление = 1, то 110
90 Направление = 1
100 Переход к 120
110 Направление = 0
120 Если (кнопка_нажата), то 20
130 Переход к 120

_________________
Я бы в паровозники пошёл - пусть меня научат!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 27 ноя 2011, 23:10 
Заглядывает иногда

Зарегистрирован: 27 янв 2010, 19:27
Сообщения: 174
можно ввести переменную. при нажатии на кнопку бит в переменной инвертировать. если бит установлен движение в одну сторону, если сброшен - в другую


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 27 ноя 2011, 23:31 
Заглядывает иногда

Зарегистрирован: 27 ноя 2011, 22:54
Сообщения: 35
пробовал делать примерно также, как вы советуете. Но видимо плохо пробовал ))). Можно, если не затруднит, работающий алгоритм на С выложить? Сам текст программы...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 27 ноя 2011, 23:36 
Супермодератор
Аватара пользователя

Зарегистрирован: 23 апр 2010, 12:58
Сообщения: 5893
Откуда: Москва/Саратов
А вы можете, если вас не затруднит, выложить ваш первоначальный код. Потому что нас затруднит писать все заново

_________________
http://d.64h.me/


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 28 ноя 2011, 01:25 
Заглядывает иногда

Зарегистрирован: 27 ноя 2011, 22:54
Сообщения: 35
вот мой текст
while (1)
{
if (PINB.0 == 0)
{
sdvig = 0b10000000;
while(sdvig!=0)
{
PORTA = sdvig;
sdvig = sdvig >> 1;
delay_ms(200);
}
}

else
{
sdvig = 0b00000001;
while(sdvig!=0)
{
PORTA = sdvig;
sdvig = sdvig <<1;
delay_ms(200);
}
}

}
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 28 ноя 2011, 03:41 
Старожил
Аватара пользователя

Зарегистрирован: 30 янв 2010, 01:03
Сообщения: 647
Откуда: Херсон
Порт на вывод настроил? DDRA = 0xFF;

_________________
Если руки золотые, то не важно с какого места они растут.
Изображение
Изображение


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 28 ноя 2011, 08:47 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 16 сен 2011, 15:23
Сообщения: 52
Откуда: РФ, Москва
Код:
char dir=0; // направление
char pressed=0; // запоминает состояние кнопки

while (1)
{
  if (PINB.0 == 0)
  {
    if (pressed==0) // до этого кнопка была отпущена
    {
      dir=1-dir; // меняем направление (был 0 стало 1, было 1 стало 0)
      pressed=1; // запоминаем что это нажатие мы уже отработали, пока не отпустят кнопку, реагировать на неё больше не нужно
    }
  } else
    pressed=0; // кнопка отпущена

if (dir==1)
{
  sdvig = 0b10000000;
  while(sdvig!=0)
  {
   PORTA = sdvig;
   sdvig = sdvig >> 1;
   delay_ms(200);
  }
}
else
{
  sdvig = 0b00000001;
  while(sdvig!=0)
  {
   PORTA = sdvig;
   sdvig = sdvig <<1;
   delay_ms(200);
  }
}

}
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 28 ноя 2011, 08:59 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 16 сен 2011, 15:23
Сообщения: 52
Откуда: РФ, Москва
Если же нужно, чтобы направление можно было сменить прямо во время движения огонька (не дожидаясь, когда огонек добежит до края), то нужно немного переделать.

Во второй части идёт блок IF, почти один в один повторяющий блок ELSE. Их можно совместить, а по условию выполнять только то, что отличается. А цикл while(sdvig!=0) вообще раскрыть.
Как-то так:
Код:
if (sdvig==0)
{
  if (dir==1) sdvig = 0b10000000; else sdvig = 0b00000001;
}
... тут всё общее ...
if (dir==1) sdvig = sdvig >> 1; else sdvig = sdvig << 1;

Тогда можно кнопку проверять на каждом шаге и dir менять в любое время.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 28 ноя 2011, 15:02 
Заглядывает иногда

Зарегистрирован: 27 ноя 2011, 22:54
Сообщения: 35
Спасибо большое. Во всем разобрался, все работает :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 06 дек 2011, 21:50 
Заглядывает иногда

Зарегистрирован: 27 ноя 2011, 22:54
Сообщения: 35
Блин, ребят. Что за фигня? В CodeVisionAVR данный алгоритм работает. А вот в WinAVR уже нет. Там, как я понял нельзя писать PINB.0. А как тогда? Пробовал писать и 0x7F и 0b01111111. Не работает. Как быть?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 06 дек 2011, 21:58 
Администратор
Аватара пользователя

Зарегистрирован: 16 янв 2010, 06:09
Сообщения: 6274
Откуда: Челябинск
Ну а что есть PINB.0 м? Это бит 0 регистра порта PINB

так что если нам надо считать этот бит, то план действий такой:

Берем весь PINB и отрезаем от него все лишнее. Чем отрезаем? Очевидно же, маской по AND, где стоит только бит 0, а остальные нули.

Так что PINB.0 на чтение эквивалентно (PINB & 0xFE)

Кстати, а откуда взялась 7F и 0b01111111? Биты то считаются с другой стороны :)

_________________
Хозяин дома


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 06 дек 2011, 22:03 
Заглядывает иногда

Зарегистрирован: 27 ноя 2011, 22:54
Сообщения: 35
ой, ошибочка)


Последний раз редактировалось dolkons 06 дек 2011, 22:17, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 06 дек 2011, 22:07 
Заглядывает иногда

Зарегистрирован: 27 ноя 2011, 22:54
Сообщения: 35
Ура, все заработало. Надо для себя железное правило сделать, что применять битовые маски. Иначе никак ))). Кстати такой вот еще вопрос. Вот когда я смотрю в отладчике, то после команды PORTB = 0xFF у нас все биты сделались единичками. А вот биты PINB - нули. Они не должны тоже в единицу выставиться?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 06 дек 2011, 22:30 
Старожил
Аватара пользователя

Зарегистрирован: 17 апр 2010, 08:38
Сообщения: 4918
Откуда: Усинск, республика Коми
dolkons писал(а):
Ура, все заработало. Надо для себя железное правило сделать, что применять битовые маски. Иначе никак ))). Кстати такой вот еще вопрос. Вот когда я смотрю в отладчике, то после команды PORTB = 0xFF у нас все биты сделались единичками. А вот биты PINB - нули. Они не должны тоже в единицу выставиться?

Выставятся при следующем такте.

_________________
хаос это непознанный порядок


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 06 дек 2011, 22:44 
Администратор
Аватара пользователя

Зарегистрирован: 16 янв 2010, 06:09
Сообщения: 6274
Откуда: Челябинск
В студии смотришь? Там они и будут нули. PINB отражает текущую ситуацию на выводе порта и только ее. PORT или DDR ей не указ.

_________________
Хозяин дома


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 06 дек 2011, 23:39 
Заглядывает иногда

Зарегистрирован: 27 ноя 2011, 22:54
Сообщения: 35
да, в студии смотрю. То есть получается, что только вручную можно менять PINB в отладчике?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 06 дек 2011, 23:46 
Администратор
Аватара пользователя

Зарегистрирован: 16 янв 2010, 06:09
Сообщения: 6274
Откуда: Челябинск
Да, там только вручную. А ты как хотел? Это же внешняя периферия. Но, впрочем, есть еще возможность загрузить sti файл. Это просто временная диаграмма, показывающая когда и в какой момент времени надо какой уровень выставить на порту. А еще есть hapsim и плагин к протеусу (правда дико глючащий)

_________________
Хозяин дома


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 09 дек 2011, 00:47 
Заглядывает иногда

Зарегистрирован: 27 ноя 2011, 22:54
Сообщения: 35
Здравствуйте. Решил написать сюда, не создавать новую тему. Я сейчас осваиваю периферию МК. Вот решил опробовать в работе встроенные таймеры/счетчики. Вот код моей программы.
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
PORTA = 0xFF;
DDRA = 0xFF;
TCCR0 = 0x05;
TCNT0 = 0x00;
ACSR = 0x80;
while(1)
{
PORTA++;

while (!(TIFR&0x01));

TIFR = 0x01;
}
}
то есть тут получается...добавляем единицу, ждем, пока таймер не переполнится. При переполнении устанавливается флаг в TIFR. Потом сбрасывается, и снова добавляем единицу. Нельзя ли сделать что - нибудь вроде PORTA = TCNT0?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 09 дек 2011, 00:53 
Администратор
Аватара пользователя

Зарегистрирован: 16 янв 2010, 06:09
Сообщения: 6274
Откуда: Челябинск
Можно, а кто мешает? Будешь видеть в порту динамику изменения состояния счетного регистра

_________________
Хозяин дома


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 09 дек 2011, 00:57 
Заглядывает иногда

Зарегистрирован: 27 ноя 2011, 22:54
Сообщения: 35
Только получается настолько быстро, что кажется, будто светодиодики горят непрерывно. Коэффициент предделителя уже максимальный...1024. Как сделать так, чтобы счет стал заметен глазу?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 09 дек 2011, 01:19 
Старожил
Аватара пользователя

Зарегистрирован: 26 янв 2010, 23:30
Сообщения: 2785
снизить частоту кварца и выводить на светодиоды не в главном цикле, а в обработчике прерывания твоего таймера


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: алгоритм
СообщениеДобавлено: 09 дек 2011, 01:34 
Заглядывает иногда

Зарегистрирован: 27 ноя 2011, 22:54
Сообщения: 35
то есть получается, что по переполнению счетчика, будет вызываться функция обработки прерывания, в которой будем прибавлять единичку к порту?


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 24 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB