- Вложения
-
- 16 мега для китая.txt
- (8.3 КБ) 252 скачивания
Почему не работает опрос кнопки?
- Сообщения: 64
- Зарегистрирован: Чт июн 09, 2016 18:24:41
Я начинающий в этой области, с большим прошлым по простой электронике. Написал прогу для Меги16. Сбственно программа-то работает, хочется чтоб она запускалась по событию (нажатие кнопки- единица на PINB.3) "Этого как раз и не происходит (запуск).Работаю в CV первое что попалось в инете. Прошу не сильно пинать. Помогите понять причину ну или подправьте код. Подтяжка к VCC реализована внешне. На 4 ноге МЕГи 1\0 переключается, а программа не выходит из строки IF. Код IF.... взят из другого кода. Хотел написать в ветке "CV вопросы и ответы" а получилось здесь. Просьба к модераторам перенести в соотв. тему. Практика уже есть-несколько устройств уже собрал (АТмега8, АТмега 16), но нигде не получилось "увидеть " кнопку.
- Реклама
- Сообщения: 19495
- Зарегистрирован: Чт фев 20, 2014 18:57:55
Если вы хотите "быстро мигать" - уберите для начала весь остальной код, а то может оно и работает, но вы ждете чего то другого. Кнопку долго держали нажатой ? А то там у вас задержки нехилые, в момент которых кнопка, конечно, ничего не делает.
Последний раз редактировалось Morroc Пт июн 10, 2016 10:17:25, всего редактировалось 1 раз.
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
- Сообщения: 64
- Зарегистрирован: Чт июн 09, 2016 18:24:41
Нет, нет! Смысл как раз в остальном коде. Мигать это, так сказать, для визуализации где "застряла" прога. Держал долго по 2-5 секунд. А про какие задержки вы говорите?
Последний раз редактировалось Billi34 Пт июн 10, 2016 10:19:23, всего редактировалось 1 раз.
- Сообщения: 19495
- Зарегистрирован: Чт фев 20, 2014 18:57:55
Вот и убедитесь, что мигалка работает сама по себе 
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
- Сообщения: 64
- Зарегистрирован: Чт июн 09, 2016 18:24:41
Как сделать постоянный опрос кнопки и запуск по изменению состояния? Этот код я взял из примера. Там как раз описывалось нужное мне поведение, а не заработало. Скорее всего в примере нужено пере-включение (сброс) для прохода этого условия. А нет нажатия и прога будет здесь крутиться.
Последний раз редактировалось Billi34 Пт июн 10, 2016 10:28:08, всего редактировалось 1 раз.
- Реклама
- Сообщения: 804
- Зарегистрирован: Чт мар 12, 2009 16:31:05
- Сообщения: 64
- Зарегистрирован: Чт июн 09, 2016 18:24:41
Книга качается.
while(PINB.3==0)
{
} \\ видимо так, опрос будет в цикле, По изменению состояния -выход
while(PINB.3==0)
{
} \\ видимо так, опрос будет в цикле, По изменению состояния -выход
- Сообщения: 19495
- Зарегистрирован: Чт фев 20, 2014 18:57:55
да и ваш вариант вроде тоже должен работать, попробуйте кнопку подержать нажатой секунды 3
ищите пример сразу с антидребезгом, варианты без него в реальности работают черте как
ищите пример сразу с антидребезгом, варианты без него в реальности работают черте как
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
- Сообщения: 64
- Зарегистрирован: Чт июн 09, 2016 18:24:41
- Сообщения: 19495
- Зарегистрирован: Чт фев 20, 2014 18:57:55
Ну выходить он у вас и не должен, входить и мигать должен 
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
- Сообщения: 64
- Зарегистрирован: Чт июн 09, 2016 18:24:41
Код заработал.
while(1)
{
while(PINB.3==1)
{
}
/////////////здесь код
}
Я и раньше так пробовал, но почему-то не работало.
Спасибо, за участие.
Прошу модератора перенести мою тему в раздел о CV. Все должно быть на месте.
while(1)
{
while(PINB.3==1)
{
}
/////////////здесь код
}
Я и раньше так пробовал, но почему-то не работало.
Спасибо, за участие.
Прошу модератора перенести мою тему в раздел о CV. Все должно быть на месте.
- Сообщения: 19495
- Зарегистрирован: Чт фев 20, 2014 18:57:55
Бесконечные циклы так себе идея.
"Вся военная пропаганда, все крики, ложь и ненависть исходят от людей, которые на эту войну не пойдут !" / Джордж Оруэлл /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
"Война - это,когда за интересы других,гибнут совершенно безвинные люди." / Уинстон Черчилль /
Если нужна мгновенная реакция на кнопку - тут без внешнего интеррапта не обойтись.
Иногда мой питомец уходит в такую спячку, что разбудить его можно только щелчком по первой ноге...
- Сообщения: 1492
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Что за мода вешать кнопки на внешнее прерывание? Сам интерфейс человек-кнопка очень медленный для МК. Плюс обработка антидребезга. Время на подавление дребезга от 20 мс. Сам собой напрашивается вопрос, на куа вешать кнопки на внешнее прерывание? Да и вообще "мгновенно" реагировать на нажатие? Смысл?watchmaker писал(а):...
В общем случае Вы правы. Но если делать опрос не через внешнее прерывание, то в программе нужно реализовать механизм, когда по периодическому срабатыванию таймера выполняются какие-то действия - проверки состояния регистров и тому подобное. В этом случае, как говорится, сам бог велел тут же делать и опрос кнопок. Если же такого механизма в программе по какой-то причине не предусмотрено, то вариант опроса по прерыванию вполне имеет место быть.Demiurg писал(а):Что за мода вешать кнопки на внешнее прерывание?
По сути - чем плох опрос кнопок по прерыванию? Это может создать проблему только если внешние прерывания нужны для чего-то другого. А если они не используются ни для каких задач - почему б не "повесить" на них кнопки?
Конечно, есть еще третий вариант - опрашивать кнопки в бесконечном цикле только в те моменты, когда программа ожидает обязательного нажатия на какую-то из них, если при этом в программе есть только такой опрос кнопок - не постоянно, а в некоторые моменты.
Словом, вариантов опроса может быть много. И лучшего или худшего тут нет - все зависит от логики программы. Выбор же, как всегда, за программистом.
А совет в выборе способа опроса можно дать, если вопрос задан не отвлеченно - "как опросить кнопку", а вот так - "Логика работы программы такая-то, кнопки нужно опрашивать в такие-то моменты, свободные выводы контроллера такие-то. Как лучше реализовать?"
Последний раз редактировалось Alkul Сб июн 18, 2016 20:16:58, всего редактировалось 1 раз.
- Сообщения: 1525
- Зарегистрирован: Чт июн 10, 2010 20:11:19
Помимо таймера, можно проверять в бесконечном цикле, особенно хорошо если время каждого цикла более-менее одинаково.
Если вешать на прерывание, может возникнуть проблема с дребезгом.
Ну и в зависимости от алгоритма использование прерывания может быть наиболее удачным вариантом (пульт от телевизора, например).
Если вешать на прерывание, может возникнуть проблема с дребезгом.
Ну и в зависимости от алгоритма использование прерывания может быть наиболее удачным вариантом (пульт от телевизора, например).
Я делал опрос через прерывание. Никаких проблем с дребезгом не возникало.COKPOWEHEU писал(а):Если вешать на прерывание, может возникнуть проблема с дребезгом.
Реализовывал так: в программе через каждые 2мс вызывался обработчик прерывания таймера, который управлял динамической индикацией на 2 семисегментных индикатора. На этот же обработчик было "подвешено еще несколько функций и среди них - "антидребезговая" функция.
При нажатии на кнопку в обработчике внешнего прерывания первым делом запрещалось прерывание для этой кнопки, инициализировался счетчик, равный количеству 2-х миллисекундных "тиков" антидребезговой задержки, после чего выполнялся программный код собственно действия по нажатию этой кнопки и делался выход из обработчика.
Упомянутый выше счетчик антидребезговой задержки у меня был равен 0xB4 (180D), что при умножении на 0,002 давало 0,36 секунд задержки. В обработчике прерывания таймера каждые 2 мс этот счетчик декрементировался, при достижении нуля прерывание для данной кнопки снова разрешалось.
Таким образом, проблема дребезга решалась довольно просто и надежно. При удержании кнопки в нажатом состоянии действие, выполняемое при нажатии, повторялось каждые 0,36 с. Если подробнее, то там был параметр, изменяющийся от 0 до 99 и две кнопки - одна младший разряд, другая - старший. При нажатии на кнопку соответствующий разряд инкрементировался, при достижении максимального значения 9 следующее значение, соответственно, было 0 и так по циклу. Т.е., в наихудшем случае (например, при переходе от 22 к 11) для изменения параметра требовалось 18 нажатий - 9 на кнопку младшего разряда и 9 - на кнопку старшего разряда.
- Сообщения: 1492
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Цикл статей Татарчевского. В 8 части про опрос клавиатуры.
Спойлер
Код: Выделить всё
//==================
#include "kbd_drv.h"
//==================
//==================
static u08 keys_prev;
static u08 keys_curr;
static u08 keys_buf;
//==================
//==================
void scan_keys (void)
{
/*
keys_curr = 0;
if (Set_Is_Key_Esc_Pressed ()) keys_curr |= KEY_ESC_BIT;
if (Set_Is_Key_Enter_Pressed ()) keys_curr |= KEY_ENTER_BIT;
if (Set_Is_Key_Prev_Pressed ()) keys_curr |= KEY_PREV_BIT;
if (Set_Is_Key_Next_Pressed ()) keys_curr |= KEY_NEXT_BIT;
if (Set_Is_Key_Minus_Pressed ()) keys_curr |= KEY_MINUS_BIT;
if (Set_Is_Key_Plus_Pressed ()) keys_curr |= KEY_PLUS_BIT;
*/
// Можно и сразу работать с keys_curr, но при таком подходе
// экономится объем кода. Нет лишних команд lds, sts.
u08 a = 0;
if (Set_Is_Key_Esc_Pressed ()) a |= KEY_ESC_BIT;
if (Set_Is_Key_Enter_Pressed ()) a |= KEY_ENTER_BIT;
if (Set_Is_Key_Prev_Pressed ()) a |= KEY_PREV_BIT;
if (Set_Is_Key_Next_Pressed ()) a |= KEY_NEXT_BIT;
if (Set_Is_Key_Minus_Pressed ()) a |= KEY_MINUS_BIT;
if (Set_Is_Key_Plus_Pressed ()) a |= KEY_PLUS_BIT;
keys_curr = a; // Единственная команда sts в этой строке.
// Экономия в коде при максимальной оптимизации 44 байта.
}
//------------------------------------------------------------------------
struct tab_key_cod __flash tab_kbd_drv_keys_cod [] =
{
{KEY_ESC_BIT, KEY_ESC_COD},
{KEY_ENTER_BIT, KEY_ENTER_COD},
{KEY_PREV_BIT, KEY_PREV_COD},
{KEY_NEXT_BIT, KEY_NEXT_COD},
{KEY_MINUS_BIT, KEY_MINUS_COD},
{KEY_PLUS_BIT, KEY_PLUS_COD},
{0xFF, 0xFF},
};
//==================
//==================
void kbd_drv (void)
{
static u08 _kbd_drv;
static soft_timer ST_KBD;
scan_keys ();
switch (_kbd_drv)
{
case KBD_DRV_INIT:
keys_prev = 0xFF;
_kbd_drv = KBD_DRV_NONE;
break;
case KBD_DRV_NONE:
if (keys_curr)
{
keys_prev = keys_curr;
set_soft_timer (ST_KBD, DEBOUNCE_DELAY, 0);
_kbd_drv = KBD_DRV_DOWN;
}
break;
case KBD_DRV_DOWN:
if (handle_soft_timer (ST_KBD))
{
if (keys_curr && keys_prev == keys_curr)
{
if (define_key_cod (keys_curr, keys_buf, tab_kbd_drv_keys_cod))
Set_Event (EV_ID_KEY_PRESSED);
set_soft_timer (ST_KBD, HOLD_DELAY, REPEAT_DELAY);
_kbd_drv = KBD_DRV_HOLD; // KBD_DRV_WAIT_UP;
}
else
_kbd_drv = KBD_DRV_NONE;
}
break;
case KBD_DRV_HOLD:
case KBD_DRV_REPEAT:
if (!(keys_curr))
{
_kbd_drv = KBD_DRV_WAIT_UP;
return;
}
if (keys_prev != keys_curr)
{
_kbd_drv = KBD_DRV_NONE;
return;
}
if (handle_soft_timer (ST_KBD))
{
if (define_key_cod (keys_curr, keys_buf, tab_kbd_drv_keys_cod))
Set_Event (EV_ID_KEY_PRESSED);
_kbd_drv = KBD_DRV_REPEAT;
}
break;
case KBD_DRV_WAIT_UP:
if (!(keys_curr))
{
set_soft_timer (ST_KBD, DEBOUNCE_DELAY, 0);
_kbd_drv = KBD_DRV_UP;
}
break;
case KBD_DRV_UP:
if (handle_soft_timer (ST_KBD))
{
if (!(keys_curr))
{
_kbd_drv = KBD_DRV_NONE;
Set_Event (EV_ID_KEY_UNPRESSED);
}
else
_kbd_drv = KBD_DRV_WAIT_UP;
}
break;
default:
break;
}
}
//==================
//==================
u08 GetKeyCode (void)
{
return keys_buf;
}
void SetKeyCod (u08 key)
{
keys_buf = key;
}
//==================
- Сообщения: 64
- Зарегистрирован: Чт июн 09, 2016 18:24:41
Воспользуюсь советом уважаемого Alkul. Логика работы такая: проэкт указателя направления на перекрёстке. Сдвиг тактируется внешним сигналом на PIN.3 Мною был задан вопрос по опросу кнопки по причине не возможности смоделировать реальные условия работы устройства. По этому тактирующий сигнал был заменён кнопкой. Есть ещё одна ситуация : Приход нуля на PIN.4 запрещает сдвиг и вызывает повторение тактирующего сигнала всей полосой указателя (запрет движения). Тактирующий сигнал меандр 70 имп. в минуту. Сейчас загружу текст моих попыток. Хочется изящного решения, но к сожалению есть опыт извращённых решений . От анти дребезга я позже попробую избавиться. Что-то подсказывает что там нет дребезга. Ещё момент: тактирующий сигнал может исчезнуть в середине текста программы (после любого сдвига "стрелки" третьего, десятого ,двадцатого ) Для этого после каждого сдвига указателя прога снова проверяет PIN.3. Я позже ещё нарисую 2, 3 десятка "сдвигов". НО ход прогр. остановится до прихода нового PIN.3. А каждое новое указание надо-бы начать со строба( for(s=1;s<15;s++)Alkul писал(а):
А совет в выборе способа опроса можно дать, если вопрос задан не отвлеченно - "как опросить кнопку", а вот так - "Логика работы программы такая-то, кнопки нужно опрашивать в такие-то моменты, свободные выводы контроллера такие-то. Как лучше реализовать?"
{
PORTB=0b00,PORTD=0b00000000,PORTC=0b00000000,PORTA=0b00000001,delay_ms(20) ;
PORTB=0b11,PORTD=0b11111111,PORTC=0b11111111,PORTA=0b11111111,delay_ms(50) ;
}
То есть через небольшое время застоя возвращать текущий момент программы на первую строчку if (PINB.4==0,PINB.3==1)
Я пробовал оператор GO TO M1 но CV ругается на неизвестный синтаксис. Может какую библ. подгрузить?
if (PINB.4==0,PINB.3==1) \\Здесь проверяются 2 условия, каким образом зациклить программу на этом месте (я хотел попробовать GO TO, но не срослось) пока есть единица на PIN.3 (меандр) и ноль на PIN.4 (запрет движения) ногах?
В принципе можно и не "циклить". После каждого "сдвига" стрелки проверять снова if (PINB.4==0,PINB.3==1) ДА-зажигаем всю стрелку, НЕТ-сдвиг . В голове каша, что-то не допонимаю.
- Вложения
-
- Текущая программа .txt
- (47.57 КБ) 196 скачиваний
- Сообщения: 1492
- Зарегистрирован: Ср июн 25, 2008 15:19:44
Действительно каша. Лично я ничего не понял. Соберитесь с мыслями и грамотно распишите ТЗ. Не надо вашего псевдоязыка. Простыми русскими словами. Четко и ясно.Billi34 писал(а):В голове каша, что-то не допонимаю.


