реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> динамический опрос кнопок, запутался окончательно
Anjey_N
сообщение Mar 7 2008, 13:39
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 80
Регистрация: 12-01-07
Из: Энергодар Украина
Пользователь №: 24 374



Всем привет! Вот пришёл просить помощи. Задача несложная, только я вконец уже запутался.
Есть МК ATmega16, АЛС, индикация динамическая, кнопки М, +, -
Есть массив переменных set_temp[3]. Пока кнопки не нажаты, происходит каждые 5 сек поочерёдный вывод на индикатор содержимого массива. ( с этим я разобрался работает). При нажати на М включается режим редактирования, 2 мл разряда индикатора мигают. Кнопками + и - изменяется содержимое элемента массива. Последующее нажатие М приводит к переходу к следующему элементу массива.
Если все элементы отредактированы - записать в EEPROM.

Кто что посоветует, или поможет кодом. Свой я надлежаще оформлю и выставлю позже. Пишу на Си в ИАРе.
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 7 2008, 13:50
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



А вопрос-то в чем - как кнопки опрашивать?

Кнопки нужно опрашивать одновременно с выводом на индикатор - настроить PA7 на вход, включить встроенный pull-up (хотя я бы поставил внешний) и смотреть состояние порта с некоторой задержкой после начала вывода очередной цифры.
Go to the top of the page
 
+Quote Post
vet
сообщение Mar 7 2008, 13:59
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32



в прерывании таймера - опрос кнопок, антидребезг, установка флагов нажатия кнопок, динамическая индикация.
в главном цикле - логика обработки флагов нажатых кнопок: смена содержимого ячейки, индекса текущей ячейки, запись в EEPROM.


--------------------
Главная линия этого опуса ясна мне насквозь!
Go to the top of the page
 
+Quote Post
Anjey_N
сообщение Mar 7 2008, 13:59
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 80
Регистрация: 12-01-07
Из: Энергодар Украина
Пользователь №: 24 374



Цитата(aaarrr @ Mar 7 2008, 17:50) *
А вопрос-то в чем - как кнопки опрашивать?

Кнопки нужно опрашивать одновременно с выводом на индикатор - настроить PA7 на вход, включить встроенный pull-up (хотя я бы поставил внешний) и смотреть состояние порта с некоторой задержкой после начала вывода очередной цифры.


я так исделал, код кнопки я получаю, не получается дальше. Не сохраняются данные в памяти, содержимое масива при длительном нажатии на кнопку увеличивается/уменьшается неравномерно, иногда останавливается.
Если вам не сложно и есть желание можете написать свой код Хочется посмотреть! beer.gif
Go to the top of the page
 
+Quote Post
algidim
сообщение Mar 7 2008, 15:49
Сообщение #5


Частый гость
**

Группа: Участник
Сообщений: 160
Регистрация: 5-04-06
Из: Москва
Пользователь №: 15 847



У вас схема не может работать по определению, ну подумайте сами. В тот момент, когда вы выставляете на PA7 лог 1 и опрашиваете PD0-PD2, с челью узнать нажатую кнопку, вы получите на PD0-PD2 в любом случае лог 1, даже если кнопки не нажаты, если конечно, у вас подключены встроенные подтягивающее резисторы. Если они не подключены то результат опроса будет не предсказуем, похоже, у вас такая ситуация. Просто, прежде чем проектировать подобные схемы, нужно чётко представлять логику её работы.
Go to the top of the page
 
+Quote Post
rezident
сообщение Mar 7 2008, 16:57
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Поскольку для динамической индикации используется "бегущая единица", а не "бегущий ноль", то диоды нужно развернуть анодами к сканирующим пинам МК и катодами к кнопкам. А на PA7 поставить pull-down (резистор к общему проводу).
Насчет алгоритмов сканирования и устранения дребезга здесь писали настолько часто, что еще один раз пальцы об клаву мозолить уже нет никакого желания. sad.gif Пользуйтесь поиском по форуму!
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 7 2008, 17:00
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(rezident @ Mar 7 2008, 19:57) *
Поскольку для динамической индикации используется "бегущая единица", а не "бегущий ноль...

С чего бы это вдруг? Посмотрите на схему - там p-n-p транзисторы.
Go to the top of the page
 
+Quote Post
Anjey_N
сообщение Mar 7 2008, 17:46
Сообщение #8


Частый гость
**

Группа: Участник
Сообщений: 80
Регистрация: 12-01-07
Из: Энергодар Украина
Пользователь №: 24 374



Цитата(algidim @ Mar 7 2008, 19:49) *
У вас схема не может работать по определению, ну подумайте сами. В тот момент, когда вы выставляете на PA7 лог 1 и опрашиваете PD0-PD2, с челью узнать нажатую кнопку, вы получите на PD0-PD2 в любом случае лог 1, даже если кнопки не нажаты, если конечно, у вас подключены встроенные подтягивающее резисторы. Если они не подключены то результат опроса будет не предсказуем, похоже, у вас такая ситуация. Просто, прежде чем проектировать подобные схемы, нужно чётко представлять логику её работы.


Не совсем так. Эта схема работает. И не только в симуляторе, но и на реальном контроллере, упрравление идёт через JTAG.
PA7 настроен на вход с подтягивающим резистором. Когда нажата кнопка, лог. нуль через диод, замкнутую кнопку подаётся на вход PA7. Запоминается номер вывода и взводится флаг антидребезга на 20 мсек для устранения дребезга. После этого программа улучает момент, когда лог. нуль появляется на том выводе, который она запомнила перед пднятием флага антидребезга. Если кнопка замкнута, тогда номер вывода = запомненному номеру и программа возвращает номер вывода, те номер кнопки. Может туманно объяснил, смотри код

// Сканирование клавиатуры
unsigned char Scan_Key(void)
{
static unsigned char pk=0;
static unsigned char Key_Buf;
if(TESTBIT(flag,DREBEZG)) //
{
if(cnt_dr!=0)
{
delay_timer1(MSEC(1)); // задержка 1 мсек
// delay_ms(1);
cnt_dr--;
}
else
{
cnt_dr=CNT_DR_MAX;
CLEARBIT(flag,DREBEZG);
BUZER=0; // снять звуковой сигнал
}
}
else
{
switch (h)
{
case 0 : if (!KEY) // кнопка нажата!
{
SETBIT(flag,DREBEZG); // взвести флаг антидребезга
BUZER=1; // подать звуковой сигнал
Key_Buf=n; // запомнить номер кнопки
h++; // увеличить счётчик прохождений
}
pk=0; break;
case 1 : if(n==Key_Buf)
{
if (!KEY)
{
SETBIT(key,n); // запоминаем нажатую кнопку!
pk=key;
SETBIT(flag,KEYBOARD);
}
else // если кнопка отжата,
{ // то проверяем - действительно ли
SETBIT(flag,DREBEZG); // взводим флаг антидребезга
h++; // и увеличиваем счётчик прохождений
}
}
break;
case 2 : if((KEY)&&(Key_Buf==n)) // если кнопка отжата и её
{ // номер соответствует записанному в буфер
Key_Buf=0xFF; // запись в буфер неиспользуемого числа
h=0; // обнуление счётчика прохождений
pk=0;
key=0;
CLEARBIT(flag,BUSY);
}
break;
default: break;
}
}
return pk;
}

Сообщение отредактировал Anjey_N - Mar 7 2008, 17:47
Go to the top of the page
 
+Quote Post
algidim
сообщение Mar 7 2008, 18:27
Сообщение #9


Частый гость
**

Группа: Участник
Сообщений: 160
Регистрация: 5-04-06
Из: Москва
Пользователь №: 15 847



Да я извиняюсь, не досмотрел, схема рабочая, просто определять нажатие кнопок нужно в момент открытия любого транзистора. Ошибка в коде. А уж разбираться в вашем коде придется вам самому, за вас врят ли кто нибудь это сделает. Алгоритм сканирования кнопок и динамической индикации довольно прост.
Go to the top of the page
 
+Quote Post
rezident
сообщение Mar 7 2008, 19:47
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(aaarrr @ Mar 7 2008, 22:00) *
С чего бы это вдруг? Посмотрите на схему - там p-n-p транзисторы.
Миль пардон! Не стал увеличивать картинку и поэтому не рассмотрел направление стрелок. За такой стиль рисования схем наказывать нужно wink.gif
Go to the top of the page
 
+Quote Post
Anjey_N
сообщение Mar 10 2008, 06:19
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 80
Регистрация: 12-01-07
Из: Энергодар Украина
Пользователь №: 24 374



Вот приготовил свой код на рассмотрение. Критикуйте! Можете потыкать меня носом в ошибки!
Прикрепленные файлы
Прикрепленный файл  Keys.rar ( 36.15 килобайт ) Кол-во скачиваний: 533
 
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Mar 10 2008, 21:48
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Так, на скорую руку писал, и без проверки, но идея вроде понятна должна быть. Если нет, то спрашивай.
Прикрепленные файлы
Прикрепленный файл  key.zip ( 1.36 килобайт ) Кол-во скачиваний: 125
 
Go to the top of the page
 
+Quote Post
Anjey_N
сообщение Mar 11 2008, 18:19
Сообщение #13


Частый гость
**

Группа: Участник
Сообщений: 80
Регистрация: 12-01-07
Из: Энергодар Украина
Пользователь №: 24 374



Цитата(SasaVitebsk @ Mar 11 2008, 01:48) *
Так, на скорую руку писал, и без проверки, но идея вроде понятна должна быть. Если нет, то спрашивай.


не пошёл Ваш код. переменная антидребезга постоянно сбрасывается в исходную величину. А Вы мой код не смотрели?
Go to the top of the page
 
+Quote Post
SasaVitebsk
сообщение Mar 12 2008, 09:28
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521



Цитата(Anjey_N @ Mar 11 2008, 22:19) *
не пошёл Ваш код. переменная антидребезга постоянно сбрасывается в исходную величину. А Вы мой код не смотрели?

Смотрел, но ваш мне показался излишне громоздким. А что значит "не пошёл"? Там же 5 операторов. Идея то понятна? Посмотрите где я хомутнул. Если вечером время будет, то сам гляну.

Индикация то работает надеюсь?
Go to the top of the page
 
+Quote Post
rimpocha
сообщение Mar 12 2008, 19:08
Сообщение #15


Частый гость
**

Группа: Свой
Сообщений: 82
Регистрация: 6-03-07
Из: Новосибирск, Seattle
Пользователь №: 25 935



http://www.embedded.com/columns/breakpoint...equestid=203518

Вот! Прелестнейшая антидребезговая утилита от Jack Ganssle

По таймеру это ей жирно, я решил. Дергаю из мэйнлупа -- справляется на отлично.
// Service routine called by a timer interrupt
bool_t DebounceSwitch2()
{
static uint16_t State = 0; // Current debounce status
State=(State<<1) | !RawKeyPressed() | 0xe000;
if(State==0xf000)return TRUE;
return FALSE;
}

Подробное описание, в статье на английском. Если есть необходимость, переведу.


--------------------
НГТУ, Физико-технический факультет, кафедра Лазерных систем
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 17th July 2025 - 22:07
Рейтинг@Mail.ru


Страница сгенерированна за 0.01531 секунд с 7
ELECTRONIX ©2004-2016