Помогите с обработкой кнопок через ADC в CVAVR

Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
akulov
Открыл глаза
Сообщения: 42
Зарегистрирован: Пн июн 06, 2011 13:18:00

Помогите с обработкой кнопок через ADC в CVAVR

Сообщение akulov »

Сразу оговорюсь, сильно не пинайте, в программировании я новичок.
Есть код обработки кнопок через ADC:

Код: Выделить всё

#define K5 0 
#define K4 118
#define K3 160
#define K2 182
#define K1 194   
#define K0 213 // для ненажатого состояния 

/*------ Выводы кнопок ----------*/
#define KEYt PINA.6
/*------ ----------*/
unsigned char read_adc(unsigned char adc_input);
char find = 0;

unsigned char KEYPRESS ()
{
unsigned char Key,KeyTmp;   // нажатая клавиша
delay_ms(35);
if(read_adc(6)<K0)
{
  delay_ms(15); //дребезг контактов
  KeyTmp=read_adc(6);
  if(KeyTmp<K0)
    {
    if(KeyTmp<K1){
        if(KeyTmp<K2){
            if(KeyTmp<K3){
              if(KeyTmp<K4)Key=3;
              else Key=4;}
            else Key=1;}
        else Key=2;}             
    else Key=5;
    }                                       
}
else Key=0;
        delay_ms(75);
    return(Key);     
    }

В непрерывном цикле:

Код: Выделить всё

if(PINA.5==0) find = 1; 
else find = 0;

Все работает нормально. Но мне нужно, чтобы при установленной переменной find==1 и нажатых кнопках K4 или К5, соответственно Key=3; или Key=4; отрабатывались непрерывно. А при find==0 - одинарно.
Не могу сообразить, как это сделать?
Аватара пользователя
Enigm
Говорящий с текстолитом
Сообщения: 1663
Зарегистрирован: Вт апр 03, 2012 20:36:41
Откуда: Сочи

Re: Помогите с обработкой кнопок через ADC в CVAVR

Сообщение Enigm »

А точнее задачу можно ?
Не совсем понятно, как это непрерывно и одинарно ?
akulov
Открыл глаза
Сообщения: 42
Зарегистрирован: Пн июн 06, 2011 13:18:00

Re: Помогите с обработкой кнопок через ADC в CVAVR

Сообщение akulov »

Enigm писал(а):А точнее задачу можно ?

Кнопки К4 и К5 управляют перестройкой частоты. При одинарном нажатии на кнопку, частота перестраивается +- на один шаг. А мне нужно, чтобы при установленном флаге find и одинарном нажатии на кнопку, частота перестраивалась автоматически до сброса флага (автопоск станции). Даже желательно, чтобы автопоиск включался не сразу, а при удержании кнопки в течении 1-2 секунд. Может, код не совсем удачный и его стоит переписать?
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Re: Помогите с обработкой кнопок через ADC в CVAVR

Сообщение zero648 »

Схему подключения кнопок посмотреть, было бы не плохо.
Аватара пользователя
Enigm
Говорящий с текстолитом
Сообщения: 1663
Зарегистрирован: Вт апр 03, 2012 20:36:41
Откуда: Сочи

Re: Помогите с обработкой кнопок через ADC в CVAVR

Сообщение Enigm »

Ну так в чем проблема ? сделайте условие где например find=1 or k1=чему там у вас.) и все .
А ваобще не понятно.
Ставте конкретно условия.
Что за переменая или порт ответственнен за вас счет и как он должен себя вести в разных услових.
akulov
Открыл глаза
Сообщения: 42
Зарегистрирован: Пн июн 06, 2011 13:18:00

Re: Помогите с обработкой кнопок через ADC в CVAVR

Сообщение akulov »

zero648 писал(а):Схему подключения кнопок посмотреть.

Key.jpg
(28.27 КБ) 373 скачивания

Enigm писал(а):сделайте условие где например find=1 or k1=чему там у вас.) Что за переменая..

Переменная-это частота. При нажатии на кнопку изменяется на один шаг. Пробовал
find=1 or k1=
и find=1 и k1=, не получается.
Аватара пользователя
Enigm
Говорящий с текстолитом
Сообщения: 1663
Зарегистрирован: Вт апр 03, 2012 20:36:41
Откуда: Сочи

Re: Помогите с обработкой кнопок через ADC в CVAVR

Сообщение Enigm »

Вы так и не уточнили ТЗ.
Задам пару вопросов.
1) переменая find откуда берется ? что ее переключает с 0 в 1 ?
2) какая перменная отвечает за остановку ? если это find, то какая переменая ответственна за распознавания срабатывания кнопки(как работать,сканировать по нажатиям или сканировать пока не изменится переменая на остановку)?
3) ну и последний вытекает из предыдущих, какая пиеременная отвечает за смену режима работы кнопок поиска( однократно или искать до остановки из вне)?
Возможно ответив на вопросы, вы и сами догадаетесь что надо делать )))
akulov
Открыл глаза
Сообщения: 42
Зарегистрирован: Пн июн 06, 2011 13:18:00

Re: Помогите с обработкой кнопок через ADC в CVAVR

Сообщение akulov »

Enigm писал(а):Задам пару вопросов...
Во первых переписал функцию опроса ADC, задал перед этим диапазоны срабатывания кнопок:

Код: Выделить всё

unsigned char KEYPRESS ()
{
unsigned char Key,KeyTmp,i;   // нажатая клавиша
  KeyTmp=read_adc(6);
    for (i=0;i<10;i++)      // програмный антидребезг контактов
       delay_ms(15);
  if (KeyTmp < K5_max)
   {
    if ((KeyTmp >= K5_min) && (KeyTmp <= K5_max)) Key=5;
    if ((KeyTmp >= K4_min) && (KeyTmp <= K4_max)) Key=2;
    if ((KeyTmp >= K3_min) && (KeyTmp <= K3_max)) Key=1;
    if ((KeyTmp >= K2_min) && (KeyTmp <= K2_max)) Key=4;
    if (KeyTmp <= K1_max) Key=3;
   }
    else Key = 0;

return Key; 
}
Переменная find устанавливается в 1, когда появляется 0 на входе порта и она же отвечает за остановку:

Код: Выделить всё

if(PINA.5==0) find = 1;
else find = 0;
за распознавание срабатывания кнопки отвечает переменная Key=3 и Key=4. Выдержка из кода:

Код: Выделить всё

tmp=KEYPRESS();
if(tmp)
  work=tmp;
     switch(work){
     ..........
   case 4:{ ..Freq=Freq-StepFreq;...}
   ...........
          work=0;
                  break;}
   case 3:{ ..Freq=Freq+StepFreq;...}
   ...........
          work=0;
                  break;} и т.д.
При однократном нажатии на кнопку 3 или 4, частота увеличивается или уменьшается на один шаг. Если кнопку держать нажатой, частота растет или уменьшается, пока удерживаешь кнопку нажатой. За смену режима работы кнопок поиска должна отвечать переменная find.
Если find==1, то при однократном нажатии на кнопку 3 или 4 (переменная Key=3 или Key=4) смена частоты (поиск) должна продолжаться непрерывно до остановки из вне (пока на PINA.5 не появится 1 и find будет=0.
К сожалению, знаний на это у меня не хватило, сам не догадался, что надо делать! Перепробовал все известные мне варианты, но УВЫ!
Аватара пользователя
Enigm
Говорящий с текстолитом
Сообщения: 1663
Зарегистрирован: Вт апр 03, 2012 20:36:41
Откуда: Сочи

Re: Помогите с обработкой кнопок через ADC в CVAVR

Сообщение Enigm »

Тоесть если я правильно понял , То выглядит это так.
Если на порту 5 сидит 0, то кнопки работают в ручном режиме. (по каждому нажатию или ее удержанию в ручную)
После того как на порт 5 приходит 1 то при нажатии на кнопку, включается режим сканирования, и будет сканировать до тех пор пока на порту 5 не появится 0, скан останавливается и переходит опять в ручной режим .

Я правильно понял логику работы?
Если да то попробую реализовать вашу затею.
Proteus используете ?
Если нет то очень советую.
akulov
Открыл глаза
Сообщения: 42
Зарегистрирован: Пн июн 06, 2011 13:18:00

Re: Помогите с обработкой кнопок через ADC в CVAVR

Сообщение akulov »

Enigm писал(а):Я правильно понял логику работы?
Proteus используете ?
Правильно, буду очень благодарен! А в Proteus я в основном и моделирую, очень помогает на этапе отладки.
Аватара пользователя
Enigm
Говорящий с текстолитом
Сообщения: 1663
Зарегистрирован: Вт апр 03, 2012 20:36:41
Откуда: Сочи

Re: Помогите с обработкой кнопок через ADC в CVAVR

Сообщение Enigm »

Еще вопрос, когда идет автоматическое сканирование, на кнопки+ и - реакция должна быть ? (тоесть не останавливая автомата менять направление , например с вычинания, на сложение )
А можно листинг программы целиком, начиная от АЦП и заканчивая обработками кнопок, а то не совсем понятно в какой последовательности у вас команды и куда что можно всунуть.
И какая у вас версия протэуса ? у меня есть две, 7.8 и 7.10 .
akulov
Открыл глаза
Сообщения: 42
Зарегистрирован: Пн июн 06, 2011 13:18:00

Re: Помогите с обработкой кнопок через ADC в CVAVR

Сообщение akulov »

Enigm писал(а):на кнопки+ и - реакция должна быть
Нет.
Версия Протеус у меня 7.10, хотя в интернете есть и 7.11. Пока ее не ставлю, подожду 8.0, демо уже на сайтах есть. Листинг:

Код: Выделить всё

#define ADC_VREF_TYPE 0x60 
char find = 0;
#define K5_min 115
#define K5_max 130
#define K4_min 87
#define K4_max 100
#define K3_min 64
#define K3_max 78
#define K2_min 41
#define K2_max 49
#define K1_max 10

unsigned char read_adc(unsigned char adc_input)
{
ADMUX=adc_input|ADC_VREF_TYPE;
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCH;
}

unsigned char KEYPRESS ()
{
unsigned char Key,KeyTmp,i; // нажатая клавиша
KeyTmp=read_adc(6);
for (i=0;i<15;i++) // програмный антидребезг контактов
delay_ms(15);
if (KeyTmp < K5_max)
{
if ((KeyTmp >= K5_min) && (KeyTmp <= K5_max)) Key=5;
if ((KeyTmp >= K4_min) && (KeyTmp <= K4_max)) Key=2;
if ((KeyTmp >= K3_min) && (KeyTmp <= K3_max)) Key=1;
if ((KeyTmp >= K2_min) && (KeyTmp <= K2_max)) Key=4;
if (KeyTmp <= K1_max) Key=3;
}
else Key = 0;
return Key;
}

while(1)
{
tmp=KEYPRESS();
if(tmp)
work=tmp;

switch(work){

case 5:{ // запись
spause=10;
tDump=Dump;
tStepFreq=StepFreq;
TUNE[Dump]=FFreq;
lcd_gotoxy(5,0);
lcd_putsf(Mes1);
delay_ms(1500);
lcd_gotoxy(2,0);
lcd_putsf("ch");
ShowFreq(FFreq);
workmem=1;
work=0;
break;
}

case 4:{ // уменьшение частоты
// if(FFreq<=7400)StepFreq=3;
if(FFreq>=8750)StepFreq=5;
if(FFreq==8750){FFreq=7400;StepFreq=3;}
if(FFreq<=6581)FFreq=10803;
FFreq=FFreq-StepFreq;
DLL_Freq(FFreq,StepFreq);
ShowFreq(FFreq);
work=0;
break;}

case 3:{ // увеличение частоты
if(FFreq<=7400)StepFreq=3;
if(FFreq>=8750)StepFreq=5;
if(FFreq==7400){FFreq=8750;StepFreq=5;}
if(FFreq>=10800)FFreq=6576
FFreq=FFreq+StepFreq;
DLL_Freq(FFreq,StepFreq);
ShowFreq(FFreq);
work=0;
break;}

case 1:{ // канал+
if(Dump++==20)Dump=1;
lcd_gotoxy(0,0);
des = (Dump / 10) % 10;
ed = Dump % 10;
lcd_putchar(des+0x30);
lcd_putchar(ed+0x30);
FFreq=TUNE[Dump];
if(FFreq<=7400)StepFreq=3;
else StepFreq=5;
DLL_Freq(FFreq,StepFreq);
ShowFreq(FFreq);
work=0;
break;}

case 2:{ // канал-
if(Dump--==1)Dump=20;
lcd_gotoxy(0,0);
des = (Dump / 10) % 10;
ed = Dump % 10;
lcd_putchar(des+0x30);
lcd_putchar(ed+0x30);
FFreq=TUNE[Dump];
if(FFreq<=7400)StepFreq=3;
else StepFreq=5;
DLL_Freq(FFreq,StepFreq);
ShowFreq(FFreq);
work=0;
break;}
default:work=0;break;
}
}
Аватара пользователя
Enigm
Говорящий с текстолитом
Сообщения: 1663
Зарегистрирован: Вт апр 03, 2012 20:36:41
Откуда: Сочи

Re: Помогите с обработкой кнопок через ADC в CVAVR

Сообщение Enigm »

Вопрос.
Зачем вы обьявляете кучу констант ?
Если они неизменны и ни где больше не используются ?
Не проще сразу циферки вписать ?
if ((KeyTmp >= 115) && (KeyTmp <= 130)) Key=5;
В чем смысл такого неоправданного расхода памяти ?
Ставил себе на пробу 8 протеус, блин там все обьеденили неудобно стало пипец, прийдется привыкать.
Совесть
Встал на лапы
Сообщения: 106
Зарегистрирован: Пн мар 26, 2012 05:25:06

Re: Помогите с обработкой кнопок через ADC в CVAVR

Сообщение Совесть »

Мне даже интересно стало, это вы в протеусе углядели увеличенный объем памяти? подсказал кто? или ваши могучие извилины мозга помогли прийти к такому выводу?
akulov
Открыл глаза
Сообщения: 42
Зарегистрирован: Пн июн 06, 2011 13:18:00

Re: Помогите с обработкой кнопок через ADC в CVAVR

Сообщение akulov »

Вот и возник резонный вопрос, как лучше делать. Задавать константы, или непосредственно вписывать значения? Сколько пересмотрел исходников, везде по разному. Есть ли на этот счет однозначный ответ?
Совесть
Встал на лапы
Сообщения: 106
Зарегистрирован: Пн мар 26, 2012 05:25:06

Re: Помогите с обработкой кнопок через ADC в CVAVR

Сообщение Совесть »

Есть рекомендации использовать define, но опять же без фанатизма. Все хорошо к месту.
В случае задания диапазонов АЦП лично я бы обошелся без define. Почему? Встречаются в коде только в одном месте, при этом их смысл легко понять.
Аватара пользователя
Enigm
Говорящий с текстолитом
Сообщения: 1663
Зарегистрирован: Вт апр 03, 2012 20:36:41
Откуда: Сочи

Re: Помогите с обработкой кнопок через ADC в CVAVR

Сообщение Enigm »

Совесть писал(а):Мне даже интересно стало, это вы в протеусе углядели увеличенный объем памяти? подсказал кто? или ваши могучие извилины мозга помогли прийти к такому выводу?

А ваш могучий мозг, вместо издевок, мог бы и выдать человеку решение его задачи )))

Да я упустил из виду что оно у него через #define и память не сожрет.

Но и не вижу смысла этого делать, когда используется всего в одном месте.

Передаю вам эстафету помощи.
Аватара пользователя
Барсик
Друг Кота
Сообщения: 3459
Зарегистрирован: Ср сен 27, 2006 16:18:57

Re: Помогите с обработкой кнопок через ADC в CVAVR

Сообщение Барсик »

Вот здесь: viewtopic.php?p=1550161#p1550161 Я выкладывал исходник: download/file.php?id=134752
Там кнопки подключены к АЦП. Схема подключения кнопок другая. Схема и номиналы резисторов описаны в комментариях. Всего там может быть до 7 кнопок.
phanis
Вымогатель припоя
Сообщения: 513
Зарегистрирован: Сб фев 19, 2011 18:04:08
Откуда: Татарстан, пос. Актюбинский
Контактная информация:

Re: Помогите с обработкой кнопок через ADC в CVAVR

Сообщение phanis »

Если кнопок очень много можно использовать метод деления пополам. И не нужно будет задавать максимум/минимум просто среднее.Главное расположить по порядку .
Спойлер

Код: Выделить всё

const unsigned int SQR[256]= {
0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169,
196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 625,
 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, 1296, 1369,
 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 2116, 2209, 2304, 2401,
 2500, 2601, 2704, 2809, 2916, 3025, 3136, 3249, 3364, 3481, 3600, 3721,
 3844, 3969, 4096, 4225, 4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329,
 5476, 5625, 5776, 5929, 6084, 6241, 6400, 6561, 6724, 6889, 7056, 7225,
 7396, 7569, 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025, 9216, 9409,
 9604, 9801, 10000, 10201, 10404, 10609, 10816, 11025, 11236, 11449, 11664,
 11881, 12100, 12321, 12544, 12769, 12996, 13225, 13456, 13689, 13924, 14161,
 14400, 14641, 14884, 15129, 15376, 15625, 15876, 16129, 16384, 16641, 16900,
 17161, 17424, 17689, 17956, 18225, 18496, 18769, 19044, 19321, 19600, 19881,
 20164, 20449, 20736, 21025, 21316, 21609, 21904, 22201, 22500, 22801, 23104,
 23409, 23716, 24025, 24336, 24649, 24964, 25281, 25600, 25921, 26244, 26569,
 26896, 27225, 27556, 27889, 28224, 28561, 28900, 29241, 29584, 29929, 30276,
 30625, 30976, 31329, 31684, 32041, 32400, 32761, 33124, 33489, 33856, 34225,
 34596, 34969, 35344, 35721, 36100, 36481, 36864, 37249, 37636, 38025, 38416,
 38809, 39204, 39601, 40000, 40401, 40804, 41209, 41616, 42025, 42436, 42849,
 43264, 43681, 44100, 44521, 44944, 45369, 45796, 46225, 46656, 47089, 47524,
 47961, 48400, 48841, 49284, 49729, 50176, 50625, 51076, 51529, 51984, 52441,
 52900, 53361, 53824, 54289, 54756, 55225, 55696, 56169, 56644, 57121, 57600,
 58081, 58564, 59049, 59536, 60025, 60516, 61009, 61504, 62001, 62500, 63001,
 63504, 64009, 64516, 65025  };

unsigned char SQR_ (unsigned int D)
{

unsigned char i;
unsigned char toLeft=0;
unsigned char toRight=255;
unsigned char pol0=0;
unsigned char pol1=0;

   

while (1)
   {
   
   
      i=(toLeft+toRight) >>1;
      if (D < SQR[i])
      {
         toRight= i-1;
         pol1 = i;
         
      }
      else if (D > SQR[i])
      {
         toLeft= i+1;
         pol0=i;
         
      }
      if ((((pol0-pol1)<2))||(toLeft > toRight)||(D == SQR[i]) ) break;
      
   }
return i;
   
}
Последний раз редактировалось phanis Пн фев 25, 2013 16:39:14, всего редактировалось 1 раз.
akulov
Открыл глаза
Сообщения: 42
Зарегистрирован: Пн июн 06, 2011 13:18:00

Re: Помогите с обработкой кнопок через ADC в CVAVR

Сообщение akulov »

Барсик писал(а):Вот здесь:
Спасибо. Попробую разобраться.
Ответить

Вернуться в «Периферия»