|
ARM, Кнопка |
|
|
|
Nov 7 2013, 11:03
|
Группа: Новичок
Сообщений: 4
Регистрация: 7-11-13
Пользователь №: 79 088

|
Здравствуйте, столкнулся с проблемой, что не могу найти как сделать однократное прочтение состояния кнопки. Код while(1) { //Если нажатa кнопка... if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==1) { Start(); GPIO_WriteBit (GPIOB,GPIO_Pin_10, Bit_RESET); } if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11)==1) { Time += 1000; GPIO_ResetBits (GPIOB,GPIO_Pin_11); } if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12)==1) { Time -= 1000; GPIO_WriteBit (GPIOB,GPIO_Pin_12, Bit_RESET); } } Мне нужно что бы нажатие кнопки включало функцию один раз, а не несколько раз на протяжении всего времени нажатия.
|
|
|
|
|
 |
Ответов
(1 - 11)
|
Nov 7 2013, 11:30
|
Гуру
     
Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295

|
Цитата(SimplyLovely @ Nov 7 2013, 15:03)  Мне нужно что бы нажатие кнопки включало функцию один раз, а не несколько раз на протяжении всего времени нажатия. Подавление дребезга нужно сделать. Дребезг не очень хорошей кнопки может запросто длиться >20 мС. Можно, например, сделать так: после обнаружения нажатия кнопки не реагировать на ее состояние в течение, например, 50 мС. Это очень удобно делать по прерыванию от таймера. Например, прерывание возникает раз в 50 мс, и вы опрашиваете клавиатуру только при возникновении прерывания (т.е., в обработчике прерывания). В некоторых задачах нужно также дождаться отпускания кнопки, опять же, подавляя возникающий при этом дребезг.
|
|
|
|
|
Nov 7 2013, 11:39
|
Группа: Новичок
Сообщений: 4
Регистрация: 7-11-13
Пользователь №: 79 088

|
Насколько я понял, нужно сделать выполнение функции, после того как кнопка будет нажата и отпущена? Как это можно реализовать?
Просто пока я нажимаю кнопку, цикл успевает 200000 раз пройти и значение Time вырастает непомерно.
Сообщение отредактировал SimplyLovely - Nov 7 2013, 11:41
|
|
|
|
|
Nov 7 2013, 11:59
|
Группа: Новичок
Сообщений: 4
Регистрация: 7-11-13
Пользователь №: 79 088

|
Цитата(Сергей Борщ @ Nov 7 2013, 14:43)  Кто-нибудь может объяснить, что должна делать вот эта строка? Код GPIO_WriteBit (GPIOB,GPIO_Pin_10, Bit_RESET); Так я думал сбрасывать бит нажатия кнопки. Но не получилось. Цитата(igorle @ Nov 7 2013, 14:39)  Код int is_pressed = 0; while(1) { //Если нажатa кнопка... if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==1) { /* Защита от дребезга */ if (is_pressed < 200 && is_pressed++ != 100 ) Start(); GPIO_WriteBit (GPIOB,GPIO_Pin_10, Bit_RESET); } else is_pressed = 0; ... sleep(1); } Говорит что функция sleep() задана неявно Видимо без этой функции работать не будет. А как можно обрабатывать нажатие не через цикл? Заодно прилагаю код полностью. Код //Не забываем подключить заголовочный файл с описание регистров микроконтроллера
#include "stm32f10x.h" #include "stm32f10x_conf.h"
static __IO uint32_t TimingDelay;
void Delay_ms(__IO uint32_t nTime);//обьявляем функцию отсчета времени
void Start (void); //обьявляем функцию начала работы мотора unsigned int Time = 1000;//переменная хранящая время задержки
//Наша главная функция
void main(void) { SysTick_Config(24000);
//Разрешаем тактирование шины порта B RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
//Объявляем структуру для настройки порта GPIO_InitTypeDef GPIO_Buttons;
//Заполняем структуру начальными значениями GPIO_StructInit(&GPIO_Buttons);
/* Запишем в поле GPIO_Pin структуры GPIO_Init_struct номер вывода порта, который мы будем настраивать далее */ GPIO_Buttons.GPIO_Pin = (GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12);
// Подобным образом заполним поля GPIO_Speed и GPIO_Mode GPIO_Buttons.GPIO_Speed= GPIO_Speed_2MHz; GPIO_Buttons.GPIO_Mode = GPIO_Mode_IN_FLOATING; //Передаем заполненную структуру, для выполнения действий по настройке регистров GPIO_Init(GPIOB, &GPIO_Buttons); //Разрешаем тактирование шины порта C RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //Объявляем структуру для настройки порта GPIO_InitTypeDef GPIO_Motor;
//Заполняем структуру начальными значениями GPIO_StructInit(&GPIO_Motor); // Настраеваем пины вывода управления мотором GPIO_Motor.GPIO_Pin = (GPIO_Pin_8 | GPIO_Pin_9); GPIO_Motor.GPIO_Speed= GPIO_Speed_2MHz; GPIO_Motor.GPIO_Mode = GPIO_Mode_Out_PP; // Передаем заполненую структуру, для выполнения действий по настройке регистров GPIO_Init(GPIOC, &GPIO_Motor); int is_pressed = 0; while(1) { //Если нажатa кнопка... if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==1) { /* Защита от дребезга */ if (is_pressed < 200 && is_pressed++ != 100 ) Start(); } else is_pressed = 0;
if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11)==1) { /* Защита от дребезга */ if (is_pressed < 200 && is_pressed++ != 100 ) Time += 1000; } else is_pressed = 0; if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12)==1) { /* Защита от дребезга */ if (is_pressed < 200 && is_pressed++ != 100 ) Time -= 1000; } else is_pressed = 0; } }
void Start (void) //функция начала работы { GPIO_SetBits(GPIOC, GPIO_Pin_9); Delay_ms(1000); GPIO_ResetBits(GPIOC, GPIO_Pin_9); Delay_ms(Time); GPIO_SetBits(GPIOC, GPIO_Pin_8); Delay_ms(1000); GPIO_ResetBits(GPIOC, GPIO_Pin_8); }
//Функция временной задержки void Delay_ms(__IO uint32_t nTime) { TimingDelay = nTime; while(TimingDelay != 0); }
void TimingDelay_Decrement(void) { if (TimingDelay != 0x00) { TimingDelay--; } }
//Обработчик прерывания системного таймера void SysTick_Handler(void) { TimingDelay_Decrement(); }
Сообщение отредактировал SimplyLovely - Nov 7 2013, 11:48
|
|
|
|
|
Nov 7 2013, 13:27
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (SimplyLovely @ Nov 7 2013, 14:59)  Так я думал сбрасывать бит нажатия кнопки.
Но не получилось. Естественно. Кнопку-то никто не отпустил и этот бит выставился снова. Точнее, он даже сбрасываться не будет. Заведите переменную "предыдущее состояние кнопки" и вызывайте свою функцию только в случае "предыдущее состояние - отпущена, текущее состояние - нажата".
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Nov 8 2013, 11:06
|
Знающий
   
Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245

|
Если после нажатия кнопки и после выполнения действия больше делать ничего не надо кроме как ждать отпускания кнопки то Код if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==1) { Start(); GPIO_WriteBit (GPIOB,GPIO_Pin_10, Bit_RESET); while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)); } while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1x)); наверно поможет
|
|
|
|
|
Nov 8 2013, 16:07
|
Группа: Новичок
Сообщений: 4
Регистрация: 7-11-13
Пользователь №: 79 088

|
Вобщем я сделал так. Код unsigned int check_button1 = 0;//флаг нажатия кнопки unsigned int check_button2 = 0; unsigned int check_button3 = 0; while(1) { //Если нажатa кнопка... if (GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==1 && check_button1 == 0) { Start(); check_button1 = 1; } else if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10)== 0) check_button1 = 0; if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11)==1 && check_button2 == 0) { Time += 1000; check_button2 = 1; } else if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11)== 0) check_button2 = 0; if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12)==1 && check_button3 == 0) { Time -= 1000; check_button3 = 1; } else if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12)== 0) check_button3 = 0; } Если кому не сложно, подскажите как через приерывания сделать. И еще как реализовать задержку с помощью таймера TIM_6 или TIM_7. А то с системным проблемы какие-то у меня, начинает подвисать иногда.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|