Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Меню на LCD 16х2 (Си WinAVR)+5кнопок
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
Кастусь Рыжов
Нужно написать меню на Си, Атмега16 +5кнопок +ЖКИ 16х2
Меня интересует сам принцип организации меню и какие средства языка Си лучше использовать для написания меню
Опыта в Си мизер, ткните пальцем для направления верного или может у кого наработки есть, поделитесь для примера, посмотреть исходник. Заранее спасибо всем откливнувшимся. (использую Си компилятор WinAVR и AVR Studio)
ЗЫ: может не умею искать, но поис по форуму у меня не увенчался успехом smile3046.gif
zltigo
Цитата(Кастусь Рыжов @ Aug 9 2009, 18:12) *
может не умею искать, но поис по форуму у меня не увенчался успехом smile3046.gif

Тогда продолжайте учиться искать. Тема на этом форуме избитая, не говоря уже о AVR-овском Butterfly
_Pasha
Меню - разные бывают. Чаще в таких случаях - редактирование параметров и какие-то автонастройки. А у Вас ? А то ведь объять необъятное - много писанины.
Vishv
Да не нужно искать специальные средства языка - их просто нет. А принцип организации меню у Вас есть - посмотрите на свой сотовый телефон!
Кастусь Рыжов
Народ, извиняюсь за размножение избитых тем. сильно не бейте maniac.gif Порылся и похожие темы нашёл .
Слышал, что для меню предпочтительнее работать с указателями на функцию, звучит классно, но вот видеть этого зверя -не видел. Про указатели читал, до указателей на функцию не дошёл. Может кто даст кусочек кода где применяется указатель на функцию. Я так понимаю по нажатии клавиш проще изменять значение указателя, а по нему ссылаемся на функцию, которая определяет алгоритм и работу следующего пункта меню. Поправьте, если не так понял.
Пошел Кернигана читать smile3009.gif Всем спасибо
zltigo
Цитата(Кастусь Рыжов @ Aug 9 2009, 20:01) *
Про указатели читал, до указателей на функцию не дошёл.

Без разницы - и в том и другом случае это адрес.
ZVE
Цитата(Кастусь Рыжов @ Aug 9 2009, 20:01) *
Слышал, что для меню предпочтительнее работать с указателями на функцию, звучит классно, но вот видеть этого зверя -не видел.

Смотрите:
Код
/*Пример использования массива указателей на функцию, удобного для обслуживания меню */

void function_0(int a);
void function_1(int b);
void function_2(int c);

// объявляем масив из 3 указателей на функции которые имеют параметр целого типа и не
// возвращают значения
void (*f[3])(int) = (function_0, function_1, function_2);

int choice, number;

main ()
{
  //  
  (*f[choice]) (number); //вызываем функцию под номером choice и передаем ей значение number
  //
}
void function_0 (int a)
{
   //
}

void function_1 (int b)
{
  //
}

void function_2 (int c)
{
  //
}
ARV
я для многих проектов с меню приспособился делать так.
1. оформляю каждый функциональный режим в виде отдельного файла-модуля, в котором обязательно есть функция вывода на дисплей и функция обработки нажатой кнопки.
2. сами функуии опроса кнопок (т.е. возврат кода нажатой) и управление дисплеем оставляю в основном модуле (непринципиально - можно и в отдельных).
3. в основном модуле создаю массив структур по числу разных режимов (читай - пунктов меню), в структурах у меня адреса функций вывода и обработки кнопок всех режимов - см. выше.
4. основной модуль в сущности сводится при этом к примерно такому (упрощенно):
Код
mode = 0; // начальный режим
while(1){
   key = get_key();
   mode = modes_table[mode].do_key(key); // обработка нажатой кнопки соответствующим модулем
   modes_table[mode].do_display(); // вывод на дисплей соответствующим модулем
}

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

спецы, я думаю, сразу увидят в этом некое подобие объектно-ориентированного подхода: модуль как бы класс, в нем метод вывода и метод обрабтки кнопок, иногда конструктор и деструктор smile.gif на С++ естественно это красивее и логичнее, но и на Си неплохо. главное, достаточно просто масштабируется проект: добавление очередного режима сводится к написанию очередного модуля и заполнению соответствующего элемента массива с указателями на функции...

P.S. извиняюсь, если написал путано - думал, описать принцип будет просто, а вышло - не очень....
Scanner
Цитата(zltigo @ Aug 9 2009, 20:33) *
Тогда продолжайте учиться искать. Тема на этом форуме избитая, не говоря уже о AVR-овском Butterfly

Тоже не смог найти темы - помогите ссылками! Заранее спасибо.
Legotron
Цитата(Scanner @ Sep 7 2009, 23:58) *
Тоже не смог найти темы - помогите ссылками! Заранее спасибо.

Внесу свои 5 копеек.
Я решал задачу построения и обработки меню следующими способами:
1 способ - аля AVR Butterfly
Качаете исходники и по 5 раз перечитываете их в отношении меню (я именно так и делал, когда-то давно, сразу понять принцип было тяжело smile.gif ) но у меня был сам батерфлай, поэтому мне было проще.
Какие плюсы на мой взгляд:
1. Красивая организация кода
2. Достаточно просто прослеживается логика
3. Всё написано на чистом С
2 способ - жесткий самопал smile.gif
Подходит для совсем маленьких меню, ~10-20 пунктов.
Просто пишите конструкции switch, if, else
Для простых меню, которые не подразумевается расширять - то что надо, писать быстро, код получается читабельным (повторюсь, только для маленьких меню!)
3 способ - мой любимый biggrin.gif (да простят меня гуру) - Visual State Machine
IAR Visual State
Quantum Leaps (сложнее и мощнее)
Начну с плюсов на примере IAR VS:
Если не брать в расчет сколько времени нужно потратить чтобы ваш конечный автомат заработал нормально, ощущение когда всё правильно работает с Deep-state и Shallow-state логикой - просто поросячий восторг!!!
Рисуете графическую UML-диаграмму своего меню (оооо-да всё перед глазами, сразу видно biggrin.gif , несомненный плюс)
Симулируете свою диаграмму в реальном времени!!! просто жмёте кнопки событий, видите как работают таймеры таймаутов и прочие-прочие сладости..
Отлаживаете свою диаграмму в железе в IAR-e, я так отладил коммуникационный протокол по RS-485 прямо под JTAG. Тоже детский восторг вызывает, скажу честно.
Всё что вам нужно - это добавить несколько авто-сгенерированных файлов в свою программу и немного во всё это воткнуться...
Также поддерживает C++.. там тоже есть прелести..
Есть очереди, ну и многое другое, копаться можно долго.
Минусы я вижу в том что это слишком долго настраивается и изучается, по сравнению со способом 2 день и ночь.
Также возможны трудно уловимые баги самой программы, на которые можно наткнуться..
Вообщем сейчас уже этой штукой не пользуюсь для меню, но время потраченное на ее освоение не жаль, если бы мне приходилось очень часто писать конечные автоматы, я бы по сей день бы пользовался, а так многое забывается и приходиться тратить слишком много времени на то, чтобы вспомнить.

P.S. Вообщем, мои 5 копеек smile.gif

Добавлено:
Не подумайте что IAR VS можно использовать только с IAR! просто в ИАРе есть дебаггер для визуал стэйт. А так подходит для любых ANSI C компиляторов.
zltigo
Цитата(Legotron @ Sep 8 2009, 16:04) *
если бы мне приходилось очень часто писать конечные автоматы, я бы по сей день бы пользовался....

Вся эта бодяга с Visual State на самом деле подходит для ОЧЕНЬ простых автоматов проектируемых, что называется тупо в лоб. Если состояний много, воздействий еще больше - поведение становится формально трудно описуемым нужно добавлять элементы размытой логики... Вся эта красота от IAR идет лесом. Проверено на собственной шкуре года четыре назад - простое и так пишется просто а сложное с этой приблудой только сложнее sad.gif


Цитата(Legotron @ Sep 8 2009, 16:04) *
1 способ - аля AVR Butterfly

Да, уже поминал в начале топика в качестве примера. Особого пиетета не стоит (ну разве только по отношению к коду генеримому IAR VS smile.gif ), но достаточно добротно.
Dog Pawlowa
А я вот пришел к макросам описания состояний и доволен.
Переходы между состояниями - ручками внутри соответствующих функций.
Единственная проблема - время компиляции после всей "макросизации" состояний, портов, ошибок, событий, клавиш) выросло драматически.

Да, вот это хорошо:
"просто поросячий восторг!!! .... Вообщем сейчас уже этой штукой не пользуюсь для меню " smile.gif
mempfis_
Делал довольно разветвлённые меню путём организации состояния программы с перебором в основном цикле и функциями перехода.
Чтото типа такого:

Код
//основной цикл
while(1)
{
switch(state)
{
   case 1: Case1();
   break;
  
   case 2: Case2();
   break;
  
   case 3: Case3();
   break;
}
}

//процедура перехода (для каждого case своя)
void JumpToCase1(void)
{
   state = 1;
  
  //вывод на индикатор чего-либо
  ...................................................

//изменение каких-либо параметров
......................................................
}

//процедура для case1
void Case1(void)
{
   //любые действия в case1
   ....................................................................

   //условия перехода в другие состояния
   if(button1 == push) JumpToCase2;
   elseif(button2 == push) JumpToCase3;
}


Всем состояниям давал осмысленые названия и в итоге получалась легко читаемая программа менюшки (даже после 2х-3х месяцев) smile.gif
Legotron
Цитата(zltigo @ Sep 8 2009, 18:28) *
воздействий еще больше - поведение становится формально трудно описуемым нужно добавлять элементы размытой логики...

В данном топике речь идёт о меню. Можно пример ваших усложнений касательно построений меню? Я себе мало представляю меню с размытой логикой, но подозреваю, что если такое и можно придумать, вряд ли возможно будет этим пользоваться с точки зрения эргономики. Хорошее меню - простое меню. Тому пример старые модели телефонов Nokia. biggrin.gif добавлено: пару нажатий кнопок и ты уже рубаешь в змейку wink.gif

Цитата(zltigo @ Sep 8 2009, 18:28) *
Да, уже поминал в начале топика в качестве примера. Особого пиетета не стоит (ну разве только по отношению к коду генеримому IAR VS smile.gif ), но достаточно добротно.

Код генерируемый IAR VS - нечитабелен, ибо там всё завязано на 1 таблице, которую без бубна не расшифруешь rolleyes.gif , но всё остальное по-моему вполне вразумительно (в сравнении с другими программами с автогенерацией кода)

Цитата(Dog Pawlowa @ Sep 8 2009, 18:45) *
А я вот пришел к макросам описания состояний и доволен.
Переходы между состояниями - ручками внутри соответствующих функций.
Единственная проблема - время компиляции после всей "макросизации" состояний, портов, ошибок, событий, клавиш) выросло драматически.

К макросам лично у меня сложилось весьма предвзятое отношение, я считаю что они сильно усложняют чтение программ сторонними людьми, а также могут содержать ошибки, которые трудно отыскать.

Цитата(Dog Pawlowa @ Sep 8 2009, 18:45) *
"просто поросячий восторг!!! .... Вообщем сейчас уже этой штукой не пользуюсь для меню " smile.gif

Вы очень хорошее резюме сделали, на самом деле очень часто хочется писать "как хочу", а знающие люди говорят - не надо так писать, и только через какое-то время понимаешь, что они были правы и главное - почему. Поэтому я лично часто говорю себе - "не буду так писать (как хочеться).... почему?(сам себе).... не знаю, но всё равно не буду, потом пойму" biggrin.gif

Цитата(mempfis_ @ Sep 8 2009, 19:08) *
Делал довольно разветвлённые меню путём организации состояния программы с перебором в основном цикле и функциями перехода.

На мой взгляд это хороший способ для простых меню. (то что я подразумевал под вариантом 2)
Чуть возрастёт логика и способность чтения экпоненциально усложняется.
Нормальный подход для простых меню.
А усложнить например можно добавив память в дочерние состояния, а если их еще несколько...
zltigo
Цитата(Legotron @ Sep 8 2009, 17:20) *
В данном топике речь идёт о меню.....

Шла, до того времени, как Вы завели речь о Конечных Автоматах.
Legotron
Цитата(zltigo @ Sep 8 2009, 19:29) *
Шла, до того времени, как Вы завели речь о Конечных Автоматах.

Я вел речь о КА применительно к построениям меню. Отошел только с примером коммуникационного протокола (виноват, неправ). А так с вами целиком и полностью согласен, что проектирование Конечных Автоматов - сложное занятие и тут IAR VS можно считать игрушкой. Но для меню считаю очень и очень пригодным. К тому же есть еще 1 большой плюс, сразу же после того как у вас меню заработало, у вас есть отличнейшая его документация в виде диаграммы для заказчиков, юзеров, и т.д. и т.п. Не нужно тратить время на конвертацию типа "Си-код -> схема".... Конечно профи пишут программы от обратного "схема -> СИ-код"... но это уже тема сооо-о-всем другого топика smile.gif
Dog Pawlowa
Цитата(Legotron @ Sep 8 2009, 18:20) *
К макросам лично у меня сложилось весьма предвзятое отношение, я считаю что они сильно усложняют чтение программ сторонними людьми, а также могут содержать ошибки, которые трудно отыскать.


У меня тоже неоднозначное отношение, но какова альтернатива?
- все писать стандартными средствами, в результате чего чтение программы не менее сложно.
- использовать нелицензионный софт, так же неизвестный для сторонних людей.

Постороннему необученному человеку нечего делать в моем коде smile.gif
Что касается поиска ошибок, то трудности сильно преувеличены, ошибка находится за 20 секунд.
_Pasha
Цитата(mempfis_ @ Sep 8 2009, 18:08) *
Делал довольно разветвлённые меню путём организации состояния программы с перебором в основном цикле и функциями перехода.

Особенно красиво получается, когда вся работа помещается в idle(), тогда как меню, так и интерфейсную логику можно не стесняясь выполнить в основном цикле. Раньше я считал конструкции типа бесконечного цикла внутри другого бесконечного цикла чем-то позорным. Теперь попустило - на надежность девайса это не оказывает ровно никакого влияния.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.