Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.73/122: Рейтинг темы: голосов - 122, средняя оценка - 4.73
z-z
169 / 168 / 56
Регистрация: 22.06.2011
Сообщений: 980
1

обработка нажатия пользовательской кнопки

25.06.2012, 21:47. Просмотров 22002. Ответов 34
Метки нет (Все метки)

написал, чтобы при нажатии кнопки менялось состояние диодов. но что то не стабильно он работает. иногда надо нажимать 5-6 раз, чтобы переключить состояние. хотя иногда переклчается сразу. в чем может быть проблема?

Код
   unsykned int control;
control = 1;

while(1)
{
if((GPIOA->IDR&0x01)==1) //нажатие кнопки
{
control = control << 1;
if (control>2) control = 1;
}
if(control == 1)
{
GPIOC->BSRR = GPIO_BSRR_BS9;
GPIOC->BSRR = GPIO_BSRR_BR8;
}
if(control == 2)
{
GPIOC->BSRR = GPIO_BSRR_BS8;
GPIOC->BSRR = GPIO_BSRR_BR9;
}

}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.06.2012, 21:47
Ответы с готовыми решениями:

Обработка нажатия кнопки
Есть кнопка без фиксатора( нажали отпустили и она разомкнулась) Как обработать...

Обработка нажатия кнопки...
Есть программа для AVR, имитирует работу светофора, написана с Code Vision AVR....

Обработка тактовой кнопки
Вобщем решил поднять тему обработки тактовых кнопок. Какое самое лучшее...

Загрузка пользовательской прошивки "на лету"
Привет. Есть Keil, stm32f4 и две прошивки - основная и пользовательская....

Обработка нажатия кнопки
Добрый день! Уже довольно долго не могу разобраться со следующей задачей: У...

34
oordvork
0 / 0 / 0
Регистрация: 24.06.2012
Сообщений: 9
29.06.2012, 23:12 21
Цитата Сообщение от z-z
а как тогда событие нажатия отследить?
Ну, как-то так (одновременно и с дребезгом поборемся):
Код
#define MAXCNT 10
char flip=0, pressed=0;

while(1)
{
if((GPIOA->IDR&0x01)==0) //кнопка не нажата (или 0 читается во впемя дребезга) - готовимся к обработке
{
pressed=0;
cntr=0;
}
else
if(!pressed) //кнопка вроде бы нажата, но возможно это пока что только дребезг
{
cntr++; // сосчитаем до десяти в надежде, что за это время переходные процессы завершатся
if(cntr>MAXCNT) // десять последних проходов кнопка в состоянии "нажато" - считаем, что событие "нажатие кнопки" свершилось
{  // тут соб-сно ваша реакция на событие "нажатие кнопки", т.е. переход от 0 к 1
flip=!flip;  // организуем простейший двоичный переключатель ("flip-flop")
if(flip)      // и в зависимости от его состояния выполняем ту или иную ветвь
{
GPIOC->BSRR = GPIO_BSRR_BS9;
GPIOC->BSRR = GPIO_BSRR_BR8;
}
else
{
GPIOC->BSRR = GPIO_BSRR_BS8;
GPIOC->BSRR = GPIO_BSRR_BR9;
}
pressed=1;  // отработав событие "нажатие кнопки", отключаем проверку на это событие -> до следующего отпускания кнопки
}
}
else //кнопка в состоянии "нажато" (после отловленного события "нажатие кнопки") - в нашем случае неинтересно
{
}
}
0
z-z
169 / 168 / 56
Регистрация: 22.06.2011
Сообщений: 980
29.06.2012, 23:20 22
oordvork, а если я вместо двоичного переключателя сделаю больее количество переключений... в принципе и качестве работы ничего же не изменится, да?)
0
oordvork
0 / 0 / 0
Регистрация: 24.06.2012
Сообщений: 9
29.06.2012, 23:30 23
Ну, поскольку в вашем примере рассматривалось два состояния переключателя, я счел за лучшее упростить соответствующий участок до невозможности.
Ну а если N>2, то да - как у вас ранее.
Кстати, MAXCNT, возможно, придется увеличить, если вдруг длительность импульсов при дребезге окажется больше времени, необходимого для пробегания 10 вышеописанных циклов - могут проскакивать ложные срабатывания.
0
z-z
169 / 168 / 56
Регистрация: 22.06.2011
Сообщений: 980
29.06.2012, 23:32 24
Цитата Сообщение от oordvork
Цитата Сообщение от z-z
а как тогда событие нажатия отследить?
Ну, как-то так (одновременно и с дребезгом поборемся):
Код
#define MAXCNT 10
char flip=0, pressed=0;

while(1)
{
if((GPIOA->IDR&0x01)==0) //кнопка не нажата (или 0 читается во впемя дребезга) - готовимся к обработке
{
pressed=0;
cntr=0;
}
else
if(!pressed)
я тут немного не понял. что значит if(!pressed) ? ведь pressed изначально определяется char flip=0, pressed=0; как он может быть !pressed ?))
0
oordvork
0 / 0 / 0
Регистрация: 24.06.2012
Сообщений: 9
29.06.2012, 23:49 25
отрицание от 0 есть 1, т.е. истина.
Ветка if(!pressed) будет исполняться при значении pressed=0.
То есть когда на пине уже есть высокий уровень, но мы еще не уверены, что переключение на этот уровень произошло окончательно и бесповоротно (принимаем, что такая уверенность появится после MAXCNT циклов ожидания при высоком уровне на пине)
0
z-z
169 / 168 / 56
Регистрация: 22.06.2011
Сообщений: 980
29.06.2012, 23:56 26
спасибо) остановился на своем первоначальном варианте... правда надо около секунды удерживать кнопку, не знаю, почему. поставил даже delay(2); все равно ждать около секунды))
мне вот интересно стало. ведь редко где надо так нажимать и ждать... например кнопку ноута достаточно нажать и ждать даже на много меньше полусекунды)) как все эти нажатия обрабатываются тогда? или кнопки лучше и дребезга не возникает?)))
0
R_uro
0 / 0 / 0
Регистрация: 06.04.2010
Сообщений: 1,088
30.06.2012, 01:13 27
Цитата Сообщение от z-z
спасибо) как все эти нажатия обрабатываются тогда? или кнопки лучше и дребезга не возникает?)))
Везде с механическми контактами возникает дребезг . Кнопку или через триггер подключают или программно с дребезгом борятся.
Суть приметно такова - обнаружил нажатие, посчитал в отдельном счетчике +1, через скажем млсек 10 проверил еще раз, если нажата - добавил еще +1 и т.д. если 5-10 проверок подряд кнопка нажата - значит считай, что это настоящее нажатие и обрабатывай его.
Делают и проще, после первого нажатия повторно через 20-30 млсек проверяют. Если все еще нажата - обрабатывается нажатие.
0
R_uro
0 / 0 / 0
Регистрация: 06.04.2010
Сообщений: 1,088
30.06.2012, 02:31 28
Цитата Сообщение от moksir
Можно использовать стандартную библиотеку:
if (GPIO_ReadInputDataByt(GPIOC,GPIO_Pin_4)== Byt_RESIT)....
Можно и так(само коротко и быстро:
if (GPIOС->IDR & GPIO_IDR_IDR4)...
Громоздко ужасно.
Нельзя ли как-то по подобию игрушечных компиляторов сделать?

Код
#define pin_X  PORTA.1
if (pin_X == 1) {......}
0
moksir
0 / 0 / 0
Регистрация: 23.05.2012
Сообщений: 216
30.06.2012, 06:53 29
Цитата Сообщение от R_uro
Громоздко ужасно.
Нельзя ли как-то по подобию игрушечных компиляторов сделать?

Код:
#define pin_X PORTA.1
if (pin_X == 1) {......}

Так в чем проблема?
Код
#define pin_X  (GPIOС->IDR & GPIO_IDR_IDR4)
if (pin_X == 1) {......}
Надо понимать, что в ARM не на первом месте ногодрыганье, и даже не на втором...
0
инкер
0 / 0 / 0
Регистрация: 28.10.2010
Сообщений: 893
30.06.2012, 11:50 30
Цитата Сообщение от R_uro
Цитата Сообщение от moksir
Можно использовать стандартную библиотеку:
if (GPIO_ReadInputDataByt(GPIOC,GPIO_Pin_4)== Byt_RESIT)....
Можно и так(само коротко и быстро:
if (GPIOС->IDR & GPIO_IDR_IDR4)...
Громоздко ужасно.
Нельзя ли как-то по подобию игрушечных компиляторов сделать?

Код
#define pin_X  PORTA.1
if (pin_X == 1) {......}
Считается, что так общепонятно и кросплатформенно...
В отличии от такой записи:

JCP iB,4,M1
0
md5sum
0 / 0 / 0
Регистрация: 19.01.2011
Сообщений: 72
30.06.2012, 12:57 31
Цитата Сообщение от z-z
md5sum, опять к вопросу о "массовом" переключении выводов... а если все надо включать и выключать их всех по очереди? включил 0, выключил 0, включил 1, выключил 1...... и так до конца... неужели никак нельзя сократить код? обязательно для каждого вывода писать GPIOB->ODR ^= ??))
например так:
Код
 int i;
int mask=1;
for(i=0;i++;i<16)
{
GPIOB->ODR ^=mask;
// что-то выполнили
GPIOB->ODR ^=mask;
mask<<=1;
}
включит/выключит по очереди 16 выводов
0
z-z
169 / 168 / 56
Регистрация: 22.06.2011
Сообщений: 980
30.06.2012, 13:34 32
md5sum, круто! спасибо, это то, что нужно))) это заменило около 120 строк кода на 9 строк!))))
0
R_uro
0 / 0 / 0
Регистрация: 06.04.2010
Сообщений: 1,088
30.06.2012, 14:52 33
Цитата Сообщение от moksir
Так в чем проблема?
Код:
#define pin_X (GPIOС->IDR & GPIO_IDR_IDR4)
if (pin_X == 1) {......}

Это, как я понимаю, будет работать только , если надо проверить состояние пина.
Установить pin_X = 1; уже не получится.

Где-то видел, что можно порт представить в виде битового поля и тогда с отдельными битами можно обращаться уже и так
PORTA.0, PORTA.1 и т.д.;
Здесь это возможно?

Код
Надо понимать, что в ARM не на первом месте ногодрыганье, и даже не на втором...
Разные у людей задачи бывают. Не всем надо лезть в самые дебри устройства и системы команд ARM. Мне вот надо именно ногами подрыгать.
А с подобными конструкциями мозг сломать можно )))
Код
if (btn_old_state == 0 && btn_state == 1)
GPIO_WriteByt(GPIOC, LED1, !GPIO_ReadOutputDataByt(GPIOC, LED1));
Насколько понятнее
Код
#define    LED1   PORTC.2
if (btn_old_state == 0 && btn_state == 1)    LED = ~LED1;
0
Wirmom_Otix
0 / 0 / 0
Регистрация: 03.05.2012
Сообщений: 33
30.06.2012, 15:57 34
а прикрутить прерывание по нажатию кнопки никак? там тогда не нужно никих проверок после нажатия, так как раз срабатывает по фронту нажатия (как тут уж настроишь так и будеть)) или нужно именно читать порт?
Код
void Init_Key(void)
{
Init_Button( PORTA,  GPIO_Pin_0);  // инициализация пина на прием

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);

SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);

EXTI_InitTypeDef EXTI_InitStruct;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Ymtirrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStruct.EXTI_Line = EXTI_Line0;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStruct);

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

}

void EXTI0_IRQHomdler(void)
{

.....

EXTI_ClearFlag(EXTI_Line0);

}
0
R_uro
0 / 0 / 0
Регистрация: 06.04.2010
Сообщений: 1,088
30.06.2012, 19:00 35
Цитата Сообщение от Werman_Otix
а прикрутить прерывание по нажатию кнопки никак?
Так дребез длится миллисекунды, а бработчик обработает нажатие за несколько микросекунд, вернется в цикл и снова на дребезг среагирует. ))
К тому же, подавление дребезга программным путем, это не только подавление самого дребезга, но и проверка истинности нажатия, потому как кратковременная помеха тоже может проскочить и восприняться как нажатие.
0
30.06.2012, 19:00
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.06.2012, 19:00

Обработка нажатия кнопки
Добрый вечер! Пытаюсь сделать простой калькулятор на Java c использованием...

Обработка нажатия на кнопки
Всем привет! У меня есть несколько кнопок на форме. Допустим 5. Мне надо...

Создать параграф с произвольным текстом по нажатию кнопки
Объясните, пожалуйста, в чём ошибка. По нажатию кнопки должен создаться...


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

Или воспользуйтесь поиском по форуму:
35
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru