ssvd 0 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба Задумка такая, надо одной кнопкой переключаться между циклами в которых что то выполняется, но если я нажимаю кнопку, то он проскакивает все циклы так как кнопку не успеваешь отпустить! Подскажите как лучше организовать алгоритм переключения одной кнопкой между циклами?! Вот не правильный текст программы //выводим на LCD "нажмите кнопку _start_" lcd_clear(); lcd_gotoxy(0,0); lcd_putsf("Hello!"); lcd_gotoxy(0,1); lcd_putsf("Press Start!"); while(PINA.0){ } //бесконечный цекл, ждем нажатие кнопки старт!!! lcd_clear(); lcd_gotoxy(0,0); lcd_putsf("Temp. beep"); lcd_gotoxy(0,1); lcd_putchar(t_count); while(PINA.0){ //бесконечный цекл, ждем нажатие кнопки старт!!! // if (PINA.3){ }; if (PINA.1){ //если нажата кнопка + t_count++; lcd_gotoxy(0,1); lcd_putchar(t_count); }; if (PINA.2){ //если нажата кнопка - t_count--; lcd_gotoxy(0,1); lcd_putchar(t_count); }; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба Вам нужно применить алгоритм подавления дребезга контактов кнопки. Иначе на одно нажатие пальцем будете получать 10-20 срабатываний. Поищите информацию по форуму или в google. По-английски ключевое слово "debounce switch". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DRUID3 0 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба Нужно просто добавить задержку (насколько помню там есть спец-функции) и проверять "по прошествии" изменилось ли состояние ног. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба Нужно просто добавить задержку...Если так сделать, до вся вычислительная мощность MCU будет расходоваться на молочение циклов в процедурах задержки. А ведь это не есть гуд... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DRUID3 0 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба Разумно... Но для такого объема программы - самое оно ;) ... Кстати, дребезг контактов хорошо давится простейшей интегрирующей RC-цепочкой... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба Разумно... Но для такого объема программы - самое оно ;) ...Согласен. Но лучше привыкать к хорошему тону с малолетства:-)Кстати, дребезг контактов хорошо давится простейшей интегрирующей RC-цепочкой...Это да. Бывает даже так... Вопрос - а оно надо, если программно всё решается великолепно. А RC цепочка в динамическом сканировании например не подходит, да и лишние элементы на плате, лишние пайки, деньги... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ssvd 0 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба Согласен. Но лучше привыкать к хорошему тону с малолетства:-)Это да. Бывает даже так... Вопрос - а оно надо, если программно всё решается великолепно. А RC цепочка в динамическом сканировании например не подходит, да и лишние элементы на плате, лишние пайки, деньги... Подскажите как программно это решить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 31 октября, 2009 Опубликовано 31 октября, 2009 (изменено) · Жалоба Вот в этом архиве есть файл keyboard.c - в нём программное подавление дддребезга. А в файле hardware.c (hardware_ged_pressed_key()) - два варианта опроса клавиатуры - или кнопки, замыкающие вход процессора на массу или набор до четырёх кнопок, через резисторную цепочку подключенных ко входу АЦП на процессоре (до четырёх кнопок на один вход АЦП). Схемы резисторной цепочки в файле doc\keyboard_matrix.pdf http://electronix.ru/forum/index.php?act=a...st&id=37570 Изменено 31 октября, 2009 пользователем Genadi Zawidowski Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ssvd 0 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба Вот в этом архиве есть файл keyboard.c - в нём программное подавление дддребезга. А в файле hardware.c (hardware_ged_pressed_key()) - два варианта опроса клавиатуры - или кнопки, замыкающие вход процессора на массу или набор до четырёх кнопок, через резисторную цепочку подключенных ко входу АЦП на процессоре (до четырёх кнопок на один вход АЦП). Схемы резисторной цепочки в файле doc\keyboard_matrix.pdf http://electronix.ru/forum/index.php?act=a...st&id=37570 спасибо конечно, но ничего в этих текстах не понял ((( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба Подскажите как программно это решить?Вот Вам ещё три варианта: #define MAX_CHECKS 10 // # checks before a switch is debounced uint8_t Debounced_State; // Debounced state of the switches uint8_t State[MAX_CHECKS]; // Array that maintains bounce status uint8_t Index; // Pointer into State // Service routine called by a timer interrupt void DebounceSwitch3() { uint8_t i,j; State[index]=RawKeyPressed(); ++Index; j=0xff; for(i=0; i<MAX_CHECKS-1;i++) j=j & State[i]; Debounced_State= j; if(Index>=MAX_CHECKS) Index=0; } //================================================================= bool_t DebounceSwitch2() { static uint16_t State = 0; // Current debounce status State=(State<<1) | !RawKeyPressed() | 0xe000; if(State==0xf000) return TRUE; return FALSE; } //================================================================= #define CHECK_MSEC 5 // Read hardware every 5 msec #define PRESS_MSEC 10 // Stable time before registering pressed #define RELEASE_MSEC 100 // Stable time before registering released // This function reads the key state from the hardware. extern bool_t RawKeyPressed(); // This holds the debounced state of the key. bool_t DebouncedKeyPress = false; // Service routine called every CHECK_MSEC to // debounce both edges void DebounceSwitch1(bool_t *Key_changed, bool_t *Key_pressed) { static uint8_t Count = RELEASE_MSEC / CHECK_MSEC; bool_t RawState; *Key_changed = false; *Key_pressed = DebouncedKeyPress; RawState = RawKeyPressed(); if (RawState == DebouncedKeyPress) { // Set the timer which allows a change from current state. if (DebouncedKeyPress) Count = RELEASE_MSEC / CHECK_MSEC; else Count = PRESS_MSEC / CHECK_MSEC; } else { // Key has changed - wait for new state to become stable. if (--Count == 0) { // Timer expired - accept the change. DebouncedKeyPress = RawState; *Key_changed=true; *Key_pressed=DebouncedKeyPress; // And reset the timer. if (DebouncedKeyPress) Count = RELEASE_MSEC / CHECK_MSEC; else Count = PRESS_MSEC / CHECK_MSEC; } } } P.S. Чтобы понять как оно работает много ума не надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ssvd 0 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба Вот Вам ещё три варианта: как я уже сказал, что С только начал изучать... можете построчно описать какой нибудь способ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 31 октября, 2009 Опубликовано 31 октября, 2009 · Жалоба как я уже сказал, что С только начал изучать... можете построчно описать какой нибудь способ? Все когда-то начинали. Читайте книги по си. Как для первоклассника: Функция DebounceSwitch2 не получает никаких аргументов и возвращает беззнаковый байт результата 1-истина 0-ложь Вызывать эту функцию надо с интервалом 5-10мс. uint8_t DebounceSwitch2(void) { // 1. Объявляется локальная статическая переменная и единожды инициализируется нулём при включении контроллера. static uint16_t State = 0; // 2. State сдвигается влево на один бит (было 0b 0000 0000 0000 0011 станет 0b 0000 0000 0000 0110) // 3. далее результат, возвращаемый функцией RawKeyPressed() логически инвертируем (был 0 стал 1 и наоборот) // 4. далее делаем побитовое ИЛИ результата пункта 2 и пункта 3 // 5. далее делаем побитовое ИЛИ результата пункта 4 с константой 0xe000 = 0b 1110 0000 0000 0000 // 6. присваиваем результат пункта 5 переменной State State=(State<<1) | !RawKeyPressed() | 0xe000; // 7. сравниваем State с константой 0xf000 = = 0b 1111 0000 0000 0000 и ели равны возвращаем 1 если иначе 0 return (State==0xf000); } побитовое ИЛИ работает так: a=0b00000001 b=0b00000010 c=a|b; // c станет равно 0b00000011 RawKeyPressed() возвращает нефильтрованное состояние логического входа (кнопка нажата = 0). и как только кнопка зажата средний член выражения (State<<1) | !RawKeyPressed() | 0xe000 превращается в 1. Получаем (State<<1) | 1 | 0xe000 Переменная State начинает меняться: State = 0xe001 State = 0xe003 State = 0xe007 State = 0xe00f State = 0xe01f State = 0xe03f State = 0xe07f State = 0xe0ff State = 0xe1ff State = 0xe3ff State = 0xe7ff State = 0xefff State = 0xffff State = 0xffff State = 0xffff State = 0xffff Как только кнопку отпустили: (State<<1) | 0 | 0xe000 State = 0xfffe State = 0xfffc State = 0xfff8 State = 0xfff0 State = 0xffe0 State = 0xffc0 State = 0xff80 State = 0xff00 State = 0xfe00 State = 0xfc00 State = 0xf800 State = 0xf000 << бинго State = 0xe000 State = 0xe000 State = 0xe000 State = 0xe000 Такой вот вариант (я его не использую). Существует масса других... Надо понимать, что при использовании этого алгоритма необходимо буферировать (очепятка была):) результат подавления дребезга в некоторой переменной... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 31 октября, 2009 Опубликовано 31 октября, 2009 (изменено) · Жалоба спасибо конечно, но ничего в этих текстах не понял ((( там, вроде, комментарии в файле keyboard.c на русском языке были, когд я писал. Функция hardware_ged_pressed_key() из файла hardware.c возвращает прзнак того, нажата ли какая-либо из кнопок и, собственно, номер (код) кнопки. Никаких ожиданий в этой функкции нет, так как она вызывается из обработчика таймерного прерывания около ста раз в секунду. Там, где она вызывается (ищется любым текстовым редактором) в файле keyboard.c - учитывается текущее состояние клавиатуры и давится дребезг (а так же определяется состойние "зажатой" кнопки - для отработки автоповтора (две скорости) или возврата признака "длинного" нажатия в вызывающую программу через функцию /* получение скан-кода клавиши или 0 в случае отсутствия. * если клавиша удержана, возвращается скан-код с добавленным битом 0x80 */ uint_least8_t kbd_scan(uint_least8_t * key, uint_least8_t * repeat) { ... } Изменено 31 октября, 2009 пользователем Genadi Zawidowski Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vetal-Soft 0 2 ноября, 2009 Опубликовано 2 ноября, 2009 · Жалоба Сделай так while(PINA.0){ }; //бесконечный цекл, ждем нажатие кнопки старт!!! delay_ms(100); while(!PINA.0){ }; //бесконечный цекл, ждем отпускания кнопки старт!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ssvd 0 2 ноября, 2009 Опубликовано 2 ноября, 2009 · Жалоба вот что написал, проверьте пожалуйста. вызывается для проверки каждой нажатой кнопки if (KeyState()==0x00){} проверка делается полностью на порт PINB. int KeyState(void){ button_state[1]=PINB; for(i=2;i<9;i++){ button_state[i]=PINB; if(button_state[i]==button_state[i-1]){ anti_drb_counter++; delay_ms(20); } else { anti_drb_counter=0; break; }; } if(anti_drb_counter==9){ while(1){ if(button_state[1]!=PINB){ return(button_state[1]); break; } } } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться