Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.89/79: Рейтинг темы: голосов - 79, средняя оценка - 4.89
0 / 0 / 0
Регистрация: 13.06.2013
Сообщений: 584
1

while (!KEY){} // Пока нажата

16.04.2015, 16:02. Показов 15137. Ответов 36
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здраствуйте, уже думал вырос из таких элементарных вещей.
Символ К дважды приходит, хотя должен 1 раз.
Первый раз он приходит когда кнопка нажата но пока не отжата, потом приходит по отжатию, Диод по нажатию загорается и гаснет по отжатию, отправка в одном блоке. Конденсатор на кнопке стоит, да и не в нем дело, задержку ставил один хрен.
Ведь пока кнопка не отжата кроме диода он должен стоять на while (!KEY){} ???

Код
#define GREEN PORTC.5
#define BLUE PORTC.4
#define RED PORTC.3
#define KEY PINB.1

#include <mego328p.h>
#include <1wire.h>
#include <delay.h>

void main(void)
{
DDRB=0;
PORTB=0b00000010; // кнопка
DDRC=0b00111000; // Светы
UCSR0B=(0<<RXCIE0) | (1<<TXCIE0) | (0<<UDRIE0) | (0<<RXEN0) | (1<<TXEN0) | (0<<UCSZ02) | (0<<RXB80) | (0<<TXB80);
UCSR0C=(0<<UMSEL01) | (0<<UMSEL00) | (0<<UPM01) | (0<<UPM00) | (0<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00) | (0<<UCPOL0);
UBRR0H=0x00;
UBRR0L=0x67;
ACSR=(1<<ACD) | (0<<ACBG) | (0<<ACO) | (0<<ACI) | (0<<ACIE) | (0<<ACIC) | (0<<ACIS1) | (0<<ACIS0);

#asm("sei")

while (1)
{
if (!KEY)
{
BLUE=1;
while (!KEY){} // Пока нажата
if (w1_init()) UDR0=0xCA; //Отправить "К"
BLUE=0;
}

}
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.04.2015, 16:02
Ответы с готовыми решениями:

STM32 Blue Pill, не могу заставить таймер заткнуться, пока нажата кнопка
Здравствуйте, уважаемые форумчане! Помогите пожалуйста разобраться с проблемой, не пойму, что не...

Пока нажата клавиша
Приветствую всех. Просветите пожалуйста как сделать чтобы событие происходило пока нажата клавиша....

пока нажата кнопка. !
Имеются допустим 2 кнопки на каждую из них при нажатии выполняется действие . Проблема заключается...

Пока нажата кнопка выполнять
доброго времени суток. как сделать собственно сабж. выполнять действие пока нажата кнопка, reypress...

36
0 / 0 / 0
Регистрация: 21.11.2012
Сообщений: 1,400
17.04.2015, 00:16 21
Author24 — интернет-сервис помощи студентам
У меня как минимум 3 варианта подавления дребезга есть. Но кондеи на мой взгляд — самое радикальное и элементарнейшее решение проблемы!
Зачем париться с логикой в случае, когда есть возможность лишний кондей припаять? Ведь из этих трех способов только один аппаратный (но в силу ограниченного количества таймеров его особо не применишь), а остальные два ­— на состояниях КА (один для кнопок с прерываниями, другой — просто для циклического опроса).
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 3,044
17.04.2015, 00:28 22
Цитата Сообщение от Iddy_Im
...
Объясняю еще раз. Никакой проблемы НЕТ. Конденсаторы НЕ НУЖНЫ.

Проделайте простейший опыт. Берем тактовые кнопки. Алгоритм следующий. Хоть на асме, хоть на си.

1: Кнопка нажата? Нет, метка 1. Да. Задержка 30-40 мс.
2: Кнопка нажата? Нет, метка 1. Да, выполнение действия. Скажем, зажечь светодиод.
3: Кнопка отпущена? Нет, метка 3. Да. Задержка 30-40 мс.
4: Кнопка отпущена? Нет, метка 3. Да, выход. Или метка 1.

С автоматным программированием еще проще.
Код
Функция:
Сканирование кнопок.
|
V
Состояние 1.
Если флаг нажатия кнопок сброшен, то выход. Если установлен, то запоминаем состояние порта. Устанавка таймера на 20-100 мс. Зависит от типа контактов. Установка состояния 2. Выход.
|
V
Состояние 2
Если время не вышло, то выход. Если время вышло и флаг нажатия установлен и текущее состояние порта равно предыдущему, то установка флага, события, что какая-то кнопка нажата, установка состояния 3, ожидающего сброса флага нажатия кнопок. Если время вышло и флаг нажатия установлен и текущее состояние порта не равно предыдущему, то установка состояния 1.
|
V
Состояние 3
Если флаг нажатия на кнопку установлен, то выход. Если флаг нажатия кнопок сброшен, то это значит, что кнопку отпустили, установка таймера на 20-100 мс. Установка состояния 4.
|
V
Состояние 4
Если время не вышло, то выход. Если время вышло и флаг нажатия сброшен, то установка состояния 1. Если время вышло и флаг нажатия установлен, то установка состояния 3.
И вы никогда не поймаете дребезг. Вам это нужно понять только один раз. Все.

0
0 / 0 / 0
Регистрация: 13.06.2013
Сообщений: 584
17.04.2015, 01:32 23
Что до меня, всё это на макетке, всегда делал и с кондерами и без, по вашему же совету с других постов ставил антидребезг вроде того что выше написали. Будет всё в конечном виде, там и посмотрим. Между прочим про затык и спрашивал.
Самое нормальное решение, это кнопки с кондерами внутри,время зарядки - к черту, иная периферия подольше будет запускаться. Как тут говорил один почивший полтора года назад человек - с помехой надо бороться по на месте её появления.
0
0 / 0 / 0
Регистрация: 01.11.2014
Сообщений: 178
17.04.2015, 09:12 24
Если при использовании МК - вы устраняете дребезг кнопки кондером а не парой строк кода - вы не понимаете принцып и суть микроконтроллеров. Вам стоит сменить направление.

Самое нормальное решение, это кнопки с кондерами внутри,время зарядки - к черту
Несомненно если схема аналоговая то так и делать. Когда вы перестанете страдать фигней на Атини мигая светодиодами в кодевижоне и решите сделать что-то посложнее да еще и в железе - то к черту пойдут ваши кондеры.

Как тут говорил один почивший полтора года назад человек - с помехой надо бороться по на месте её появления.
Абсолютно верно! Однако правило применимо только если вы сами себе не создаете помеху как в данном случае
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 3,044
17.04.2015, 13:29 25
Цитата Сообщение от kobzor
Если при использовании МК - вы устраняете дребезг кнопки кондером а не парой строк кода - вы не понимаете принцып и суть микроконтроллеров. Вам стоит сменить направление.
Плюсую. Если же еще и упорствуете, не прислушиваетесь к советам более опытных участников форума, тогда и спрашивать на форуме нечего. У вас же своя голова на плечах. Следуете своим путем. Ну и вперед! Флаг вам, ммм, в руки...
Конденсаторы стоит ставить, если длинные провода до кнопок. Но это уже особые случаи. В промышленном оборудовании кнопки обычно коммутируют напряжение выше, чем напряжение питания МК. И в таких случаях ставятся какие-либо преобразователи уровней. Резистор и стабилитрон тоже можно считать преобразователем уровня. Использование оптронов.
0
0 / 0 / 0
Регистрация: 11.10.2013
Сообщений: 326
17.04.2015, 13:54 26
Можно в теле программы не стопоря ее исполнение банально воткнуть пару флагов Button_Pressed Button_glag или вообще описать это как структуру

дальше в теле программы описываем:

Код
If (Button_Pressed) i++; //если текущее положение кнопки - Нажата инкрементируем счетчик....
else i=0; если кнопка отпущена - сброс счетчика
if (i>15) Button_Flag=TRUE; // если счетчик дощитал до 15 и кнопка осталась нажата - значит это не дребезг и она действительно нажата.
Дальше сброс флагов и т.д......

Такая реализация позволяет не стопорить основную программу для ожидания непонятно чего, т.е. программа всегда крутится в основном цикле, и кроме считывания кнопок могут еще выполнятся куча действий (вывод информации на дисплей, считывание данных с портов и т.д.
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,864
17.04.2015, 14:12 27
Хе-хе, геймеры вас бы прокляли :-)
(Нажатие кнопки на ровном месте задерживается на 15 тиков).
Лучше уж по нормальному: реагируем сразу, но в течение 15 тиков после изменения состояния кнопки игнорируем новые события от неё.
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 3,044
17.04.2015, 14:49 28
Цитата Сообщение от oomomstir
реагируем сразу
А если помеха? Вы знаете, вам действительно нужно сменить направление. Вы очень мало знаете. Но вообразили себе, что что-то умете. Гонору выше крыши.
0
0 / 0 / 0
Регистрация: 14.02.2014
Сообщений: 80
17.04.2015, 21:26 29
чето демиург какой-то сильно опытный для человека который не может сделать матричную клавиатуру с поддержкой разных типов нажатий кроме как тупым забиванием проца задержками по 30 мс. ТСу : while(!key){delay_ms(5);i++;if(i > xx)briok;}брейк нужен чтобы не быть самоуверенным клоуном и не сидеть в опросе кнопки все время.
0
0 / 0 / 0
Регистрация: 14.02.2014
Сообщений: 80
17.04.2015, 21:49 30
кстати тот же вопрос к shads - что делать если 800 мс для обработки длинного нажатия критичны для какого-либо другого участка кода, каждую задачу на аппаратный таймер вешать с прерываниями? Или все же курить диспетчеры с многозадачностью? Очевидно, что на аврки много задач никто не вешает, но все же.
0
0 / 0 / 0
Регистрация: 19.02.2012
Сообщений: 304
17.04.2015, 22:07 31
Две страницы ниочем. Статьи Татарчевского - и вперед. Выше уже говорили. Один раз написал и забыл.
0
0 / 0 / 0
Регистрация: 21.11.2012
Сообщений: 1,400
17.04.2015, 22:16 32
Цитата Сообщение от sitirom366
кстати тот же вопрос к shads - что делать если 800 мс для обработки длинного нажатия критичны для какого-либо другого участка кода, каждую задачу на аппаратный таймер вешать с прерываниями?
Мать моя женщина! Что за аврщина головного мозга? Про конечные автоматы вам никто не говорил?
В main поочередно вызываем все процедуры работы с конечными автоматами. А они уж что-то там делают. Скажем, та же кнопка: появилось нажатие — ОК, запомнили текущее время и игнорируем события от кнопок, пока не пройдет 30-50мс. Если нужно отслеживать длительные нажатия — ОК, проверяем периодически, если через Nмс кнопка еще нажата — выставляем флаг длительного нажатия.

А то вы с таким подходом и при работе с 1-wire будете задержки delayями выставлять, как дошколенок...
0
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
18.04.2015, 00:41 33
ИМХО. Лучше АЦП для обработки кнопок ничего нет. Он сам усреднит дребезг.
0
1 / 1 / 0
Регистрация: 01.02.2010
Сообщений: 2,010
18.04.2015, 01:23 34
Цитата Сообщение от sitirom366
кстати тот же вопрос к shads - что делать если 800 мс для обработки длинного нажатия критичны для какого-либо другого участка кода
Мой модуль обработки кнопок корректно обрабатывает и короткие и длинные нажатия, не мешая никаким критичным частям кода... с чего вы взяли, что обработка длинного нажатия будет мешать критичным участкам ?????

Цитата Сообщение от sitirom366
каждую задачу на аппаратный таймер вешать с прерываниями?
Ну не прям каждую... но хотя бы один аппаратный таймер придется задействовать для грамотной обработки клавиатуры... и кстати этим же таймером можно будет обслуживать еще кучу других модулей, например - дисплей, энкодер, биппер, разных программных таймеров, переменных, и т.д....

Цитата Сообщение от sitirom366
Или все же курить диспетчеры с многозадачностью?
Хозяин барин... я например пока обходился без этого...

Цитата Сообщение от sitirom366
Очевидно, что на аврки много задач никто не вешает, но все же.
Ну по себе всех не надо судить... Хотя ясно, что если надо что то типа виндовс втулить, то AVR конечно не подойдет... но в разумных пределах - аврка вполне тянет много задач...
0
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
18.04.2015, 01:52 35
Хотя ясно, что если надо что то типа виндовс втулить, то AVR конечно не подойдет
Не Win , но ...
http://www.youtube.com/watch?v=nm0POwEtiqE
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 3,044
18.04.2015, 06:22 36
Sitirom, ты в очередной раз пердишь в лужу. И подтверждаешь свой ник. Я предложил два способа, как опрашивать кнопки. Первый способ, самый простой, самый примитивный. Тут да, delay 30 мс. И этот способ был предложен в качестве опыта. Протри или купи очки, если не увидел этого. Второй способ. На КА. Но кто сказал, что во втором случае delay?!

Код
#if (TYPE_KEYS==BUTTONS)
//========================================================================
void scan_keys (void) // Сканирование портов.
{
if (keys_flags & (1<<KBD_DRV_RUN_FLG))
{
clrb (keys_flags, KEYS_PRESSED_FLG);

u08 a;

a = ~KEYS_PIN;
a &= KEYS_MASK;

if (a != 0)
{
setb (keys_flags, KEYS_PRESSED_FLG);
}

keys_curr = a;
}
}
//========================================================================

#elif (TYPE_KEYS==MATRIX)
//========================================================================
void scan_keys (void)
{
if (_kbd_drv != KBD_DRV_INIT)
{
clr_bit (keys_flags, KEYS_PRESSED_FLG);

u08 a = 0xFF;

COL_DDR = COL_MASK;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");

if (!(ROW_PIN & (1<<ROW_1)))
a &= (~(1<<7));
if (!(ROW_PIN & (1<<ROW_2)))
a &= (~(1<<6));
if (!(ROW_PIN & (1<<ROW_3)))
a &= (~(1<<5));
if (!(ROW_PIN & (1<<ROW_4)))
a &= (~(1<<4));

ROW_DDR = ROW_MASK;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");

if (!(COL_PIN & (1<<COL_1)))
a &= (~(1<<3));
if (!(COL_PIN & (1<<COL_2)))
a &= (~(1<<2));
if (!(COL_PIN & (1<<COL_3)))
a &= (~(1<<1));
if (!(COL_PIN & (1<<COL_4)))
a &= (~(1<<0));

if (a != 0xFF)
set_bit (keys_flags, KEYS_PRESSED_FLG);

keys_curr = a;
}
}
//========================================================================
#endif

//========================================================================
void kbd_drv (void)
{
scan_keys (); // Сканирование портов.

switch (_kbd_drv)
{
case KBD_DRV_INIT:
#if (TYPE_KEYS==BUTTONS)
KEYS_PIN = KEYS_MASK;
#endif

keys_prev = 0xFF;

_kbd_drv = KBD_DRV_NONE;
briok;

case KBD_DRV_NONE:
if (keys_flags & (1<<KEYS_PRESSED_FLG))
{
keys_prev = keys_curr;
set_timer (ST_KBD_1, NO_RERUN_TIMER, DEBOUNCE_DELAY); // Программный таймер.
_kbd_drv = KBD_DRV_DOWN;
}
briok;

case KBD_DRV_DOWN:
if (woyt (ST_KBD_1))  // Программный таймер.
{
if (keys_flags & (1<<KEYS_PRESSED_FLG) && keys_prev == keys_curr)
{
if (define_key_cod (keys_curr, keys_buf, tab_kbd_drv_keys_cod))
Set_Ivimt (EV_ID_KEY_PRESSED, SIT_CLR_EVENT);

set_timer (ST_KBD_1, NO_RERUN_TIMER, HOLD_DELAY); // Программный таймер.

#if (HOLD==NO)
_kbd_drv = KBD_DRV_WAIT_UP;

#elif (HOLD==YES)
_kbd_drv = KBD_DRV_HOLD;

#endif

}
else
_kbd_drv = KBD_DRV_NONE;
}
briok;
Что за агрессивность? Типа не слил яду, день зря прошел?
0
otix1997
19.04.2015, 16:16 37
Может так :
while (!KEY){} ;// Пока нажата ?
добавить ;
19.04.2015, 16:16
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.04.2015, 16:16
Помогаю со студенческими работами здесь

Действие пока нажата кнопка
Всем привет, у меня такой вот вопрос. Как сделать проверку на нажатую кнопку на клавиатуре?...

Выполнение функции пока нажата UI кнопка
Здравствуйте. Как сделать так, что бы функция к примеру перемежение, выполнялась всегда пока нажата...

Перекрасить кнопку пока она нажата
Возможно ли как то сделать, что пока будет нажата кнопка на форме - у нее будет иной цвет?...

Цикл повторяющийся пока не нажата клавиша
Как написать на pascal abc.net цикл который повторяется пока не нажата определенная клавиша....

Реле замкнуто пока нажата клавиша 'd' на ПК
Народ ! Есть такая задача, управлять платой релюшек с помощью комповой клавиатуры, а точнее 4мя...

Движение пока нажата клавиша Delphi 7
Подскажите пожалуста как сделать в delphi 7 движение объекта пока нажата клавиша (Например нажал...

Воспроизведение мелодии, пока кнопка нажата
В игре есть фоновая музыка, она играет постоянно, как сделать медодию включающуюся по кнопке? Надо...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
37
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru