Перейти к содержанию
    

CodeVisionAVR помогите по написанию!

Задумка такая, надо одной кнопкой переключаться между циклами в которых что то выполняется, но если я нажимаю кнопку, то он проскакивает все циклы так как кнопку не успеваешь отпустить! Подскажите как лучше организовать алгоритм переключения одной кнопкой между циклами?!

Вот не правильный текст программы

 

    //выводим на 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);
        };
    }

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вам нужно применить алгоритм подавления дребезга контактов кнопки.

Иначе на одно нажатие пальцем будете получать 10-20 срабатываний.

Поищите информацию по форуму или в google. По-английски ключевое слово "debounce switch".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нужно просто добавить задержку (насколько помню там есть спец-функции) и проверять "по прошествии" изменилось ли состояние ног.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нужно просто добавить задержку...
Если так сделать, до вся вычислительная мощность MCU будет расходоваться на молочение циклов в процедурах задержки.

А ведь это не есть гуд...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Разумно... Но для такого объема программы - самое оно ;) ... Кстати, дребезг контактов хорошо давится простейшей интегрирующей RC-цепочкой...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Разумно... Но для такого объема программы - самое оно ;) ...
Согласен. Но лучше привыкать к хорошему тону с малолетства:-)
Кстати, дребезг контактов хорошо давится простейшей интегрирующей RC-цепочкой...
Это да. Бывает даже так... Вопрос - а оно надо, если программно всё решается великолепно.

А RC цепочка в динамическом сканировании например не подходит, да и лишние элементы на плате, лишние пайки, деньги...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Согласен. Но лучше привыкать к хорошему тону с малолетства:-)Это да. Бывает даже так... Вопрос - а оно надо, если программно всё решается великолепно.

А RC цепочка в динамическом сканировании например не подходит, да и лишние элементы на плате, лишние пайки, деньги...

 

Подскажите как программно это решить?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот в этом архиве есть файл keyboard.c - в нём программное подавление дддребезга. А в файле hardware.c (hardware_ged_pressed_key()) - два варианта опроса клавиатуры - или кнопки, замыкающие вход процессора на массу или набор до четырёх кнопок, через резисторную цепочку подключенных ко входу АЦП на процессоре (до четырёх кнопок на один вход АЦП). Схемы резисторной цепочки в файле doc\keyboard_matrix.pdf

 

http://electronix.ru/forum/index.php?act=a...st&id=37570

Изменено пользователем Genadi Zawidowski

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот в этом архиве есть файл keyboard.c - в нём программное подавление дддребезга. А в файле hardware.c (hardware_ged_pressed_key()) - два варианта опроса клавиатуры - или кнопки, замыкающие вход процессора на массу или набор до четырёх кнопок, через резисторную цепочку подключенных ко входу АЦП на процессоре (до четырёх кнопок на один вход АЦП). Схемы резисторной цепочки в файле doc\keyboard_matrix.pdf

 

http://electronix.ru/forum/index.php?act=a...st&id=37570

 

спасибо конечно, но ничего в этих текстах не понял (((

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подскажите как программно это решить?
Вот Вам ещё три варианта:

#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. Чтобы понять как оно работает много ума не надо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот Вам ещё три варианта:

 

как я уже сказал, что С только начал изучать...

можете построчно описать какой нибудь способ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

как я уже сказал, что С только начал изучать...

можете построчно описать какой нибудь способ?

Все когда-то начинали. Читайте книги по си.

Как для первоклассника:

 

Функция 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

Такой вот вариант (я его не использую). Существует масса других...

Надо понимать, что при использовании этого алгоритма необходимо буферировать (очепятка была):) результат подавления дребезга в некоторой переменной...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

спасибо конечно, но ничего в этих текстах не понял (((

 

там, вроде, комментарии в файле 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сделай так

 
while(PINA.0){ }; //бесконечный цекл, ждем нажатие кнопки старт!!!
delay_ms(100);
while(!PINA.0){ }; //бесконечный цекл, ждем отпускания кнопки старт!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вот что написал, проверьте пожалуйста.

вызывается для проверки каждой нажатой кнопки 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;
            }
        }
    }
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

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

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...