Форум по микроконтроллерам: Обработка кнопок - Форум по микроконтроллерам

Перейти к содержимому

  • 5 Страниц +
  • 1
  • 2
  • 3
  • Последняя »
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

Обработка кнопок

#1 Пользователь офлайн   Alex 

  • Убиватель МК
  • PipPipPipPip
  • Группа: Пользователи
  • Сообщений: 1 882
  • Регистрация: 15 Февраль 11

Отправлено 22 Октябрь 2011 - 23:33

Небольшая библиотечка, которая поможет с опросом кнопок.

Прикрепленный файл  buttons.zip (648байт)
Количество загрузок:: 1149

Подключение файла к проекту:
#include "buttons.h"


Настройка параметров файла "buttons.h".

#define PERIOD_BUTT_TICK    10      // Период опроса кнопок в Мс.
В этой строке указывается период в миллисекундах, с которым будет вызываться опрос кнопок.

#define BUTTON_ACT_LEVEL    0       // Активный уровень кнопок
В этой строке указывается уровень на ПИНе при нажатой кнопке.


Сервисы библиотеки.

Butt_Init(_name, _port_name, _bit_num)
Сервис, инициализирующий кнопку.
Выделяет память под структуру необходимых переменных.
Вызывается в области объявлений переменных. Т.е. вне функций.
_name - Имя кнопки.
_port_name - Порт, используемый кнопкой.
_bit_num - Номер бита порта, к которому подключена кнопка.
Пример вызова:
Butt_Init(My_Butt, PORTA, 0);
Инициализирует кнопку с именем My_Butt, прицепленную к 0-ому биту PORTA (т.е. RA0).

Butt_Tick(_name)
Опрос кнопки.
Сервис опрашивает пин кнопки с именем _name и, в соответсвии с его состоянием, изменяет в структуре переменные.
Вызывается в переодично-повторяющемся месте программы. Например в ОП таймера. Период должен быть прописан в константе PERIOD_BUTT_TICK файла "buttons.h".
Пример вызова:
    if(TMR1IF && TMR1IE){   // Если событие от таймера
        TMR1IF=0;               // Сбрасываем флаг события
        TMR1-=50000;            // Переустанавливаем таймер на 50000 тактов (10мс.).

        Butt_Tick(My_Butt);     // Опрос кнопки My_Butt
    }


Поля структуры кнопки.

b_name - имя кнопки.
b_name.stat
Текущее состояние кнопки. 1/0 - нажата/отжата.

b_name.click
Флаг кликнутой кнопки. Устанавливается когда щёлкнули кнопкой. После проверки, необходимо сбрасывать самостоятельно.

b_name.cnt_ms
Время, в миллисекундах, в течении которого кнопка находится в нажатом состоянии. Используется, как правило, для обработки длительного нажатия кнопки.
Не говорите что мне делать, и я не скажу куда Вам идти !
0

#2 Пользователь офлайн   Alex 

  • Убиватель МК
  • PipPipPipPip
  • Группа: Пользователи
  • Сообщений: 1 882
  • Регистрация: 15 Февраль 11

Отправлено 22 Октябрь 2011 - 23:40

Пример использования.
Прикрепленный файл  butt.rar (59,01К)
Количество загрузок:: 1172
При клике по кнопке изменяется состояние светодиода.
При удержании кнопки более 1 сек. состояние светодиода изменяется каждые 300 мс.
При удержании кнопки более 3 сек. состояние светодиода изменяется каждые 50 мс.
Не говорите что мне делать, и я не скажу куда Вам идти !
1

#3 Гость_dosikus_*

  • Группа: Гости

Отправлено 09 Март 2012 - 22:29

Просмотр сообщенияAlex (22 Октябрь 2011 - 23:40) писал:

Пример использования.
Прикрепленный файл butt.rar
При клике по кнопке изменяется состояние светодиода.
При удержании кнопки более 1 сек. состояние светодиода изменяется каждые 300 мс.
При удержании кнопки более 3 сек. состояние светодиода изменяется каждые 50 мс.


Есть отличный обработчик у tester'a сразу на 8 кнопок .
Если есть желание могу разжевать...

#4 Пользователь офлайн   Alex 

  • Убиватель МК
  • PipPipPipPip
  • Группа: Пользователи
  • Сообщений: 1 882
  • Регистрация: 15 Февраль 11

Отправлено 09 Март 2012 - 22:51

Цитата

Есть отличный обработчик у tester'a сразу на 8 кнопок .
Видели, знаем :)

Цитата

Если есть желание могу разжевать...
Если только кому-нибудь интересно будет....
Не говорите что мне делать, и я не скажу куда Вам идти !
0

#5 Пользователь офлайн   slava_piter 

  • Знаток
  • PipPip
  • Группа: Пользователи
  • Сообщений: 76
  • Регистрация: 11 Март 12

Отправлено 12 Март 2012 - 09:24

Здравствуйте!!! Поставили задачку на работе. Необходима программа опроса трех кнопок для Pic, любого в принципе, у меня будет Pic16f628a. После опроса должен загораться светодиод кнопки которая дольше всего удерживалась. Набрасал программку три переменных сразу обнуляем, и в main делаем опрос кнопок какая кнопка нажата та переменная ++, а потом просто сравниваем состояние какая переменная насчитала больше единичек. встала проблема, кнопка это просто имитация, там будет устройство и необходимо знать какое стояло дольше всего, напротив той и должен светодиод гореть.Стоять они могут долго несколько часов. Как избежать переполнения переменной??? делать сдвиг или просто делать медленный опрос и для переменной много места отвести???? или как в вашем примере таймер использовать и прерывания????? Зарание спасибо!
0

#6 Пользователь офлайн   Alex 

  • Убиватель МК
  • PipPipPipPip
  • Группа: Пользователи
  • Сообщений: 1 882
  • Регистрация: 15 Февраль 11

Отправлено 12 Март 2012 - 10:19

Поверьте, микроконтроллер может считать ооочень долго :) Не хватает одной переменной, заведите ещё одну и считайте ей переполнения первой. Не хватит второй - заведите третью...

Цитата

Набрасал программку
Вы хоть выкладывайте то, о чём говорите.
Не говорите что мне делать, и я не скажу куда Вам идти !
0

#7 Пользователь офлайн   slava_piter 

  • Знаток
  • PipPip
  • Группа: Пользователи
  • Сообщений: 76
  • Регистрация: 11 Март 12

Отправлено 12 Март 2012 - 10:32

#include <16f628a.h>       // Подключение библиотеки МК PIC18F4520

void low_init()      //   инициализация МК
unsigned char A,B,C;           // Объявление переменной
TRISB = 0b00000111;               // Настройка RB1-RB2 на ввод данных
A=0;
B=0;
C=0:

void main            // Основная функция
{


if (PORTBbits.RB0==0) {A++;}
esle A=0;
if (PORTBbits.RB1==0) {B++;}
esle B=0;
if (PORTBbits.RB2==0) {C++;}
esle C=0;

if (A>B & A>C) {PORTBbits.RB4=1;}
else
if (B>A & B>C) {PORTBbits.RB5=1;}
else
if (C>A & C>B) {PORTBbits.RB6=1;}
else
return;
}


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

#8 Пользователь офлайн   Alex 

  • Убиватель МК
  • PipPipPipPip
  • Группа: Пользователи
  • Сообщений: 1 882
  • Регистрация: 15 Февраль 11

Отправлено 12 Март 2012 - 11:04

1. Сделайте опрос входов (кнопок, как Вы их называете) через определённый промежуток времени. Проще будет расчитывать переменные для счёта.
2. У Вас счётчики однобайтные (char). Можно увеличить их разрядность до 2(int) или 4(long) байт.

А это что такое ?

Цитата

void low_init()      //   инициализация МК
unsigned char A,B,C;           // Объявление переменной
TRISB = 0b00000111;               // Настройка RB1-RB2 на ввод данных
A=0;
B=0;
C=0:
Ни функцией, ни объявлениями не назовёшь :huh:

Советую Вам почитать какую-нибудь литературку по Си для начинающих.
Не говорите что мне делать, и я не скажу куда Вам идти !
0

#9 Пользователь офлайн   slava_piter 

  • Знаток
  • PipPip
  • Группа: Пользователи
  • Сообщений: 76
  • Регистрация: 11 Март 12

Отправлено 12 Март 2012 - 11:49

Полностью согласен. Си изучал давно и так тока на лабах, сча желею что тогда халявил и пытаюсь читать книжки по нему. Как можно настроить время через каторое будет опрос кнопок??? через прирывания???? или еще есть способы???
Скажем с частой опроса 5мс???
0

#10 Пользователь офлайн   Alex 

  • Убиватель МК
  • PipPipPipPip
  • Группа: Пользователи
  • Сообщений: 1 882
  • Регистрация: 15 Февраль 11

Отправлено 12 Март 2012 - 12:22

Цитата

через прирывания????
Можно через них, можно без них.
Можно таймером, можно без него.
Не говорите что мне делать, и я не скажу куда Вам идти !
0

#11 Пользователь офлайн   slava_piter 

  • Знаток
  • PipPip
  • Группа: Пользователи
  • Сообщений: 76
  • Регистрация: 11 Март 12

Отправлено 12 Март 2012 - 12:25

Тогда вопрос как??? я увы не знаю, какой есть способ чтобы без прерываний установить частоту опроса кнопок???
0

#12 Пользователь офлайн   Ewgen 

  • Знаток
  • PipPip
  • Группа: Пользователи
  • Сообщений: 72
  • Регистрация: 15 Февраль 11
  • ГородВоркута

Отправлено 12 Март 2012 - 14:15

Просмотр сообщенияslava_piter (12 Март 2012 - 10:32) писал:

#include <16f628a.h> // Подключение библиотеки МК PIC18F4520

Это так и должно быть?
0

#13 Пользователь офлайн   Alex 

  • Убиватель МК
  • PipPipPipPip
  • Группа: Пользователи
  • Сообщений: 1 882
  • Регистрация: 15 Февраль 11

Отправлено 12 Март 2012 - 16:01

slava_piter, Вам нужно создать тему что-то типа "C чего начать" и потихоньку в ней задавать вопросы, возникающие во время изучения МК.
Нельзя вот так просто, не зная ничего, взять и написать программу. Это просто нереально.
И прекратите эмоционально расставлять знаки вопроса :)
Не говорите что мне делать, и я не скажу куда Вам идти !
0

#14 Гость_dosikus_*

  • Группа: Гости

Отправлено 08 Апрель 2012 - 10:40

Просмотр сообщенияslava_piter (12 Март 2012 - 11:49) писал:

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


5 мс - это много , 20 хватит .
Например,
в прерывании определяем участок, вхождение в который будет каждые 20 мс .
в нем же выставляем флаг , захватываем состояние кнопок . Матрица или тупо кнопки на порту, не важно -главное максимально быстро сохранить "сырое" состояние кнопок .

В super_loop (главном цикле) проверяем флаг на готовность , тут же сбрасываем ,давим дребезг - т.е. отслеживаем произошли ли изменения состояния кнопок .
Если не было изменений и значение не нулевое (отличное от "кнопки отпущены") , дребезг подавлен.
Принимаем решения ...
Естественно , что этот вариант годится если super_loop не имеет тупых задержек и построен по принципу конечного автомата.
Если имеет , то и давить дребезг и вычислять кнопки нужно в прерывании.

#15 Пользователь офлайн   BiNaR 

  • Знаток
  • PipPip
  • Группа: Пользователи
  • Сообщений: 64
  • Регистрация: 01 Август 12
  • ГородNovosibirsk

Отправлено 03 Август 2012 - 08:00

Не могу приделать кнопку к pic18f252, как в примере во втором посте...
А если при нажатии на кнопку должны выводиться информация на LCD, как это реализовать?
И для чего сопротивление повешано? :rolleyes:

Сообщение отредактировал BiNaR: 03 Август 2012 - 10:37

0

#16 Пользователь офлайн   Alex 

  • Убиватель МК
  • PipPipPipPip
  • Группа: Пользователи
  • Сообщений: 1 882
  • Регистрация: 15 Февраль 11

Отправлено 03 Август 2012 - 10:52

Цитата

как это реализовать?
Вы не поверите, нужно просто написать программу ручками :)
Что не получается ? Покажите код и скажите на чём конкретно застряли.
Не говорите что мне делать, и я не скажу куда Вам идти !
0

#17 Пользователь офлайн   BiNaR 

  • Знаток
  • PipPip
  • Группа: Пользователи
  • Сообщений: 64
  • Регистрация: 01 Август 12
  • ГородNovosibirsk

Отправлено 03 Август 2012 - 11:42

Просмотр сообщенияAlex (03 Август 2012 - 10:52) писал:

Цитата

как это реализовать?
Вы не поверите, нужно просто написать программу ручками :)
Что не получается ? Покажите код и скажите на чём конкретно застряли.


#include "htc.h"
#include "buttons.h"
#include "LCD.h"


__CONFIG(1, 0x02FF);		//
__CONFIG(2, 0x00FF);		//  Конфигурация контроллера
__CONFIG(4, 0xFF80);		//

static volatile near unsigned int   TMR1    @ 0x00E;                           - На эту строчку ругается!


Butt_Init(Enter, PORTA, 0);


/********************************************************************/
void interrupt _isr(void){

    if(TMR1IF && TMR1IE){   // Если событие от таймера
        TMR1IF=0;               // Сбрасываем флаг события
        TMR1-=50000;            // Переустанавливаем таймер на 50000 тактов (10мс.).

        Butt_Tick(Enter);     // Опрос кнопки My_Butt
    }

}
/********************************************************************/

/********************************************************************/
void main (void){

TMR1ON=1;       // Включить TMR1
TMR1IF=0;       // Сбросить флаг от TMR1
TMR1IE=1;       // Разрешить прерывания от TMR1
TMR1=-50000;    // Установить TMR1 на 50000 тактов

PEIE=1;         // Разрешаем прерывания от перефирии
GIE=1;          // и глобально

CMCON=7;

while(1){       // Безконечный цикл

    if(Enter.click){        // Если была кликнута кнопка
        Enter.click=0;          // Сбрасываем флаг
        lcd_gotoxy(0.0);
         lcd_puts("Hello");              
    }
        else if(Enter.cnt_ms>=1000){    // Если кнопка нажата более 1 сек.
        lcd_gotoxy(0.0);
         lcd_puts("GoodBy");                 
        DelayMs(200);                       // Задержка 100 Мс.
    }
}
}
/********************************************************************/


В итоге: если просто нажать на кнопку - ни какой реакции,
если подержать ее больше 1сек. - на LCD надпись GoodBy.
А мне надо чтобы нажал на кнопку - Hello, когда еще раз нажал - GoodBy, без всяких удержаний.
0

#18 Пользователь офлайн   Alex 

  • Убиватель МК
  • PipPipPipPip
  • Группа: Пользователи
  • Сообщений: 1 882
  • Регистрация: 15 Февраль 11

Отправлено 03 Август 2012 - 11:49

Вам нужно завести переменную, которая будет хранить в себе статус состояния, т.е. будет указывать что делать при следующем нажатии кнопки. Затем обрабатывать нажатие кнопки, в этом обработчике проверять эту переменную, делать то, что нужно в зависимости от её значения и изменять её для следующего события (в Вашем случае, просто её инверсия).
Не говорите что мне делать, и я не скажу куда Вам идти !
0

#19 Пользователь офлайн   BiNaR 

  • Знаток
  • PipPip
  • Группа: Пользователи
  • Сообщений: 64
  • Регистрация: 01 Август 12
  • ГородNovosibirsk

Отправлено 03 Август 2012 - 12:45

Просмотр сообщенияAlex (03 Август 2012 - 11:49) писал:

Вам нужно завести переменную, которая будет хранить в себе статус состояния, т.е. будет указывать что делать при следующем нажатии кнопки. Затем обрабатывать нажатие кнопки, в этом обработчике проверять эту переменную, делать то, что нужно в зависимости от её значения и изменять её для следующего события (в Вашем случае, просто её инверсия).


А можно на наглядном примере? :rolleyes:
0

#20 Пользователь офлайн   Alex 

  • Убиватель МК
  • PipPipPipPip
  • Группа: Пользователи
  • Сообщений: 1 882
  • Регистрация: 15 Февраль 11

Отправлено 03 Август 2012 - 13:12

Скиньте свой проект сюда, всю папочку целиком.
Не говорите что мне делать, и я не скажу куда Вам идти !
0

Поделиться темой:


  • 5 Страниц +
  • 1
  • 2
  • 3
  • Последняя »
  • Вы не можете создать новую тему
  • Вы не можете ответить в тему

1 человек читают эту тему
0 пользователей, 1 гостей, 0 скрытых пользователей