0 / 0 / 0
Регистрация: 13.06.2013
Сообщений: 584
|
|
1 | |
while (!KEY){} // Пока нажата16.04.2015, 16:02. Показов 15137. Ответов 36
Метки нет (Все метки)
Здраствуйте, уже думал вырос из таких элементарных вещей.
Символ К дважды приходит, хотя должен 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
|
16.04.2015, 16:02 | |
Ответы с готовыми решениями:
36
STM32 Blue Pill, не могу заставить таймер заткнуться, пока нажата кнопка Пока нажата клавиша пока нажата кнопка. ! Пока нажата кнопка выполнять |
0 / 0 / 0
Регистрация: 21.11.2012
Сообщений: 1,400
|
|
17.04.2015, 00:16 | 21 |
У меня как минимум 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
В 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
Сообщение от sitirom366
Сообщение от sitirom366
Сообщение от sitirom366
0
|
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
|
|
18.04.2015, 01:52 | 35 |
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 | |
19.04.2015, 16:16 | |
Помогаю со студенческими работами здесь
37
Действие пока нажата кнопка Выполнение функции пока нажата UI кнопка Перекрасить кнопку пока она нажата Цикл повторяющийся пока не нажата клавиша Реле замкнуто пока нажата клавиша 'd' на ПК Движение пока нажата клавиша Delphi 7 Воспроизведение мелодии, пока кнопка нажата Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |