Читая тему, хочу помощи от знатоков и совет для начинающих. Неоднократно повторялось на форуме о том что для отсчета пауз, временных интервалов и т.д. необходимо использовать таймеры. Приведу пример на фото . В данной задаче НЕДОПУСТИМО использования задержек и разных delay-ев, т.к. нарушается подсчет по опорной частоте. Суть в втом, что генерится опорная частота и по подсчетам которой дергаем ногами в двух портах. Начинается отсчет от синхроимпульса. На картинке видны настройки таймеров и работа в целом. Пока проект в протэусе, на днях буду пробовать в железе. Задействованы два таймера, 3-прерывания. Жду советов.
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]. ТО ЧТО СЕЙЧАС НЕВОЗМОЖНО ЧИТАТЬ!!! З***ЛСЯ ФОРМАТИТЬ, ЧТОБЫ И КОМЕНТЫ ОТДЕЛИТЬ ОТ КОДА ЦВЕТОМ И ОСТАВИТЬ ТАБУЛЯЦИЮ.
Заголовок сообщения: 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) все равно также
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения