Обсуждаем контроллеры компании Atmel.
Ответить

Re: micromenu-v2

Сб апр 02, 2022 13:56:55

я одного понять не могу: зачем sprintf, если формат %s? можно же сразу вывести строку при помощи lcd_str_out...

Re: micromenu-v2

Сб апр 02, 2022 15:50:07

Не знаю как у вас там все реализовано, отсюда не видно.

Где-то так надо:
Код:
Объявляете
Menu_Item_t* menu = &NULL_MENU;

получаете позицию пункта меню
menu = Menu_GetCurrentMenu();

и выводите на экран
lcd_clear();
lcd_gotoxy(0,0);   
lcd_str_out(menu->Text);

Re: micromenu-v2

Сб апр 02, 2022 16:17:51

я одного понять не могу: зачем sprintf, если формат %s? можно же сразу вывести строку при помощи lcd_str_out...

Каким образом? lcd_str_out(Text) выдает ту же хрень. Может быть эта хрень реально и лежит по адресу... Как бы это проверить?

Добавлено after 3 minutes 1 second:
lcd_str_out(menu->Text);[/code]

я не очень понял, что это за конструкция. Компилятор ругается Error invalid type argument of '->' (have 'int')

Re: micromenu-v2

Сб апр 02, 2022 17:01:22

Код:
lcd_str_out(menu->Text);


Код:
const char* ptr = menu->Text;
while(char c = pgm_read_byte(ptr++))
  putc(c);

Разные области памяти.
Последний раз редактировалось Карбофос Сб апр 02, 2022 17:06:47, всего редактировалось 2 раз(а).

Re: micromenu-v2

Сб апр 02, 2022 17:04:46

Выложите свой проект вместе с протеусом, в архив zip и сюда.

Re: micromenu-v2

Сб апр 02, 2022 17:11:44

если у вас текст меню хранится в flash, то для sprintf надо формат %S использовать, а не %s

Re: micromenu-v2

Сб апр 02, 2022 17:56:43

ARV, вам очередное спасибо. В таком виде:
Код:
static void Generic_Write(const char* Text)
{
   if (Text)      
      lcd_clear();      
      sprintf(string_M, "%S", Text);
      lcd_gotoxy(0,0);   
      lcd_str_out(string_M);
}

заработало. А прямой вывод через lcd_str_out -- ни в какую.

Re: micromenu-v2

Сб апр 02, 2022 18:20:53

ARV, вам очередное спасибо

Да ты, сначала, научись правильно говорить "спасибо".
Видишь под именем автора поста "+" - так нажми его, придурок.

Re: micromenu-v2

Сб апр 02, 2022 18:40:55

Видишь под именем автора поста "+" - так нажми его, придурок.

иди по маршруту корабля.

Re: micromenu-v2

Сб апр 02, 2022 18:41:19

Карбофос, за плюсики работаешь?
Ну так, держи тебе плюс.

Re: micromenu-v2

Сб апр 02, 2022 18:45:58

Карбофос, за плюсики работаешь?
Ну так, держи тебе плюс.

1. я не работаю.
2. где "плюс"?
3.
Land писал(а):
Видишь под именем автора поста "+" - так нажми его, придурок.

иди по маршруту корабля.

Ты сюда ещё придешь.
Изображение
Вложения
1.png
(21.45 KiB) Скачиваний: 390

Re: micromenu-v2

Сб апр 02, 2022 19:05:49

Карбофос писал(а):2. где "плюс"?
У мну не доступна эта "функция", не могу не плюс не минус поставить.

Re: micromenu-v2

Сб апр 02, 2022 19:47:11

Dimon456, вы очень хороший специалист. Это моё мнение о Вас.
Пожалуйста, не держите на меня зла.

Добавлено after 35 minutes 42 seconds:
иди по маршруту корабля.

У меня есть встречное предложение.
Вы на хуй давно ходили?

Независимо от вашего ответа, у читателей форума уже должно сложиться представление о вас.
Просто придурок.

Re: micromenu-v2

Вс апр 03, 2022 05:16:55

Карбофос, вы соответствуете своему нику? Если в че, я про токсичность. Весенне-осеннее обострение? Лишний грамм в мозг упал? Что ругаешься?

Re: micromenu-v2

Вс апр 03, 2022 17:10:47

Карбофос идет означенным курсом. У нормальных прошу помощи продолжить разбираться с меню.
Собственно вот в таком виде у меня сейчас выглядит файл MicroMenu.c
Спойлер
Код:
#ifndef LIBRARY
   #define LIBRARY
      #include "define.h"
      #include "stdio.h"
      #include "globals.h"
      #include "axlib/type_var.h"
      #include "MicroMenu.h"
      #include "Menu_def_func.h"

#endif

   #define BUTTON_UP_STATE      (PIND & (1<<PD6))
   #define BUTTON_DOWN_STATE   (PINB & (1<<PB1))
   #define BUTTON_LEFT_STATE   (PIND & (1<<PD7))
   #define BUTTON_RIGHT_STATE   (PINB & (1<<PB0))

   
   uint8_t BUTTON;
   char string_M[14] = {0};


/** This is used when an invalid menu handle is required in
 *  a \ref MENU_ITEM() definition, i.e. to indicate that a
 *  menu has no linked parent, child, next or previous entry.
 */
Menu_Item_t PROGMEM NULL_MENU = {0};

/** \internal
 *  Указатель на общую функцию отображения текста меню
 * обратный вызов, для отображения настроенного текста пункта меню
 * если не задана функция отображения, специфичная для меню
 * в пункте меню выбора.
 */
static void (*MenuWriteFunc)(const char* Text) = NULL;

/** \internal
 *  Указатель на текущий выбранный пункт меню.
 */
static Menu_Item_t* CurrentMenuItem = &NULL_MENU;


Menu_Item_t* Menu_GetCurrentMenu(void)
{
   return CurrentMenuItem;
}

void Menu_Navigate(Menu_Item_t* const NewMenu)
{
   if ((NewMenu == &NULL_MENU) || (NewMenu == NULL))
      return;

   CurrentMenuItem = NewMenu;

   if (MenuWriteFunc)
      MenuWriteFunc(CurrentMenuItem->Text);

   void (*SelectCallback)(void) = MENU_ITEM_READ_POINTER(&CurrentMenuItem->SelectCallback);

   if (SelectCallback)
      SelectCallback();
}

void Menu_SetGenericWriteCallback(void (*WriteFunc)(const char* Text))
{
   MenuWriteFunc = WriteFunc;
   Menu_Navigate(CurrentMenuItem);
}

void Menu_EnterCurrentItem(void)
{
   if ((CurrentMenuItem == &NULL_MENU) || (CurrentMenuItem == NULL))
      return;

   void (*EnterCallback)(void) = MENU_ITEM_READ_POINTER(&CurrentMenuItem->EnterCallback);

   if (EnterCallback)
      EnterCallback();
}

extern enum ButtonValues
{
   BUTTON_NONE,
   BUTTON_UP,
   BUTTON_DOWN,
   BUTTON_LEFT,
   BUTTON_RIGHT
};

enum ButtonValues GetButtonPress(void)
{
   skan_key();
   return BUTTON;
}
/*** END DUMY CODE ***/

/** Generic function to write the text of a menu.
 *
 *  \param[in] Text   Text of the selected menu to write, in \ref MENU_ITEM_STORAGE memory space*/
 
static void Generic_Write(const char* Text)
{
   if (Text)      
      lcd_clear();      
      sprintf(string_M, "%S", Text);
      lcd_gotoxy(0,0);   
      lcd_str_out(string_M);
}
//         NAME   NEXT(DOWN)   PREVIOS(UP)      PARENT(LEFT)   CHILD(RIGHT)   SELECT            ENTER            TEXT:
MENU_ITEM(   Menu_1,      Menu_2,      Menu_6,      NULL_MENU,   Menu_1_1,   NULL              , NULL          , "SET_DATE");
MENU_ITEM(   Menu_2,      Menu_3,      Menu_1,      NULL_MENU,   Menu_2_1,   NULL                 , NULL             , "SET_TIME");
MENU_ITEM(   Menu_3,      Menu_4,      Menu_2,      NULL_MENU,   Menu_3_1,   NULL                 , NULL             , "SET_OPEN");
MENU_ITEM(   Menu_4,      Menu_5,      Menu_3,      NULL_MENU,   Menu_4_1,   NULL                 , NULL             , "SET_CLOSE");
MENU_ITEM(   Menu_5,      Menu_6,      Menu_4,      NULL_MENU,   Menu_5_1,   NULL                 , NULL             , "SET_TEMPR");
MENU_ITEM(   Menu_6,      Menu_1,      Menu_5,      NULL_MENU,   Menu_6_1,   NULL                 , NULL             , "SET_BRIGHTNES");


MENU_ITEM(   Menu_1_1,   NULL_MENU,   NULL_MENU,   Menu_1,      Menu_1_2,   day_of_month_Select   , day_of_month_Enter, "DAY_OF_MONTH");
MENU_ITEM(   Menu_1_2,   NULL_MENU,   NULL_MENU,   Menu_1_1,   Menu_1_3,   month_Select      , month_Enter      , "MONTH");
MENU_ITEM(   Menu_1_3,   NULL_MENU,   NULL_MENU,   Menu_1_2,   Menu_1_4,   year_Select         , year_Enter      , "YEAR");
MENU_ITEM(   Menu_1_4,   NULL_MENU,   NULL_MENU,   Menu_1_3,   Menu_1,      day_Select         , day_Enter         , "DAY");
MENU_ITEM(   Menu_1_5,   NULL_MENU,   NULL_MENU,   Menu_1_4,   NULL_MENU,   save            , NULL            , "SAVE");

MENU_ITEM(   Menu_2_1,   NULL_MENU,   NULL_MENU,   Menu_2,      Menu_1_2,   hours_Select      , hours_Enter      , "HOURS");
MENU_ITEM(   Menu_2_2,   NULL_MENU,   NULL_MENU,   Menu_2_1,   Menu_2,      minutes_Select      , minutes_Enter      , "MINUTES");
MENU_ITEM(   Menu_2_3,   NULL_MENU,   NULL_MENU,   Menu_2_2,   NULL_MENU,   save            , NULL            , "SAVE");

MENU_ITEM(   Menu_3_1,   NULL_MENU,   NULL_MENU,   Menu_3,      Menu_3_2,   open_hours_Select   , open_hours_Enter   , "OPEN_HOURS");
MENU_ITEM(   Menu_3_2,   NULL_MENU,   NULL_MENU,   Menu_3_1,   Menu_3,      open_minutes_Select   , open_minutes_Enter, "OPEN_MINUTES");
MENU_ITEM(   Menu_3_3,   NULL_MENU,   NULL_MENU,   Menu_3_2,   NULL_MENU,   save            , NULL            , "SAVE");

MENU_ITEM(   Menu_4_1,   NULL_MENU,   NULL_MENU,   Menu_4,      Menu_4_2,   close_hours_Select   , close_hours_Enter   , "CLOSE_HOURS");
MENU_ITEM(   Menu_4_2,   NULL_MENU,   NULL_MENU,   Menu_4_1,   Menu_4,      close_minutes_Select, close_minutes_Enter, "CLOSE_MINUTE");
MENU_ITEM(   Menu_4_3,   NULL_MENU,   NULL_MENU,   Menu_4_2,   NULL_MENU,   save            , NULL            , "SAVE");

MENU_ITEM(   Menu_5_1,   NULL_MENU,   NULL_MENU,   Menu_5,      Menu_5,      degress_Select      , degress_Enter      , "DEGRESS_C");
MENU_ITEM(   Menu_5_2,   NULL_MENU,   NULL_MENU,   Menu_5_1,   NULL_MENU,   save            , NULL            , "SAVE");

MENU_ITEM(   Menu_6_1,   NULL_MENU,   NULL_MENU,   Menu_6,      Menu_6,      brightnes_Select   , brightnes_Enter   , "BRIGHTNES");
MENU_ITEM(   Menu_6_2,   NULL_MENU,   NULL_MENU,   Menu_6_1,   NULL_MENU,   save            , NULL            , "SAVE");



void menu_RUN(void)
{      
   Menu_SetGenericWriteCallback(Generic_Write);
   Menu_Navigate(&Menu_1);

   switch (GetButtonPress())
      {
         case BUTTON_UP:
         Menu_Navigate(MENU_PREVIOUS);
         break;
         case BUTTON_DOWN:
         Menu_Navigate(MENU_NEXT);
         break;
         case BUTTON_LEFT:
         Menu_Navigate(MENU_PARENT);
         break;
         case BUTTON_RIGHT:
         Menu_Navigate(MENU_CHILD);
         break;
         default:
         break;
      }
   //return 0;
}

в main.c я по прерыванию с кнопки вызываю функцию menu_RUN() в MicroMenu.c.
Код:
if((flag_BUTTON)|(flag_BUTTON_TICK))   
         {
            LCD_backlight_ON;
            flag_BUTTON = _OFF;
            flag_BUTTON_TICK = _OFF;
            seconds = 0;
            flag_WAIT = _ON;
            menu_RUN();
         } else;
Если я понимаю правильно, дальше идет обращение за значением кнопки в функцию
Код:
enum ButtonValues GetButtonPress(void)
{
   skan_key();
   return BUTTON;
}
которая обращается к обработчику собственно кнопок skan_key(), из которого и получает значение нажатой кнопки. Вопрос собственно в том, правильно ли я понимаю последовательность необходимых событий? Потому, что у меня получается при первом же обращении к menu_RUN() я получаю вывод элемента меню, а затем из обработчика кнопок возвращается значение нажатой кнопки. И я понимаю, что не понимаю. Или мне надо сначала получить код нажатой кнопки, а уже потом вызывать обработку меню? Но все равно сначала произойдет обращение к Menu_1, а затем в swith будет выбран переход по кнопке :dont_know:

Re: micromenu-v2

Вс апр 03, 2022 17:15:58

вы понимаете логику работы micromenu не правильно. читайте документацию.

Re: micromenu-v2

Вс апр 03, 2022 17:25:59

Пасаны, зачем ругаетесь? :)
На деле, чтобы понять работу механизма менюшки, надо изучить в языке Си тему про указатели и массив указателей и указатели на функции. И после этого все премудрсти раскроются.
Менюшки как обычно делаются то. Для кнопок создается массив указателей на функции, реализующие действия по нажатиям. И в зависимости от текущего режима меню каждой кнопке присваивается определенный указатель на исполняемую функцию. Навигация по пунктам менюшки - это одна группа указателей. Изменение параметра в пункте менюшки - другая группа указателей.

Re: micromenu-v2

Вс апр 03, 2022 21:00:49

To Land. MicroMenu это структура данных. За счёт макросов стало проще создавать развитое меню. Не более. Не менее.
Дальше идёт организация программных модулей. Взаимосвязи. Пусть у нас дисплей. Кнопочки. Ну и что то там делать. Давай посмотрим на программу как на конечный автомат. С подчинёнными КА.

Main:
Proc_Device (); // целевой модуль.
Proc_Button (); // обработка кнопок.
Proc_Info_Service (); // модуль обработки кодов кнопок. Обработка меню. Вывод в буфер дисплея. Именно в этом модуле используется MicroMenu.
Proc_Display (); // модуль аппаратной части дисплея.

Все эти обработчики - конечные автоматы. Пусть Proc_Info_Service в каком то состоянии. В этом состоянии в том числе ждём нажатия кнопки или сочетание, чтобы войти в меню. Есть условие входа в меню? Установка состояния меню. В этом состоянии уже ждём свой набор кодов кнопок. Пусть, скажем, установка часов.

Ну и так далее. В каждом состоянии используются callback-и MicroMenu. Plus, Minus, Prev, Next, Enter.
Последний раз редактировалось Demiurg Пн апр 04, 2022 03:13:41, всего редактировалось 2 раз(а).

Re: micromenu-v2

Вс апр 03, 2022 21:28:43

Пасаны, зачем ругаетесь? :)
На деле, чтобы понять работу механизма менюшки, надо изучить в языке Си тему про указатели и массив указателей и указатели на функции. И после этого все премудрсти раскроются.
Менюшки как обычно делаются то. Для кнопок создается массив указателей на функции, реализующие действия по нажатиям. И в зависимости от текущего режима меню каждой кнопке присваивается определенный указатель на исполняемую функцию. Навигация по пунктам менюшки - это одна группа указателей. Изменение параметра в пункте менюшки - другая группа указателей.

Там будет два подраздела - первый сами "векторные кнопы", второй блок взаимосвязи программ, обеспечивающих "вкладки устройств".
Под ассемблером заметно удобнее ("микровиндовс" с иконками и под ассемблером я уже делал
viewtopic.php?p=1830978#p1830978
viewtopic.php?p=2151072#p2151072
viewtopic.php?p=2198317#p2198317
) и кода поменьше.
А вот под СИ/С++ это таки досада - объем кода весьма огорчает (правда то адуринья - но тот же GCC).
Уровень "векторно-программируемых кноп" при одном "устройстве"(тестовые светики) вот тут
viewtopic.php?p=4208592#p4208592
остается проработать "магазин устройств" для нескольких задач, у каждой из которых свои "менюшки"/алгоритмы управления для кнопок/комбинаций кноп.
Для СИ/С++ главная головная боль в таком случае именно в корректной "разноске" задач каждого устройства по своим файлам,
поскольку текста там весьма моного...
8)

Re: micromenu-v2

Вс апр 03, 2022 21:44:54

Как все сложно: автоматы кнопки векторы С++ классы, а по проще нет ни чего?
Ответить