|
CodeVisionAVR помогите по написанию! |
|
|
|
Oct 31 2009, 07:07
|
Участник

Группа: Участник
Сообщений: 16
Регистрация: 30-10-09
Пользователь №: 53 320

|
Задумка такая, надо одной кнопкой переключаться между циклами в которых что то выполняется, но если я нажимаю кнопку, то он проскакивает все циклы так как кнопку не успеваешь отпустить! Подскажите как лучше организовать алгоритм переключения одной кнопкой между циклами?! Вот не правильный текст программы Код //выводим на 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); }; }
Причина редактирования: Оформление цитаты исходника.
|
|
|
|
|
Oct 31 2009, 08:48
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(DRUID3 @ Oct 31 2009, 11:31)  Разумно... Но для такого объема программы - самое оно  ... Согласен. Но лучше привыкать к хорошему тону с малолетства:-) Цитата Кстати, дребезг контактов хорошо давится простейшей интегрирующей RC-цепочкой... Это да. Бывает даже так... Вопрос - а оно надо, если программно всё решается великолепно. А RC цепочка в динамическом сканировании например не подходит, да и лишние элементы на плате, лишние пайки, деньги...
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Oct 31 2009, 09:12
|
Участник

Группа: Участник
Сообщений: 16
Регистрация: 30-10-09
Пользователь №: 53 320

|
Цитата(demiurg_spb @ Oct 31 2009, 12:48)  Согласен. Но лучше привыкать к хорошему тону с малолетства:-)Это да. Бывает даже так... Вопрос - а оно надо, если программно всё решается великолепно. А RC цепочка в динамическом сканировании например не подходит, да и лишние элементы на плате, лишние пайки, деньги... Подскажите как программно это решить?
|
|
|
|
|
Oct 31 2009, 12:20
|
Участник

Группа: Участник
Сообщений: 16
Регистрация: 30-10-09
Пользователь №: 53 320

|
Цитата(Genadi Zawidowski @ Oct 31 2009, 15:03)  Вот в этом архиве есть файл keyboard.c - в нём программное подавление дддребезга. А в файле hardware.c (hardware_ged_pressed_key()) - два варианта опроса клавиатуры - или кнопки, замыкающие вход процессора на массу или набор до четырёх кнопок, через резисторную цепочку подключенных ко входу АЦП на процессоре (до четырёх кнопок на один вход АЦП). Схемы резисторной цепочки в файле doc\keyboard_matrix.pdf http://electronix.ru/forum/index.php?act=a...st&id=37570спасибо конечно, но ничего в этих текстах не понял (((
|
|
|
|
|
Oct 31 2009, 13:36
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(ssvd @ Oct 31 2009, 12:12)  Подскажите как программно это решить? Вот Вам ещё три варианта: CODE #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. Чтобы понять как оно работает много ума не надо.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Oct 31 2009, 15:43
|
Участник

Группа: Участник
Сообщений: 16
Регистрация: 30-10-09
Пользователь №: 53 320

|
Цитата(demiurg_spb @ Oct 31 2009, 17:36)  Вот Вам ещё три варианта: как я уже сказал, что С только начал изучать... можете построчно описать какой нибудь способ?
Причина редактирования: Нарушение п.3.4 Правил форума.
|
|
|
|
|
Oct 31 2009, 20:42
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(ssvd @ Oct 31 2009, 18:43)  как я уже сказал, что С только начал изучать... можете построчно описать какой нибудь способ? Все когда-то начинали. Читайте книги по си. Как для первоклассника: Функция 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 CODE Переменная 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 Такой вот вариант (я его не использую). Существует масса других... Надо понимать, что при использовании этого алгоритма необходимо буферировать (очепятка была)  результат подавления дребезга в некоторой переменной...
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Oct 31 2009, 22:34
|

Профессионал
    
Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634

|
Цитата(ssvd @ Oct 31 2009, 15:20)  спасибо конечно, но ничего в этих текстах не понял ((( там, вроде, комментарии в файле 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) { ... }
Сообщение отредактировал Genadi Zawidowski - Oct 31 2009, 22:45
|
|
|
|
|
Nov 2 2009, 07:55
|
Участник

Группа: Участник
Сообщений: 60
Регистрация: 16-06-05
Пользователь №: 6 074

|
Сделай так Код while(PINA.0){ }; //бесконечный цекл, ждем нажатие кнопки старт!!! delay_ms(100); while(!PINA.0){ }; //бесконечный цекл, ждем отпускания кнопки старт!!!
|
|
|
|
|
Nov 2 2009, 15:40
|
Участник

Группа: Участник
Сообщений: 16
Регистрация: 30-10-09
Пользователь №: 53 320

|
вот что написал, проверьте пожалуйста. вызывается для проверки каждой нажатой кнопки 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; } } } }
Причина редактирования: Оформление цитаты исходника.
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|