Читая тему, хочу помощи от знатоков и совет для начинающих. Неоднократно повторялось на форуме о том что для отсчета пауз, временных интервалов и т.д. необходимо использовать таймеры. Приведу пример на фото . В данной задаче НЕДОПУСТИМО использования задержек и разных delay-ев, т.к. нарушается подсчет по опорной частоте. Суть в втом, что генерится опорная частота и по подсчетам которой дергаем ногами в двух портах. Начинается отсчет от синхроимпульса. На картинке видны настройки таймеров и работа в целом. Пока проект в протэусе, на днях буду пробовать в железе. Задействованы два таймера, 3-прерывания. Жду советов.
Качественное и безопасное устройство, работающее от аккумулятора, должно учитывать его физические и химические свойства, профили заряда и разряда, их изменение во времени и под влиянием различных условий, таких как температура и ток нагрузки. Мы расскажем о литий-ионных аккумуляторных батареях EVE и нескольких решениях от различных китайских компаний, рекомендуемых для разработок приложений с использованием этих АКБ. Представленные в статье китайские аналоги помогут заменить продукцию западных брендов с оптимизацией цены без потери качества.
voidB1_SUB(void) { if((PIND&(1<<6))==0)//на порте D6 висит кнопка, проверяем нажата ли __{ ____B1++;//инкремент переменной подсчета кол-ва периодов нажатия ____ if(B1==B1_N)//если продержали долгое время и переменная дошла до необходимого значения _____{ ______B1_PUSHED=1;//выставляем флаг нажатой кнопки ______MODE=1;//выполняем действие по нажатию кнопки (у меня 2 команды) ______MODE_CHGD=1; _____} __} else//если кнопка не нажата, очищаем переменную подсчета кол-ва периодов нажатия B1=0;
if(B1_PUSHED)//теперь проверяем флаг нажатой кнопки, он означает что была нажата кнопка и было выполнено действие по нажатию __{ ___B1=0;//если он установлен (кнопка была нажата и действие по нажатию уже было выполнено), очищаем переменную подсчета кол-ва периодов нажатия ___if(PIND&(1<<6))//теперь, если она уже отпущена ____{ _____B1_PUSHED=0;//очищаем флаг нажатой кнопки _____MODE=0;//и выполняем действие по отпусканию кнопки (у меня их 2) _____MODE_CHGD=1; ____} __} } //вставлять действия "по отпускании" и "по нажатию" по Вашему усмотрению, можно одно исключить //эта программа должна вызываться по таймеру либо в главном цикле вертеться //числоB1_Nрассчитывается исходя из максимального времени дребезга контактов,Tдр. //B1_N = Tдр.* Tвыз., время в одинаковых единицах. Tвыз. - период вызова функции.
ОФФ ТОПИК ДЛЯ АДМИНИСТРАЦИИ: СДЕЛАЙТЕ УЖЕ НОРМАЛЬНЫЕ ФОРМАТЫ ДЛЯ [code]. ТО ЧТО СЕЙЧАС НЕВОЗМОЖНО ЧИТАТЬ!!! З***ЛСЯ ФОРМАТИТЬ, ЧТОБЫ И КОМЕНТЫ ОТДЕЛИТЬ ОТ КОДА ЦВЕТОМ И ОСТАВИТЬ ТАБУЛЯЦИЮ.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Заголовок сообщения: Re: Обработка нажатия кнопки в AVR...
Добавлено: Пн янв 16, 2012 13:31:51
Поставщик валерьянки для Кота
Карма: 1
Рейтинг сообщений: 5
Зарегистрирован: Ср май 11, 2011 21:37:45 Сообщений: 1995 Откуда: Цветочный город
Рейтинг сообщения:0
я очень рекомендую сначала продумать логику работы программы, а затем кодить у вас вырисовывается примерно такой алгоритм: есть переменная, содержащая номер эффекта, есть какие-то кнопки, нажатие на которые изменяет эту переменную. вы в бесконечном цикле должны опрашивать кнопки и в зависимости от того, какая нажата, выполнять изменение переменной. теперь рассуждаем: опрос кнопок - это задача, которая имеет самостоятельную ценность, как бы независимость от остального - значит, судьба этой задачи быть в виде отдельной функции. анализ разных вариантов нажатых кнопок - это обычный оператор Си switch. значит, "ядро" вашей задачи выглядит так:
Код:
while(1){ // бесконечный цикл switch(get_key_pressed()){ // при помощи функции get_key_pressed получаем код нажатой кнопки case KEY_1: // увеличение переменной effect++; break; case KEY_2: // уменьшение переменной effect--; break; } }
теперь вам остается лишь продумать, как должна быть сделана функция получения кода нажатой кнопки, описать эти коды (KEY_1, KEY_2 и т.д.) и добавить сколько нужно вариантов в оператор switch.
программа получается читаемой, аккуратной, понятной и логичной, легко модифицируемой. сумеете?
_________________ битва с дураками проиграна, победители торжествуют. слава победителям!
сделать как вы сказали смогу, но вот у меня не получается поймать нажатие кнопки... вот сделал как сказал товарищ выше ...не реагирует (((
Код:
if (PIND & (1<<4)) { delay(50); effect++; if (effect >4) effect=0; };
я пытался поймать нажатие на кнопку PD4 на платке у меня кнопочки на ногах от PD0 до PD4 и светодиод на PB PD0 и PD3 - изменяют частоту моргания светодиода PD1 и PD2 - меняют скважность свечения PD4 - выбирает эффект (не гореть, гореть постоянно, моргать)
Заголовок сообщения: Re: Обработка нажатия кнопки в AVR...
Добавлено: Пн янв 16, 2012 14:44:55
Поставщик валерьянки для Кота
Карма: 1
Рейтинг сообщений: 5
Зарегистрирован: Ср май 11, 2011 21:37:45 Сообщений: 1995 Откуда: Цветочный город
Рейтинг сообщения:0
не можете поймать нажатие кнопки? поступайте, как я вам рассказывал итак, задача: есть порт МК, к которому на землю подключено до 8 кнопок. надо отловить их нажатия. как поступить? заранее настроить порт на ввод с встроенными подтяжками, тогда чтение порта с ненажатыми кнопками вернет единицы во всех разрядах байта, а если будет что-то нажато - в том месте будет ноль. кнопка может "дребезжать", т.е. некоторое время (10-25 мс) не иметь постоянного контакта - этого нужно избежать. как? опрашиваем порт, запоминаем результат. ждем 10-25 мс и снова опрашиваем порт, сравнивая результат с запомненным: если они совпали, значит, дребезг уже закончился (или не начинался) и считаны именно данны о нажатых кнопках. теперь, когда на словах разобрались с алгоритмом, опишем его на языке Си, вспоминая ранее данные рекомендации о кодах кнопок:
Код:
#define KEY_1 (1<<PB0) #define KEY_2 (1<<PB1) // и так далее хоть все 8 кнопок #define ANY_KEY (KEY_1 | KEY_2) /* тут надо перечислить все существующие кнопки, и не слушайте тех, кто скажет, что скобки лишние */ #define NO_KEY 0
// настройка порта на ввод с подтяжками - делается где-то в начале main() DDRB &= ~ANY_KEY; PORTB |= ANY_KEY;
// функция получения кода нажатых кнопок unsigned char get_key_pressed(void){ unsigned char key; key = ~(PINB & ANY_KEY); delay_ms(15); // задержка для подавления дребезга if(key == ~(PINB & ANY_KEY)) return key; else return NO_KEY; // если дребезг - вернем 0, что будет означать: не нажата ни одна кнопка }
разумеется, лучше кодам кнопок давать более осмысленные имена, например не KEY_1, а NEXT_EFFEKT_KEY и т.п. - это позволит получить более читабельную программу.
вопросы?
_________________ битва с дураками проиграна, победители торжествуют. слава победителям!
не можете поймать нажатие кнопки? поступайте, как я вам рассказывал итак, задача: есть порт МК, к которому на землю подключено до 8 кнопок. надо отловить их нажатия. как поступить? заранее настроить порт на ввод с встроенными подтяжками, тогда чтение порта с ненажатыми кнопками вернет единицы во всех разрядах байта, а если будет что-то нажато - в том месте будет ноль. кнопка может "дребезжать", т.е. некоторое время (10-25 мс) не иметь постоянного контакта - этого нужно избежать. как? опрашиваем порт, запоминаем результат. ждем 10-25 мс и снова опрашиваем порт, сравнивая результат с запомненным: если они совпали, значит, дребезг уже закончился (или не начинался) и считаны именно данны о нажатых кнопках. теперь, когда на словах разобрались с алгоритмом, опишем его на языке Си, вспоминая ранее данные рекомендации о кодах кнопок:
Код:
#define KEY_1 (1<<PB0) #define KEY_2 (1<<PB1) // и так далее хоть все 8 кнопок #define ANY_KEY (KEY_1 | KEY_2) /* тут надо перечислить все существующие кнопки, и не слушайте тех, кто скажет, что скобки лишние */ #define NO_KEY 0
// настройка порта на ввод с подтяжками - делается где-то в начале main() DDRB &= ~ANY_KEY; PORTB |= ANY_KEY;
// функция получения кода нажатых кнопок unsigned char get_key_pressed(void){ unsigned char key; key = ~(PINB & ANY_KEY); delay_ms(15); // задержка для подавления дребезга if(key == ~(PINB & ANY_KEY)) return key; else return NO_KEY; // если дребезг - вернем 0, что будет означать: не нажата ни одна кнопка }
разумеется, лучше кодам кнопок давать более осмысленные имена, например не KEY_1, а NEXT_EFFEKT_KEY и т.п. - это позволит получить более читабельную программу.
вопросы?
делаю как вы сказали ругается вот так ((( Error[Pe020]: identifier "PD0" is undefined D:\atmel\MK\proj\IAR2\main.c 40
а когда пишу #define KEY_1 (1<<PD,0) Error[Pe020]: identifier "PD" is undefined D:\atmel\MK\proj\IAR2\main.c 38
int interval = 200; int delitel = 5; int effect = 0;
void delay(long unsigned int Pause) { long int i; long int i2; i2=Pause*100;
for(i=0; i<i2; ++i ) asm("nop"); }
// функция получения кода нажатых кнопок unsigned char get_key_pressed(void) { unsigned char key; key = ~(PIND & ANY_KEY); delay(15); // задержка для подавления дребезга if(key == ~(PIND & ANY_KEY)) return key; else return NO_KEY; // если дребезг - вернем 0, что будет означать: не нажата ни одна кнопка }
int main( void ) { char del; int i;
PORTB = 0xFF; DDRB = 0xFF;
DDRD &= ~ANY_KEY; PORTD |= ANY_KEY;
while(1) { switch(get_key_pressed()) // при помощи функции get_key_pressed получаем код нажатой кнопки { case KEY_5: // след.эффект effect++; if (effect>3) effect = 0; break; }
switch(effect) { case 0: PORTB=0x00; break; case 1: PORTB=0xFF; break; case 2: PORTB=0xFF; del = 5 / delitel; i = interval * del ; delay(i); PORTB=0x00; i = interval * (1/del); delay(i); break; } } return 0; }
вместо #define KEY_1 (1<<PIND0) #define KEY_2 (1<<PIND1) #define KEY_3 (1<<PIND2) #define KEY_4 (1<<PIND3) #define KEY_5 (1<<PIND4) ставил #define KEY_1 (1<<PORTD0) #define KEY_2 (1<<PORTD1) #define KEY_3 (1<<PORTD2) #define KEY_4 (1<<PORTD3) #define KEY_5 (1<<PORTD4) все равно также
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 16
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения