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

micromenu-v2

Ср мар 18, 2015 12:40:20

Доброго времени уважаемые!

Обнаружил я проект меню
https://github.com/abcminiuser/micromenu-v2

но беда в том, что из-за недостатка опыта не могу его запустить в CodeVisionAVR 3.12
подскажите пожалуйста что от меня хочет компилятор ? и как пофиксить

Спасибо за ваше время и ответы

Код:
#include <io.h>
#include <pgmspace.h>
#include <stdio.h>

#include "MicroMenu.h"


/*** DUMY CODE ***/
enum ButtonValues
{
    BUTTON_NONE,
    BUTTON_UP,
    BUTTON_DOWN,
    BUTTON_LEFT,
    BUTTON_RIGHT,
    BUTTON_ENTER,
};

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


/** Example menu item specific enter callback function, run when the associated menu item is entered. */
static void Level1Item1_Enter(void)
{
    puts("ENTER");
}

/** Example menu item specific select callback function, run when the associated menu item is selected. */
static void Level1Item1_Select(void)
{
    puts("SELECT");
}

/** 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)
        puts_P(Text)
;
}

MENU_ITEM(Menu_1, Menu_2, Menu_3, NULL_MENU, Menu_1_1,  NULL, NULL, "1");
MENU_ITEM(Menu_2, Menu_3, Menu_1, NULL_MENU, NULL_MENU, NULL, NULL, "2");
MENU_ITEM(Menu_3, Menu_1, Menu_2, NULL_MENU, NULL_MENU, NULL, NULL, "3");

MENU_ITEM(Menu_1_1, Menu_1_2, Menu_1_2, NULL_MENU, NULL_MENU, NULL, NULL, "1.1");
MENU_ITEM(Menu_1_2, Menu_1_1, Menu_1_1, NULL_MENU, NULL_MENU, NULL, NULL, "1.2");

void main(void)
{
    /* Set up the default menu text write callback, and navigate to an absolute menu item entry. */
    Menu_SetGenericWriteCallback(Generic_Write);
    Menu_Navigate(&Menu_1);

    while (1)
    {
        /* Example usage of Micromenu - here you can create your custom menu navigation system; you may wish to perform
         * other tasks while detecting key presses, enter sleep mode while waiting for user input, etc.
         */
        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;
            case BUTTON_ENTER:
                Menu_EnterCurrentItem();
                break;
            default:
                break;
        }
    }


Ругается на MENU_ITEM........

Ошибки вылетают такие:
Error: C:\Project\Micromenu\intkey.c(49): a value of type 'flash struct Menu_Item_t *' can't be used to initialize an entity of type 'const struct Menu_Item *'
Error: C:\Project\Micromenu\intkey.c(50): a value of type 'flash struct Menu_Item_t *' can't be used to initialize an entity of type 'const struct Menu_Item *'
Error: C:\Project\Micromenu\intkey.c(51): a value of type 'flash struct Menu_Item_t *' can't be used to initialize an entity of type 'const struct Menu_Item *'
Error: C:\Project\Micromenu\intkey.c(53): a value of type 'flash struct Menu_Item_t *' can't be used to initialize an entity of type 'const struct Menu_Item *'
Error: C:\Project\Micromenu\intkey.c(54): a value of type 'flash struct Menu_Item_t *' can't be used to initialize an entity of type 'const struct Menu_Item *'
Error: C:\Project\Micromenu\intkey.c(60): function argument #1 of type 'flash struct Menu_Item_t *' is incompatible with required parameter of type 'const struct Menu_Item_t *'

Изображение

Re: micromenu-v2

Ср мар 18, 2015 17:35:18

А вы эти ошибки читали вообще? У вас есть 2 типа данных Menu_Item_t и Menu_Item. Если ожидается получение переменной первого типа, то не сьест переменную второто типа. Посмотрите их объявления, может эти типы данных одинаковы.

Re: micromenu-v2

Чт мар 19, 2015 12:39:43

читал но мало что понял.
в исходном примере переменные не задаются.
я не специалист в данной теме, думал не сложно или кто-то уже делал подобное.... но видимо придётся разбираться с 0 самому.

а вообще я думаю что проблема в работе с памятью

Re: micromenu-v2

Чт мар 19, 2015 14:43:22

проект выкладывайте, иначе сложно вам подсказать.

Re: micromenu-v2

Чт мар 19, 2015 15:56:14

абсолютно весь проект тут
его можно тут посмотреть полностью без скачки
https://github.com/abcminiuser/micromenu-v2

ссылка на скачку https://github.com/abcminiuser/micromen ... master.zip

это полный исходник без моего вмешательства

Re: micromenu-v2

Чт мар 19, 2015 17:14:23

Собрал эту демку в студии для меги8. Все собирается вообще без проблем. Гдето косяки у вас при переносе этой библиотеки в свой проект. Смотрите еще раз внимательней
Вложения
Console.rar
(25.46 KiB) Скачиваний: 493

Re: micromenu-v2

Чт мар 19, 2015 18:53:07

скиньте ваш CVAVR проект, сударь

UPD: довел до тех же ошибок, ступор

Проще написать самому, чем разбираться с чужими макросами, хотя, естественно, интересно

Проблема где-то в приведении типов

У вас выбран си компилятор?

вот так уходят часть ошибок, но на правоту не могу претендовать
(естественно править нужно либу, она не совсем не кросс- компиляторная)

Код:
    typedef const struct Menu_Item {
        flash struct Menu_Item *Next; /**< Pointer to the next menu item of this menu item */
        flash struct Menu_Item *Previous; /**< Pointer to the previous menu item of this menu item */
        flash struct Menu_Item *Parent; /**< Pointer to the parent menu item of this menu item */
      flash struct Menu_Item *Child; /**< Pointer to the child menu item of this menu item */
      void (*SelectCallback)(void); /**< Pointer to the optional menu-specific select callback of this menu item */
      void (*EnterCallback)(void); /**< Pointer to the optional menu-specific enter callback of this menu item */
      const char Text[]; /**< Menu item text to pass to the menu display callback function */
   } Menu_Item_t;

Re: micromenu-v2

Пт мар 20, 2015 09:38:07

Библиотека австралийцем писалась под AVR Studio. Вы же используете CVAVR, хотя язык си как бы одинаков, но кроссплатформенность в средах разработки реализована по разному. Отсюда и надо думать, почему CVAVR не хочет "съедать" данную структуру как новый тип данных.

А зачем вы при объявлении const туда добавили?

Re: micromenu-v2

Пт мар 20, 2015 10:53:45

Странно я собрал проект Атмел студии 6,2 и нефига не работает
Изображение
изменений не вносил вообще

уважаемый eess9 у вас какая версия ?

Вкладываю свой проект на CVAVR 3.12

я почему то грешу на #include <pgmspace.h> может по незнанию а может по тому что в студии эта библиотека нужна а CV вроде как сам всё умеет и скорее всего тут есть не совместимость.
Вложения
Micromenu.zip
(16.72 KiB) Скачиваний: 377

Re: micromenu-v2

Пт мар 20, 2015 11:11:59

AVR Studio v6.2 релиз 1548. Кидайте свой проект гляну, т.к. с фото не очень то ясно, кода там почти не видно.

Re: micromenu-v2

Пт мар 20, 2015 11:19:32

eess9 писал(а):AVR Studio v6.2 релиз 1548. Кидайте свой проект гляну, т.к. с фото не очень то ясно, кода там почти не видно.


вот в полный размер
http://f-picture.net/lfp/s49.radikal.ru ... c7.png/htm

хм а Ваш проект Console.rar у меня работает......

я ради эксперимента собрал его в студии она сложнее CV потому мне с мои скудным знанием вопроса очень не удобно в ней работать и проект в ней я не смогу свой реализовать.

Я сейчас пока сам гляну что за беда и в чём разница

Re: micromenu-v2

Пт мар 20, 2015 11:25:40

binarick писал(а):вот в полный размер
http://f-picture.net/lfp/s49.radikal.ru ... c7.png/htm

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

Re: micromenu-v2

Сб мар 21, 2015 09:49:38

binarick писал(а):Да не это я имел ввиду. Как я по картинке могу определить ошибки, если я не вижу строк кода, в которых возникают ошибки? Вы же понимаете, что часто одну и туже ошибку можно вызвать большим количеством способов


Спасибо я понял что не так делал в Студии.
Жаль что CV ни кто не знает как заставить работать

Re: micromenu-v2

Сб июн 27, 2015 19:48:17

Убил день на микроменю. Ковыряние показало что CV препроцессор не переваривает некоторые макросы, а через них там сделано многое.
Плюнул, написал своё похожее.
Вложения
menu_test.zip
Си, протеус
(21.42 KiB) Скачиваний: 583

Re: micromenu-v2

Ср фев 28, 2018 08:56:32

Привет! Был проект на основе MICRO-MENU V2 (C) Dean Camera, 2012. Что бы не забыть, решил выделить в отдельный исходник, только меню с различной реализацией функций, так называемых типовых, где для реализации пункта меню выбираются уже написанные функции в исходнике, и не типовые, когда надо реализовать "свой" пункт меню. Еще есть категория для динамических данных, например, у меня использовались для калибровки АЦП и ЦАП. Смысл в том, что меню прорисовывается один раз, по событию нажатия на кнопку и надо было, как то придумать механизм вывода изменяющихся данных, здесь не очень хорошая реализация, но в рабочем проекте меня все это устроило. Работа со шрифтами своя, если кого-то заинтересует расскажу как сделать шрифт к этому проекту.. Изначально писалось для STM32, поэтому в исходниках есть переключение на AVR и STM32. Проект под 8 протеус и мегу328 и ST7735.
длинное скучное видео демонстрация
https://youtu.be/rpWHc3USWQg
Добавление пункта меню с "типовыми" функциями.
https://youtu.be/g_qrI1SEVj4
Проект https://yadi.sk/d/E9JPZa1d3SgKok

Re: micromenu-v2

Чт окт 25, 2018 13:54:31

Ребята, выручайте!
Завяз я с этим микроменю 2. Я слишком плохо ориентируюсь в этих указателях и просто запутался в некоторых моментах.
Я не пойму каким образом выводится поле Text при нажатии кнопок, если основная функция вывода строки
static void Generic_Write(const char* Text); находится в main.c и вызывается всего один раз перед бесконечным циклом опроса кнопок.

У меня сейчас дисплей 128х64. Хочу сделать меню по типу, как DimAlt реализовал, но с некоторыми изменениями.
Инверсию выбранной строчки хочу заменить на присутствие символа ">" перед строкой меню. Инверсию пробовал, строчка плохо читается.
Хочу вывести сразу все пункты выбранного меню. В оригинальной библиотеке выводится только один пункт. А что отвечает за его вывод я не пойму, о чем в начале и написал.

Программист я никакой, хотя и пишу прошивки для своих устройств. Но эта самая сложная из всех, что были.
Очень нужна помощь! Можно в форуме меня помидорами закидывать, можно в личке. Но вопросов реально много. Пока все не озвучиваю, потому как возможно после ваших советов я пойму суть проблемы и дальше пойдет легче. Но пока дело не движется

Смотрю код DimAlt, пока тоже не пойму, каким образом происходит вывод всех пунктов меню. В какой функции?

Re: micromenu-v2

Пт окт 26, 2018 08:18:56

    Ну да, все очень и очень запутано.

    // Есть в MicroMenu.c переменная указатель на функцию
    // которая существует только в MicroMenu.c
    // код в MicroMenu.c
    static void (*MenuWriteFunc)(void) = NULL;
    // Это переменная указатель на функцию, которая будет вызываться для построения (прорисовки, хождения по) меню.
    // при выполнении функции Menu_Navigate(NewMenu)

    // Но в эту функцию не передаются параметры, что не удобно.
    // Значит можно, при вызове функции по этому указателю, вызывать другую с нужными параметрами.
    // Соответственно можно переключиться на другую функцию построения меню, например подменю имеет
    // другой дизайн, который нельзя реализовать в предыдущей функции

    // В этой функции, переменной MenuWriteFunc присваивается адрес на функцию которая строит меню
    // код в MicroMenu.c
    void Menu_SetGenericWriteCallback(void (*WriteFunc)(void))
    {
    MenuWriteFunc = WriteFunc;//установить указатель на ф. построения меню.
    }

    //вызов в main.c
    Menu_SetGenericWriteCallback(Generic_Write_Menu);
    // Назначение функции для построения меню
    // Теперь по вызову переменной MenuWriteFunc будет выполняться функция Generic_Write_Menu
    // Которая выглядит так
    // реализация и вызов в main.c
    void Generic_Write_Menu(void){
    menu_make_screen(menu_get_ptrGeneric(), SystemFont);
    }
    // В ней уже вызывается функция с нужным набором параметров.
    // В общем, смотрите код в MicroMenu.c и где видите MenuWriteFunc(),
    // на самом деле вызывается menu_make_screen(menu_get_ptrGeneric(), SystemFont);

    /** Например, нужно переключиться на другую функцию, для этого
    пишем ее реализацию f_prn(параметры..) и вызываем эту функцию в функции имеющий вид
    void f(void); так как, только такую функцию можно выполнить по указателю
    объявленному так static void (*MenuWriteFunc)(void);
    // Назначаем ее для построения меню:
    Menu_SetGenericWriteCallback(f);
    //
    f(void){//теперь эта функция будет вызываться по указателю MenuWriteFunc
    f_prn(параметры..)
    } */


    // menu_make_screen(menu_get_ptrGeneric(), SystemFont);
    // Эта моя основная функция для построения меню.
    // Главное в ней понять, что она вызывает функцию PrintItemCallback
    // для каждого пункта меню. PrintItemCallback - назначает функцию для вывода одной строки (пункта) меню.
    // В начале функции считается количество таких пунктов.
    // В этой функции также принимается решение о полной перерисовки экрана или только частичной.
    // Например, при Menu_Navigate(MENU_NEXT), если не надо сдвигать все пункты меню, то прорисовываются
    // только два пункта меню, предыдущий и "новый" текущий.

    // Теперь, что происходит при навигации меню, через вызовы
    Menu_Navigate(MENU_NEXT);
    // последовательность вызова функций
    // вызывается MenuWriteFunc
    // в которой вызывается функция назначенная через указатель на функцию PrintItemCallback
    // столько раз, сколько пунктов меню.
    // затем вызывается функция SelectCallback

    // Самая сложная обработка по нажатию кнопки SET
    // здесь надо анализировать, что нужно сделать, или перейти на подуровень или выполнить
    // действие или перейти на редактирование параметра, в общем смотрите код.

    // В общем виде последовательность вызова будет такой,
    // для переходов по пунктам, нажатие на кнопки PLUS MINUS
    // вызовы в таком порядке MenuWriteFunc->PrintFunc->SelectFunc
    // для редактирования или перехода на потомка, при нажатии на SET
    // вызовы в таком порядке EnterF->InitFunc->MenuWriteFunc->PrintFunc->SelectFunc

    // *****************************************************
    // Подробней про вызов PrintFunc, он самый забубенный.
    // *****************************************************
    // в макросе
    #define MENU_ITEM //переменная указатель на функцию задана так
    void (*printItemCallback)(void);

    // При описании макроса мы задаем адрес функции для указателя printItemCallback
    // далее вызов его
    if (PrintItemCallback)//проверим что указатель не NULL
    PrintItemCallback();

    // допустим разбираемся с этим пунктом меню
    // MENU_ITEM(Name, Next, Previous, Parent, Child, SelectF,EnterF, InitF, PrintText, TEXT)
    MENU_ITEM(It_Fan_1, It_Fan_2, It_Fan_8, Menu_2, NULL_MENU, sel_sample, NULL, m_init_fan, m_print_nn, " Нижняя ТLow `C");
    // здесь для PrintItemCallback задан адрес функции m_print_nn

    // В данном случае по PrintItemCallback() будет вызвана
    m_print_nn();
    // ее реализация в файле main.c
    void m_print_nn(void){
    menu_set_print_item_callback(item_print_nn);
    }
    // которая вызовет выполнет функцию menu_set_print_item_callback
    // её реализация в файле MicroMenu.c
    void menu_set_print_item_callback(void (*f)(uint8_t pos, uint8_t x, uint8_t y, const char *s, uint8_t Width, TSettingfontDot *sF))
    {
    menu_item_print = f;//присвоить указ-лю на ф. адрес ф-ции которая рисует пункт меню
    }
    // В menu_set_print_item_callback передали адресс функции item_print_nn,
    // которая будет использоваться для прорисовки пункта меню.

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

    // Описание указателя на функцию menu_item_print в файле MicroMenu.h
    extern void (*menu_item_print)(uint8_t pos, uint8_t x, uint8_t y, const char *s, uint8_t Width, TSettingfontDot *sF);//указатель на ф.

    // Теперь, строчкой menu_set_print_item_callback(item_print_nn) menu_item_print будет присвоен адрес функции item_print_nn
    // её реализация, в файле main.c
    void item_print_nn(uint8_t pos, uint8_t x, uint8_t y, const char *s, uint8_t Width, TSettingfontDot *sF){
    item_print_x(pos,x,y,s,1,sF);
    }

    // Итак внимание, вызов PrintItemCallback() сделал только одно, назначил menu_item_print новый адресс.
    // Теперь при вызове menu_item_print, выполняется item_print_nn.

    // При выполнении функции через указатель MenuWriteFunc, в этом исходнике он всегда вызывает функцию
    // menu_make_screen(Menu_Item_t* const Menu, TSettingfontDot *sF)
    // Это используется так:

    if (PrintItemCallback)
    PrintItemCallback();//для каждого пункта меню вызывать свою функцию
    //то есть здесь только переназначение функции рисующей пункт меню
    //а далее где нибудь по коду
    menu_item_print(j,0,y,NextMenu->Text,0, sF);// выполнение этой функции
    // для расматриваемого MENU_ITEM(It_Fan_1, ...) это равносильно item_print_nn(j,0,y,NextMenu->Text,0, sF);
Последний раз редактировалось DimAlt Пт окт 26, 2018 17:50:13, всего редактировалось 3 раз(а).

Re: micromenu-v2

Пт окт 26, 2018 08:50:11

DimAlt? спасибо за пояснение. Попробую все это понять.
Но уже понял по Вашим пояснениям, что я язык СИ знаю на 2 странички учебника :(
Первое, что надо понять, как работает static void (*MenuWriteFunc)(void) = NULL; :shock:

Re: micromenu-v2

Пт окт 26, 2018 13:24:47

Дополнил предыдущий пост. Попытался объяснить как рисуется пункт меню. В моем исходнике, для прорисовки главного пункта меню, используется функция
Код:
//---Главное меню, рисует только пункты(без параметров)----------
void gl_item_print(uint8_t pos, uint8_t x, uint8_t y, const char *s, uint8_t Width, TSettingfontDot *sF){
uint16_t tcol[2];   
   tcol[0]=sF->Color; tcol[1]=sF->BgColor;   
   if (pos==menu_get_pos()){
      sF->Color=tcol[1];
      sF->BgColor=tcol[0];
   }
   
   str_dot_out_pgm(1,y,s,0,sF);
   
   sF->Color=tcol[0];
   sF->BgColor=tcol[1];
}

как вызывается, расписал выше. Для того что бы изменить выделение параметров, для типовых функций достаточно изменить
void item_print_x(uint8_t pos, uint8_t x, uint8_t y, const char *s, uint8_t FormatN, TSettingfontDot *sF)
там выделение зависит от переменной IndP.

Это первый и пока единственный мой проект меню. А первый блин имеет право быть комом :))

Re: micromenu-v2

Пт окт 26, 2018 15:28:48

А первый блин имеет право быть комом :))

Да ничего ж себе ком :). Для таких "программистов" как я, там поле не паханое в плане ковыряния учебников. Спасибо, пояснения подробные, но все равно требуют осмысления. Мне легко эти указатели не даются.
Я первоначальную попытку с этим микро меню делал еще по статье http://easyelectronics.ru/organizaciya- ... menyu.html
Тоже ее удалось запустить, только там автор реализовал прокрутку выбранного меню относительно центра экрана. Мне не очень это понравилось и я решил с нуля разобраться. Ну и закопался по самые уши :(
Просто у меня этот вывод на дисплей тормозит весь проект. Я всеми правдами и неправдами пытаюсь его допилить, пусть и с костылями, но лишь бы он работал. Потому, что это пока единичное устройство, где я первый раз применил графический индикатор и где можно сделать интерфейс, а не жать комбинации кнопок, как ранее я делал.
Ответить