Здравствуйте, помогите пожалуйста разобраться с задержкой, пишу прогу для тини13, у меня две кнопки пин3 и пин4 и один выход порт 0. Нужно при нажатом пин3 горит светодиод на порту0 а при отпускании гаснет, следующий алгоритм при нажатом пине3 нажимаем пин4 и светодиод на порту 0 через 20сек должен погаснуть, использовал функцию иф и вайл задержку ставил в вайл но она работает ка при нажатии и при отпускании пин4 а надо только при нажатии,
как поставить задержку выключения светодиода на порте 0 при нажатой кнопке пин4 а при отпускании он должен снова сразу включиться т,к, пин 3 кнопка нажата постоянно а она отвечает за порт 0 (нажата то =лог-1 если нет то лог-0), сам не могу осилить уже пять дней мучаюсь, я файл атмел студио прикрепил!
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
открой свой атмел студио, скопируй свой код оттуда, здесь в редакторе его вставь, только не забуь завернуть в теги "код" и "спойлер" тогда коты хотя-бы смогут тебе помочь...
Добавлено after 5 minutes 50 seconds: хотя, если честно, ответ NStormа мне понравился...
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Добавлено after 6 minutes 11 seconds: Вы меня извините, но я только начал во всем этом разбираться и как тут правильно просить о помощи еще не знаю! По этому коду пин 4 гасит сразу порт 0 а при отпускании пина 4 через 2 сек зажигает а надо наоборот!
Добавлено after 1 minute 16 seconds: Пин 4 нажимаю только тогда когда зажат пин3
Карма: 20
Рейтинг сообщений: 188
Зарегистрирован: Вс мар 28, 2010 12:52:22 Сообщений: 1368 Откуда: Беларусь
Рейтинг сообщения:0
Цитата:
как поставить задержку выключения светодиода на порте 0 при нажатой кнопке пин4 а при отпускании он должен снова сразу включиться т,к, пин 3 кнопка нажата постоянно а она отвечает за порт
Спойлерif(!((PORTB & (1<<PB3)) && (PORTB & (1<<PB4)))) // проверка на нажатие двух кнопок { unsigned int count = 1000; // us delay - количество микросекунд задержки while(count) { delay_us(1); if(1<<PB4) // как только отпущена - включим светодиод { PORTB |=(1<<PB0); count=1; // и установим счетчик для выхода из задержки } count--; // или тупо ждем в цикле положенное время } } код не отлаживал, писал прямо тут, поэтому за мелкие баги прошу прощения
_________________ «Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
Т.е нажимаю на кнопку, загорается диод, нажимаю еще раз - диод гаснет. Все.
С зажиганеим диодом я разобрался. А вот с кнопками нет.
Я взял ПРОТЕУС 8.5 и загрузил туда этого код для Атмеги8 что бы проверить его, а затем переложить на Тиньку13
Код:
#include <avr/io.h> #include <util/delay.h> int main(void) { DDRD = 0x00; // Порт D вход PORTD = 0xFF; // Подключаем подтягивающие резисторы DDRB = 0xFF; // Порт B выход PORTB = 0x00; // Лог. 0 на выходе while(1) { while ((PIND&(1 << PD0)) == 1){} // Ждем пока на выводе PDO лог. 1 _delay_ms(200); // Задержка 200мс if ((PINB&(1 << PB0)) == 0) // Если на выводе PB0 лог. 0 { PORTB |= (1 << PB0); // Лог. 1 на выводе PB0 } else { PORTB &= ~(1 << PB0); // Лог. 0 на выводе PB0 } while ((PIND&(1 << PD0)) == 0){} // Ждем пока на выводе PDO лог. 0 _delay_ms(200); // Задержка 200мс } }
Добавлено after 25 minutes 26 seconds: Я начал перекладывать код на Тинку, с сохранением логики Самое главное это отличие в портах
это код из Атмега 8 DDRD = 0x00; // Порт D вход PORTD = 0xFF; // Подключаем подтягивающие резисторы DDRB = 0xFF; // Порт B выход PORTB = 0x00; // Лог. 0 на выходе
У меня на тиньке столько портов нету поэтому все приходится делать на порте PORTB к PB0 я подключу светодиод через резистор 220 ом и сделаю этот порт выходом к PB1 я подключу кнопку сразу на массу и сделаю этот порт входом
DDRB = 0x00000001 (последний бит установил в единицу - это будет выход, т.е на PB0 будет светодиод) PORTB= 0x11111110 (по аналогии с атмегой PB1=1 (подключен подтягивающий резистор), а PB0 - установлен логический 0 на входе)
Теперь там где ((PIND&(1 << PD0)) == 1) меняю на PINB и PB1
те. вот так
Код:
#include <avr/io.h> #include <util/delay.h> int main(void) { //DDRD = 0x00; // Порт D вход //PORTD = 0xFF; // Подключаем подтягивающие резисторы //DDRB = 0xFF; // Порт B выход //PORTB = 0x00; // Лог. 0 на выходе
DDRB = 0x00000001; //(последний бит установил в единицу - это будет выход, т.е на PB0 будет светодиод) PORTB= 0x11111110; //(по аналогии с атмегой PB1=1 (подключен подтягивающий резистор), а PB0 - установлен логический 0 на входе)
while(1) { while ((PINB&(1 << PB1)) == 1){} // Ждем пока на выводе PDO лог. 1 _delay_ms(200); // Задержка 200мс if ((PINB&(1 << PB0)) == 0) // Если на выводе PB0 лог. 0 { PORTB |= (1 << PB0); // Лог. 1 на выводе PB0 } else { PORTB &= ~(1 << PB0); // Лог. 0 на выводе PB0 } while ((PINB&(1 << PB1)) == 0){} // Ждем пока на выводе PDO лог. 0 _delay_ms(200); // Задержка 200мс } }
Ошибки компилятор не дает, но именно на цикле while не сработки. Цикл while (ожидание нажатие) просто пролетает до следующий строки
Что у меня тут не так?
Добавлено after 23 minutes 52 seconds: т. е сейчас так: я нажимаю на кнопку - начинается миганием светодиода, нажимаю другой раз и третий и тд мигание продолжается. Должно быть: нажал - светодиод вспыхнул, нажал еще раз - погас.
Сейчас задержка которая для устранения дребезга фактически является причиной мигания светодиода. Непонятненько.
Не надо магических цифр. Особенно писать в биты регистра, которые помечены как read-only. Не надо сравнивать с 1 результат AND (&). 1<<PB1 равно 2, а никак не 1. А в исходном работало, потому что там были PD0/PB0, которые = 1. Но это изначально убогий код был.
Код:
#include <avr/io.h> #include <util/delay.h>
int main(void) { //DDRD = 0x00; // Порт D вход //PORTD = 0xFF; // Подключаем подтягивающие резисторы //DDRB = 0xFF; // Порт B выход //PORTB = 0x00; // Лог. 0 на выходе
DDRB = (1 << PB0); //(последний бит установил в единицу - это будет выход, т.е на PB0 будет светодиод) PORTB= (1 << PB1); //(по аналогии с атмегой PB1=1 (подключен подтягивающий резистор), а PB0 - установлен логический 0 на входе)
while(1) { while ((PINB&(1 << PB1))); // Ждем пока на выводе PDO лог. 1 _delay_ms(200); // Задержка 200мс if ((PINB&(1 << PB0)) == 0) // Если на выводе PB0 лог. 0 { PORTB |= (1 << PB0); // Лог. 1 на выводе PB0 } else { PORTB &= ~(1 << PB0); // Лог. 0 на выводе PB0 } while (!(PINB&(1 << PB1))); // Ждем пока на выводе PDO лог. 0 _delay_ms(200); // Задержка 200мс } }
PS: Чисто для этого тинька не нужна, это обычный триггер.
а что вы здесь имели ввиду. Биты pb6 и pb7, которым ног не досталось?
Вроде того. Только таких бит нет. В ДШ загляните, там написано что их просто нет, они RESERVED и только для чтения. Проблема была не в этом, но в целом подобного надо избегать. Где-нибудь, в другом месте, на другом МК это можно вызвать проблему.
Не надо сравнивать с 1 результат AND (&). 1<<PB1 равно 2, а никак не 1
здесь тоже не понял, если честно
((PIND&(1 << PD0)) == 1) - конструкция плохая. Нельзя так писать. Потому что в случае с ((PIND&(1 << PD1)) == 1) - она уже никогда не будет равна 1. Она будет равна 0 или 2. Поэтому нет смысла сравнивать с цифрой. Просто if/while ([!](PIND&(1 << PD0))) - если 0, оно и так НЕТ, если отличное от нуля, оно ДА. На пальцах - 1 << PD1 = 0b00000010, это понятно? Потому что PD1 = 1, но сдвинув 1 на 1 позицию влево получаем 2. Операция лог. И (&) с PIND в данном случае ну никак не может дать нам 1. Если на PD1 высокий уровень, в PIND будет 0bxxxxxx1x, где x - любое значение. В этом случае PIND & (1 << PD1) будет равен тому же 0b00000010 = 2. Надеюсь понятно, такие вещи тыщу раз уже описаны везде.
Нет, в данном случае они не обязательны (разве что если нет желания экономить энергию и переводить МК в сон), см. выше.
EDIT: Ну и плюс вместо всего этого:
Код:
if ((PINB&(1 << PB0)) == 0) // Если на выводе PB0 лог. 0 { PORTB |= (1 << PB0); // Лог. 1 на выводе PB0 } else { PORTB &= ~(1 << PB0); // Лог. 0 на выводе PB0 }
Пишется просто PORTB ^= (1 << PB0);
Ну и форматировании я молчу )
Добавлено after 9 minutes 53 seconds: В итоге хотя бы так должен выглядеть этот код:
Код:
#include <avr/io.h> #include <util/delay.h>
int main(void) { DDRB = (1 << PB0); //(последний бит установил в единицу - это будет выход, т.е на PB0 будет светодиод) PORTB = (1 << PB1); //(по аналогии с атмегой PB1=1 (подключен подтягивающий резистор), а PB0 - установлен логический 0 на входе)
while (1) { while ((PINB & (1 << PB1))); // Ждем пока на выводе PB1 лог. 1 _delay_ms(200); // Задержка 200мс PORTB ^= (1 << PB0); while (!(PINB & (1 << PB1))); // Ждем пока на выводе PB1 лог. 0 _delay_ms(200); // Задержка 200мс } }
Только в реално железе скорее всего не помешают еще и внешние подтяжки посильнее, чем в аврке.
Карма: 14
Рейтинг сообщений: 115
Зарегистрирован: Сб май 21, 2016 11:04:52 Сообщений: 2957 Откуда: Беларусь
Рейтинг сообщения:0
NStorm писал(а):
Пишется просто PORTB ^= (1 << PB0);
ну это вообще хит.
Добавлено after 36 seconds: Не сегодня думаю хватит открытий.
Добавлено after 1 minute 31 second: Счас думаю, как включить мигание и выключить мигание. Только дайте мне сначала самому подумать.
Добавлено after 1 hour 29 minutes 40 seconds: Максимум что удалось придумать это включение мигания, Выключение не получается. Не знаю как из цикла мигания выйти
захожу в цикл мигания
while (1){ PORTB ^= (1 << PB0); _delay_ms(200); }
Код:
while(1) { while ((PINB&(1 << PB1))){} // Ждем пока на выводе PDO лог. 1 (Жднем нажатия) _delay_ms(200); // Задержка 200мс
while (1){ PORTB ^= (1 << PB0); _delay_ms(200); }
while ((PINB&(1 << PB1))) {} _delay_ms(200); // Задержка 200мс }
olegue, варианты на выбор для размышления: 1. Прерывание на кнопку для "выхода из цикла". Она как раз на INT0 висит. 2. Таймер вместо delay. 3. Проверка кнопки в цикле мигания, выход по нажатию. Чтобы снизить время реакции, можно ждать "шагами":
Код:
while (1){ uint8_t i = 0, btn_flag = 0; PORTB ^= (1 << PB0); while (i <= 10) { i++; _delay_ms(20); if (!((PINB & (1 << PB1)))) { btn_flag = 1; PORTB &= ~(1 << PB0); break; } } if (btn_flag) break; }
Не супер точно 200 мс будет, потому что на i++ и if будут такты расходоваться, но думаю не принципиально в данном случае. Если принципиально, то это вар. 1 и 2.
olegue, если не секрет, ты пишешь эту программу для того что-бы разобраться с МК или для практической задачи? Если второе, то тебе для включения\выключения достаточно взять к561тм2 или её аналог и с минимум обвеса добиться результата. Для мигания просто добавить генератор на к561ла7 например. А если хочешь разобраться с МК, то предусмотри или в коде или аппаратное подавление дребезга от кнопки.
Карма: 14
Рейтинг сообщений: 115
Зарегистрирован: Сб май 21, 2016 11:04:52 Сообщений: 2957 Откуда: Беларусь
Рейтинг сообщения:0
radteh писал(а):
если не секрет, ты пишешь эту программу для того что-бы разобраться с МК или для практической задачи?
какие уж тут секреты. Хочу разобраться с МК. И если дело пойдет, но наверняка гдето в далеке может замаячить что-то практическое. Но, вот на данном уровне мигания диодов говорить об этом сильно преждевременно. Пару дней вожусь, вижу,ч то элементарные, казалось бы задачи уже вызывают затруднения Допустим, что бы просто зажечь диоды, тут с помощью интернета, кое как получилсь А с кнопкой вообще беда. Тут еще и дребез нужно учитывать
с помощью NStorm продвинулся может на месяц вперед. Вот пример, казалось бы, на мой розум, должно все работать как надо
Вот код, в нем я жду нажатия кнопки.
Код:
while ((PINB & (1 << PB1))){};
Кнопка нажата, т.е PB стало 0, я вхожу в следующий цикл, где мигаю диодом, пока не нажму кнопку
Код:
while ((PINB & (1 << PB1))){ PORTB^=(1<<PB0); _ms_delay(200); };
После нажатия я должне опять перейти к строке первого цикла ожидания нажатия, но этого не происходит.
Добавлено after 2 minutes 4 seconds:
Код:
while(1) { while ((PINB&(1 << PB1))){} // Ждем пока на выводе PDO лог. 1 (Жднем нажатия) _delay_ms(200); // Задержка 200мс
while ((PINB&(1 << PB1))){ /// Вот в этом цикле, как я полагаю должно быть мигание, которое выключится по нажатию кнопки.
PORTB ^= (1 << PB0); _delay_ms(200); }
}
вот полный код.
Добавлено after 1 minute 56 seconds: т.е мигания нет. Происходит просто включения и выключения светодиода.
Добавлено after 11 minutes 43 seconds: Такое впечатление, что этот цикл не крутиться
Код:
while ((PINB & (1 << PB1))){ PORTB^=(1<<PB0); _ms_delay(200); };
Ежли охота Си освоить - то тинька 13я не самое лучшее из имеющегося. Другое дело - на чистом ассемблере в АВР студии 4.19 - там и симулятор работает и места будет в достатке, и понятнее на уровне "железа".
а что должно это делать? это генератор случайного состояния? пока кнопка нажата у тебя по очереди быстро быстро проверяются оба условия, какой из циклов будет исполняться при отпускании кнопки - воля случая... если хочешь стабильности, между циклами ожидающими отпускания кнопки вставь циклы, ожидающие нажатия... пока(1){ пока (нажата){}; немного ждем; // антидребезг пока (отпущена){}; немного ждем; пока (нажата){}; немного ждем; пока (отпущена){мигаем;}; гасим светодиод; немного ждем; } примерно так...
_________________ Просто не учи физику в школе, и вся твоя жизнь будет наполнена чудесами и волшебством Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Сейчас этот форум просматривают: Kolin и гости: 45
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения