40-50 мс - нормальное время для принятия решения об уровне сигнала с ручного механического контакта.
40-50 мс - нормальное время для принятия решения об уровне сигнала с ручного механического контакта.
Я рисую в EDGE Diagrammer очень доволен. Еще работал в Diagram DesignerAlexeyslav писал(а):Если кто найдет более удобную программу для рисования блок-схем, сообщите.
Код: Выделить всё
// Timer1 overflow interrupt service routine
ISR(TIMER1_OVF_vect)
if(ticTimer == 1) { // таймер тиков для определения временных интервалов короткого, длинного нажатий и автоповтора
cntTic++;
}
}
. . .
main() {
_delay_ms(500);
startup(); // Controller configuration
// Global enable interrupts
sei();
BUT_Init();
while(1) {
FPowerCheck();
switch(Mode) {
case M_SETUP: FSetUp(); break;
case M_VIEWUP: FViewUp(); break;
case M_VIEWDN: FViewDn(); break;
case M_NORMAL: FNormal(); break;
}
}
}Код: Выделить всё
/************************************************ FViewDn */
void FViewDn(void){
// что-то выполняется
Button(); // вызываем опрос кнопок
if( isKey == 1 ) { // флаг что было нажатие
if( (keyPress == KEY_UP) || (keyPress == KEY_ENTER) )
Mode = LastMode; // меняем текущий режим
_resBut(); // обнуляем кнопку
}
}
Могу EDGE скинуть с ключомAlexeyslav писал(а):Одна какая-то левая китайская, а другая триальная. Нет счастья в жизни.
Заведи еще одну переменную или флаг, лучше переменную, которая увеличивается с каждым приходом длинного нажатия. При отпускании кнопки смотри если она ноль, значит коротко нажали, а если она не ноль, значит было длинное нажатие и нужно сбросить кнопку.skeef писал(а):1. По отпусканию кнопки определяется была ли она нажата и было ли короткое или длинное нажатие.
...
Например, долгое нажатие на KEY_UP переходим в режим установки и сразу же начинается увеличение показаний счетчика.
Как сделать чтобы при одном нажатии мы входили в режим установки, а смена показаний была только при следующем нажатии, а не сразу как сейчас? Может кто решал подобную задачу?
А это смотря с какой стороны посмотреть.Alexeyslav писал(а):Чем это лучше фиксации состояния кнопки по таймеру каждые 10мс?
Как можно потерять событие, происходящее реже, чем опрос этого события?fox15 писал(а): Ну и где тут будет фиксация по таймеру каждые 10 ms? В сложной программе мы рискуем "потерять" нажатие на кнопку, а событие не потеряешь!
На самом деле там нет ничего сложного. Две кнопки с квадратурной диаграммой переключений. Обе защищаются от дребезга как обычные кнопки, причем есть алгоритмы, которые сами по себе бездребезговые, поскольку интервал обработки как раз дает защиту от дребезга.Alexeyslav писал(а):С энкодером дело конечно сложнее...
Не как обычные кнопки! Там время нужно уменьшать, иначе не комфортно крутить энкодер.КРАМ писал(а):На самом деле там нет ничего сложного. Две кнопки с квадратурной диаграммой переключений. Обе защищаются от дребезга как обычные кнопки, причем есть алгоритмы, которые сами по себе бездребезговые, поскольку интервал обработки как раз дает защиту от дребезга.Alexeyslav писал(а):С энкодером дело конечно сложнее...
Я довольно часто ставлю механические энкодеры с осевой кнопкой в разные устройства и всегда и кнопка и энкодер висят на прерывании от системного таймера, совершенно не напрягая общий алгоритм устройства.
обработчик примитивный примерно десяток процессорных команд, обрабатывает только кнопки. Сложности на ровном месте если и есть то только от компаратора, но я ведь не использовал внешний компаратор в противном случае и алгоритм был бы другой или события от внешнего компаратора сидели бы на другом порту (ну сугубо индивидуально вариантов тысяча).Alexeyslav писал(а):Вобщем-то я с этим и не спорил, просто поставил под сомнение использование прерываний для считывания состояния кнопок. Жирно им будет, и необходимости такой нет. Это ведь нужен будет обработчик прерывания, и диспетчер в нем если прерывание происходит не только от кнопок но еще и от внешнего компаратора который использует тот же порт и одно прерывание вместе с кнопками... вобщем, сложности на ровном месте. А еще с приоритетами разобраться... прерывание от кнопки может возникнуть в неожиданный момент, когда надо ловить другое прерывание с минимальным временем реакции на него.
Код: Выделить всё
DDRB = 0b11111000;
PORTB= 0b00000111;
switch(count)
{
case 1:
display = 10;
break;
case 2:
display = 20;
break;
case 3:
display = 30;
break;
}
if(!(PINB&1)) // опрашиваем кнопку 1(+)
{
flag1=1; //кнопка нажата (устанавливаем флаг в 1)
_delay_ms(10); //задержка (защита от дребезга)
}
if((flag1==1 )&&(PINB&1)) //условие если кнопка была нажата а потом отпущена
{ count++; flag1=0; } // увеличиваем счетную переменную на единицу и сбрасываем флажок
if(!(PINB&2)) // опрашиваем кнопку 2(+)
{
Flag2=1; //кнопка нажата (устанавливаем флаг в 1)
_delay_ms(10); //задержка (защита от дребезга)
}
if(( Flag2==1 )&&(PINB&2)) //условие если кнопка была нажата о потом отпущена
{ count--; Flag2=0; } // уменьшаем счетную переменную на единицу и сбрасываем флажок
if(!(PINB&3)) // опрашиваем кнопку 3(+)
{
flag3=1; //кнопка нажата (устанавливаем флаг в 1)
_delay_ms(10); //задержка (защита от дребезга)
}
if(( flag3==1 )&&(PINB&3)) //условие если кнопка была нажата о потом отпущена
{ count++; flag3=0; }
if(count>3) count=1;
if(count<1) count=3;
Может надо так?-=eagle=- писал(а):...а третья ни в какую не хочет нажиматься...
Код: Выделить всё
if(!(PINB&4)) // опрашиваем кнопку 3(+)
{
flag3=1; //кнопка нажата (устанавливаем флаг в 1)
_delay_ms(10); //задержка (защита от дребезга)
}
if(( flag3==1 )&&(PINB&4)) //условие если кнопка была нажата о потом отпущена
{ count++; flag3=0; }