Пт апр 25, 2014 13:21:20
- вынужден не согласиться, я ведь понимаю как должна работать эта программа, вся проблема в том что я не знаю как это записать в код.Alexeyslav писал(а):Это не зависит от языка
- если я все правильно понял то от дребезга можно избавиться с помощью задержки delay()? Как-то можно избавиться аппаратно?Alexeyslav писал(а):работает такая вещь как дребезг контактов
- это предложение поясняет то, от чего сигналы на INT0 считаются 1 за 2?Alexeyslav писал(а):при нажатии кнопки возникает сложный переходный процесс в котором возникает целая пачка импульсов иногда до сотни за раз
- это как?Alexeyslav писал(а):исполнить в роли процессора
Пт апр 25, 2014 14:39:56
sanyo.95 писал(а):это предложение поясняет то, от чего сигналы на INT0 считаются 1 за 2?
Пт апр 25, 2014 20:08:14
ARV писал(а):в это время контакт дребезжит
Пт апр 25, 2014 21:24:24
sanyo.95 писал(а):ARV писал(а):в это время контакт дребезжит
Большое спасибо за столь поняьный ответ. Не подскажете как избавиться от дребезга, я так понимаю нужно исползовать таймер?
// макрос для задержки подалвения дребезга в миллисекундах
#define DEBOUNCE 15
uint8_t get_key_code(void); // эта функция вернет состояние кнопок
// функия опроса кнопок, вернет 0, если нет нажатий, не ноль - если есть
uint8_t get_key(void){
uint8_t key;
key = get_key_code();
delay_ms(DEBOUNCE);
if(key == get_key_code())
return key;
else
return 0;
}
uint8_t get_key_code(void){
return ~PINB & _BV(0);
}
// определяем константы для каждой кнопки
#define KEY1 _BV(PB0)
#define KEY2 _BV(PB1)
#define KEY3 _BV(PB2)
#define KEY4 _BV(PB3)
// а вот так мы обозначаем сразу все наши кнопки
#define ALL_KEY (KEY1 | KEY2 | KEY3 | KEY4)
uint8_t get_key_code(void){
return ~PINB & ALL_KEY;
}
// где-то в глубине своей программы
switch(get_key()){
case KEY1: // тут обработка кнопки 1
break;
case KEY2: // тут обработка кнопки 1
break;
case KEY3: // тут обработка кнопки 1
break;
case KEY4: // тут обработка кнопки 1
break;
case KEY1 | KEY3: // тут обработка одновременного нажатия сразу 2 кнопок
break;
default:
// а тут обработка всех прочих вариантов, в том числе отсутствия нажатия
}
typedef unsigned char uint8_t;
#define _BV(x) (1<<(x))
Пт апр 25, 2014 22:00:39
я ведь понимаю как должна работать эта программа, вся проблема в том что я не знаю как это записать в код.
Берешь указательный палец правой руки и водишь им по программе предсказывая её поведение в каждый момент времени. Это возможно, поскольку программа работает строго определенным образом и не зависит от нашего желания - обычно когда за строгость принимаешь собственное желание возникает неожиданное поведение программы.- это как?
я уже так много раз рассказывал про кнопки, что скоро тошнить будет... но все-таки повторюсь.
Пт апр 25, 2014 22:22:12
обеспечить равномерную переодичность опроса в главном цикле намного сложнее, чем пользоваться моим вариантом кода. сомневаюсь, что от этого будет какой-то выигрыш... но если вы приведете свой вариант кода - с интересом погляжу: век живи, век учисьAlexeyslav писал(а):Чрезмерно усложненный алгоритм
Пт апр 25, 2014 22:47:00
Пт апр 25, 2014 22:51:35
Alexeyslav писал(а):Равномерность нужна только для вывода на индикатор, а опрос кнопки важно соблюсти только минимальный интервал.
Пт апр 25, 2014 23:33:11
Пт апр 25, 2014 23:41:26
и чем же это будет лучше (проще?) обычного периодического опроса кнопки, предлагаемому мной? использованием лишнего ресурса - таймера?Alexeyslav писал(а):Если есть такие части программы которые выполняются долго а опрос кнопок нужен - повесить анализ кнопок на прерывание от таймера который даст стабильный интервал независимо от основного алгоритма.
Пт апр 25, 2014 23:54:16
Сб апр 26, 2014 00:02:56
как изменится ваш код для 16 кнопок матрицей? для 3 кнопок на 3 разных портах? если таймер занят чем-то? если пинов с аппартными запросами прерываний нет свободных?Alexeyslav писал(а):Так все-таки что проще?
Сб апр 26, 2014 09:23:35
ARV писал(а):алгоритм опроса кнопки должен быть следующим:
1. считываем состояние кнопки (или кнопок, если их несколько) в какую-то переменную, пусть это будет key
2. делаем задержку на 10-15 миллисекунд, за которые дребезг обычно должен кончиться
3. снова считываем состояние кнопки и сравниваем его с key
4. если оба значения одинаковы - то key и будет соответствовать текущему состоянию кнопки (кнопок), можно его обрабатывать
5. если значения разные - то мы считаем, что дребезг еще не кончился и тогда вместо key выдаем 0, что должно означать отсутствие нажатия кнопок.
Сб апр 26, 2014 09:40:40
Сб апр 26, 2014 09:45:22
+1...КРАМ писал(а):Универсальным решением я полагаю ВСЕГДА использовать один таймер как системный.
И все относительно большие интервалы типа дребезга, миганий, интервалов регенерации и т.п. вешать на этот таймер как ПРОГРАММНЫЕ таймеры.
А использовать в программе delay() - глупость какая то для любителей подрыгать ногой...
Из серии printf ...
Сб апр 26, 2014 11:06:03
sanyo.95 писал(а):Как-то можно избавиться аппаратно?
Сб апр 26, 2014 11:59:38
#include <mega8.h>
#include <delay.h>
volatile unsigned char per=0;
void main(void)
{
PORTB=0x00;
DDRB=0x01;
PORTC=0x01;
DDRC=0x00;
while (1)
{
unsigned char i, dr;
if (PINC.0==0) // если кнопка нажата
{
dr=0;
for (i=0;i<10;i++) // программный антидребезг контактов
{
delay_ms(10);
if(PINC.0==0)
{
dr++;
}
}
if(dr > 5)
{
per++; // увеличиваем переменную
}
}
if(per==4) // если переменная = 4
{
PORTB.0=1;
per=0; //обнулить переменную
}
}
}
Сб апр 26, 2014 18:08:14
Сб апр 26, 2014 18:44:08
-пожалуйста поясните как получилось такое число?Alexeyslav писал(а):похоже что N = 500
Alexeyslav писал(а):главный цикл
итерация это что?Alexeyslav писал(а):по 10мс на каждую итерацию
после while?Alexeyslav писал(а):Внутри цикла
ну можна хоть кусочек кода по этому поводу? Я реально не понимаю как это записать.Alexeyslav писал(а):Дальше, берем и сравниваем это значение с сохраненным в предыдущей итерации
Сб апр 26, 2014 19:27:35