между циклами ожидающими отпускания кнопки вставь циклы, ожидающие нажатия...
Всё верно, только чуть поправлю - ожидающие отпускания )
olegue, соб-но вам Ivanoff-iv правильно подсказал - между while ((PINB & (1 << PB1))){}; и while ((PINB & (1 << PB1))){ PORTB^=(1<<PB0); ... у вас нет ничего. Вы нажимаете кнопку раз, переходите ко 2му while, который сразу же не срабатывает, потому что кнопка еще нажата. Ведь кнопка - не сферическая в вакууме, она не моментально отжимается, а нажата сколько-то там времени, которое много больше, чем 3-4 инструкции МК выполнить.
Карма: 14
Рейтинг сообщений: 115
Зарегистрирован: Сб май 21, 2016 11:04:52 Сообщений: 2957 Откуда: Беларусь
Рейтинг сообщения:0
NStorm писал(а):
Ведь кнопка - не сферическая в вакууме, она не моментально отжимается, а нажата сколько-то там времени, которое много больше, чем 3-4 инструкции МК выполнить.
Правильней проверять кнопку не постоянно, зависая на ней в бесконечном цикле, а в ходе выполнения основной программы. Для простого мигания это не критично, но лучше как можно реже использовать _ms_delay(), это тормозит основную программу.
olegue, проверяй нажатия не в цикле while, а в проверке if. Я вижу примерно следующий алгоритм:
Код:
переменная A = 0 бесконечный цикл {
если нажата кнопка{ подождать если кнопка всё ещё нажата {присвоить переменной A значение противоположное тому что в ней было} }
если переменная A разрешает мигание { включить порт подождать выключить порт } иначе { выключить порт } }
Но опять же повторюсь что не стоит применять в основном цикле задержки если они действительно не нужны
Карма: 14
Рейтинг сообщений: 115
Зарегистрирован: Сб май 21, 2016 11:04:52 Сообщений: 2957 Откуда: Беларусь
Рейтинг сообщения:0
да, кстати, я тоже нахожу довольно трудным управление сразу несколькими вложенными циклами. Хотя, возможно, это более правильный способ. Но удержать его в голове просто немыслимо пока.
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
olegue, функции и макросы могут помочь визуально сделать код более легко читаемым. Еще советую - почитайте про конечные автоматы. Очень часто на них реализуются в МК задачи.
Карма: 14
Рейтинг сообщений: 115
Зарегистрирован: Сб май 21, 2016 11:04:52 Сообщений: 2957 Откуда: Беларусь
Рейтинг сообщения:0
Вот что у меня получилось с миганеим светодиода Одно нажатие - включить мигание Второе нажатие - выключить мигание Привожу с коментами. Посмотртие. Учел нажатие и отпускание, как и советовали
Код:
#include <avr/io.h> #include <util/delay.h> int main(void) {
DDRB =(1<<PB0); // это будет выход, т.е на PB0 будет светодиод) PORTB=(1<<PB1); //(по аналогии с атмегой PB1=1 (подключен подтягивающий резистор),
1) моргать не будет... точнее будет, но это глазу не будет видно... нужно внутри цикла только одно переключение порта оставить. 2) при выходе из моргания светодиод стоит тушить принудительно т.к. если выйти при включенном светодиоде, то он так и останется гореть... 3) в целом для изучения неплохо, но для работы этот код подойдет только если мк кроме мигания ничего не делает - АЛУ всё время занят и ему некогда обрабатывать другие инструкции... если их ему подсовывать через прерывания, то будет немного сбиваться частота мигания светодиодом... (проблема тут в программных задержках делай_мс)
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
вот смотри: первая инструкция его (допустим) зажгет, потом ждем, потом гасим, тутже начинается новый виток цикла и светодиод зажигается снова... светодиод будет выключен около десяти тактов или (при тактовой 8 МГц) 1,25 мкс... (а включен 200мс - т.е. в 160000 раз дольше чем выключен...)
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
вот смотри: первая инструкция его (допустим) зажгет, потом ждем, потом гасим, тутже начинается новый виток цикла и светодиод зажигается снова... светодиод будет выключен около десяти тактов или (при тактовой 8 МГц) 1,25 мкс... (а включен 200мс - т.е. в 160000 раз дольше чем выключен...)
я пытаюсь понять, что Вы пояснили, но то что я вижу в Протеусе получается неправильно? В протеусе диод моргает, в железе не проверял, но теперь хочуется уже вшить этот код в тинку и посмотреть.
Кстати, смотрел Таймеры. Ну там конечно, на первых порах можно мозг сломать.
Мигание заметно только до 15Гц. 0,06 секунды на период и больше. И то... не всяким глазом... А ШПРОТ это все равно покажет. Лучше раз в пол секунды состояние менять для наглядности. 500 и более миллисекунд.
while (1) { PORTB^=(1<<PB0); _delay_ms(500); PORTB^=(1<<PB1); _delay_ms(500); // PORTB^=(1<<LED2); _delay_ms(500);
} }
должно моргать 2 ламоптчик попеременно, но моргает только последняя обьявленная-инициализированная строками DDRB и PORTB Что опять не так? Если PB1 убираю то тогда мограет pb0, если еще доБавляю pb2, то она моргает - первые 2 нет!
порт настроил неправильно у тебя последующая настройка затирает результат предыдущей надо так: ддр=((1<<порт0)|(1<<порт1)); или так ддр=1<<порт0; ддр|=1<<порт1;
Добавлено after 2 minutes 32 seconds: П.С.: ддр здесь взят для примера...
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Добавлено after 52 minutes 49 seconds: я разобрал вот этот код. Здесь работа с кнопками через програмные прерывания У меня он почему то не работает. Вероятно где -то ошибка ,но найти ее я немогу С моей точки здения вроде все правильно написано.
PORTB^=(1<<PB0); _delay_ms(500); - никогда так не пишите. В одну строчку. Сами потом запутаетесь. Поставили ; - перешли на новую строку. И отступы и форматирование научитесь делать правильно. Это только кажется, что мелочи, но с ними код намного читаемей. https://codebeautify.org/c-formatter-beautifier в помощь
Вот это - "while ( (PINB & (1<<BUTTON1)) == 0 || (PINB & (1<<BUTTON2)) == 0 ) {} // ждём отпускания кнопки" в прерывании не нужно уже. У вас входит в обработчик прерывания при смене состояния порта только. Поэтому ждать отпускания кнопки уже не нужно. И даже очень плохо, в прерывании так нельзя делать. Это хуже чем _delay_ms даже там.
Dimon456, зачем и где? Исходя из описание ручками его мало когда надо выставлять: When a logic change on any PCINT5:0 pin triggers an interrupt request, PCIF becomes set (one). If the I-bit in SREG and the PCIE bit in GIMSK are set (one), the MCU will jump to the corresponding Interrupt Vector. The flag is cleared when the interrupt routine is executed. Alternatively, the flag can be cleared by writing a logical one to it.
В протеусе код, указанный выше, на тини13 работает.
Карма: 14
Рейтинг сообщений: 115
Зарегистрирован: Сб май 21, 2016 11:04:52 Сообщений: 2957 Откуда: Беларусь
Рейтинг сообщения:0
NStorm писал(а):
В протеусе код, указанный выше, на тини13 работает.
т.е Вы у себя попробовали этот код? И все в порядке. Работает?
я тоже даже на 2-ом компьютере уже попробовал и нифига. Что за чертовщина Я даже попробовал упрощать его до минимума. Все равно ничего. Не могу добиться хоть какой-то работы на прерываниях Пробовал даже и на INTO настраивать - не получается запустить.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 66
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения