Страница 1 из 2

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

Добавлено: Сб фев 23, 2013 00:29:23
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 - одинарно.
Не могу сообразить, как это сделать?

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

Добавлено: Сб фев 23, 2013 07:28:13
Enigm
А точнее задачу можно ?
Не совсем понятно, как это непрерывно и одинарно ?

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

Добавлено: Сб фев 23, 2013 10:46:49
akulov
Enigm писал(а):А точнее задачу можно ?

Кнопки К4 и К5 управляют перестройкой частоты. При одинарном нажатии на кнопку, частота перестраивается +- на один шаг. А мне нужно, чтобы при установленном флаге find и одинарном нажатии на кнопку, частота перестраивалась автоматически до сброса флага (автопоск станции). Даже желательно, чтобы автопоиск включался не сразу, а при удержании кнопки в течении 1-2 секунд. Может, код не совсем удачный и его стоит переписать?

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

Добавлено: Сб фев 23, 2013 11:05:26
zero648
Схему подключения кнопок посмотреть, было бы не плохо.

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

Добавлено: Сб фев 23, 2013 18:24:26
Enigm
Ну так в чем проблема ? сделайте условие где например find=1 or k1=чему там у вас.) и все .
А ваобще не понятно.
Ставте конкретно условия.
Что за переменая или порт ответственнен за вас счет и как он должен себя вести в разных услових.

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

Добавлено: Сб фев 23, 2013 19:52:08
akulov
zero648 писал(а):Схему подключения кнопок посмотреть.

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

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

Переменная-это частота. При нажатии на кнопку изменяется на один шаг. Пробовал
find=1 or k1=
и find=1 и k1=, не получается.

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

Добавлено: Сб фев 23, 2013 20:48:08
Enigm
Вы так и не уточнили ТЗ.
Задам пару вопросов.
1) переменая find откуда берется ? что ее переключает с 0 в 1 ?
2) какая перменная отвечает за остановку ? если это find, то какая переменая ответственна за распознавания срабатывания кнопки(как работать,сканировать по нажатиям или сканировать пока не изменится переменая на остановку)?
3) ну и последний вытекает из предыдущих, какая пиеременная отвечает за смену режима работы кнопок поиска( однократно или искать до остановки из вне)?
Возможно ответив на вопросы, вы и сами догадаетесь что надо делать )))

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

Добавлено: Вс фев 24, 2013 00:29:48
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.
К сожалению, знаний на это у меня не хватило, сам не догадался, что надо делать! Перепробовал все известные мне варианты, но УВЫ!

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

Добавлено: Вс фев 24, 2013 01:42:33
Enigm
Тоесть если я правильно понял , То выглядит это так.
Если на порту 5 сидит 0, то кнопки работают в ручном режиме. (по каждому нажатию или ее удержанию в ручную)
После того как на порт 5 приходит 1 то при нажатии на кнопку, включается режим сканирования, и будет сканировать до тех пор пока на порту 5 не появится 0, скан останавливается и переходит опять в ручной режим .

Я правильно понял логику работы?
Если да то попробую реализовать вашу затею.
Proteus используете ?
Если нет то очень советую.

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

Добавлено: Вс фев 24, 2013 03:14:09
akulov
Enigm писал(а):Я правильно понял логику работы?
Proteus используете ?
Правильно, буду очень благодарен! А в Proteus я в основном и моделирую, очень помогает на этапе отладки.

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

Добавлено: Вс фев 24, 2013 22:53:56
Enigm
Еще вопрос, когда идет автоматическое сканирование, на кнопки+ и - реакция должна быть ? (тоесть не останавливая автомата менять направление , например с вычинания, на сложение )
А можно листинг программы целиком, начиная от АЦП и заканчивая обработками кнопок, а то не совсем понятно в какой последовательности у вас команды и куда что можно всунуть.
И какая у вас версия протэуса ? у меня есть две, 7.8 и 7.10 .

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

Добавлено: Пн фев 25, 2013 01:04:38
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;
}
}

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

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

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

Добавлено: Пн фев 25, 2013 11:03:47
Совесть
Мне даже интересно стало, это вы в протеусе углядели увеличенный объем памяти? подсказал кто? или ваши могучие извилины мозга помогли прийти к такому выводу?

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

Добавлено: Пн фев 25, 2013 13:02:21
akulov
Вот и возник резонный вопрос, как лучше делать. Задавать константы, или непосредственно вписывать значения? Сколько пересмотрел исходников, везде по разному. Есть ли на этот счет однозначный ответ?

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

Добавлено: Пн фев 25, 2013 13:28:21
Совесть
Есть рекомендации использовать define, но опять же без фанатизма. Все хорошо к месту.
В случае задания диапазонов АЦП лично я бы обошелся без define. Почему? Встречаются в коде только в одном месте, при этом их смысл легко понять.

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

Добавлено: Пн фев 25, 2013 14:36:52
Enigm
Совесть писал(а):Мне даже интересно стало, это вы в протеусе углядели увеличенный объем памяти? подсказал кто? или ваши могучие извилины мозга помогли прийти к такому выводу?

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

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

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

Передаю вам эстафету помощи.

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

Добавлено: Пн фев 25, 2013 15:30:34
Барсик
Вот здесь: viewtopic.php?p=1550161#p1550161 Я выкладывал исходник: download/file.php?id=134752
Там кнопки подключены к АЦП. Схема подключения кнопок другая. Схема и номиналы резисторов описаны в комментариях. Всего там может быть до 7 кнопок.

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

Добавлено: Пн фев 25, 2013 16:26:07
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;
   
}

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

Добавлено: Пн фев 25, 2013 16:38:56
akulov
Барсик писал(а):Вот здесь:
Спасибо. Попробую разобраться.