Страница 1 из 4
micromenu-v2
Добавлено: Ср мар 18, 2015 12:40:20
binarick
Доброго времени уважаемые!
Обнаружил я проект меню
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
eess9
А вы эти ошибки читали вообще? У вас есть 2 типа данных Menu_Item_t и Menu_Item. Если ожидается получение переменной первого типа, то не сьест переменную второто типа. Посмотрите их объявления, может эти типы данных одинаковы.
Re: micromenu-v2
Добавлено: Чт мар 19, 2015 12:39:43
binarick
читал но мало что понял.
в исходном примере переменные не задаются.
я не специалист в данной теме, думал не сложно или кто-то уже делал подобное.... но видимо придётся разбираться с 0 самому.
а вообще я думаю что проблема в работе с памятью
Re: micromenu-v2
Добавлено: Чт мар 19, 2015 14:43:22
eess9
проект выкладывайте, иначе сложно вам подсказать.
Re: micromenu-v2
Добавлено: Чт мар 19, 2015 15:56:14
binarick
абсолютно весь проект тут
его можно тут посмотреть полностью без скачки
https://github.com/abcminiuser/micromenu-v2
ссылка на скачку
https://github.com/abcminiuser/micromen ... master.zip
это полный исходник без моего вмешательства
Re: micromenu-v2
Добавлено: Чт мар 19, 2015 17:14:23
eess9
Собрал эту демку в студии для меги8. Все собирается вообще без проблем. Гдето косяки у вас при переносе этой библиотеки в свой проект. Смотрите еще раз внимательней
Re: micromenu-v2
Добавлено: Чт мар 19, 2015 18:53:07
punxer
скиньте ваш 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
eess9
Библиотека австралийцем писалась под AVR Studio. Вы же используете CVAVR, хотя язык си как бы одинаков, но кроссплатформенность в средах разработки реализована по разному. Отсюда и надо думать, почему CVAVR не хочет "съедать" данную структуру как новый тип данных.
А зачем вы при объявлении const туда добавили?
Re: micromenu-v2
Добавлено: Пт мар 20, 2015 10:53:45
binarick
Странно я собрал проект Атмел студии 6,2 и нефига не работает

изменений не вносил вообще
уважаемый
eess9 у вас какая версия ?
Вкладываю свой проект на CVAVR 3.12
я почему то грешу на #include <pgmspace.h> может по незнанию а может по тому что в студии эта библиотека нужна а CV вроде как сам всё умеет и скорее всего тут есть не совместимость.
Re: micromenu-v2
Добавлено: Пт мар 20, 2015 11:11:59
eess9
AVR Studio v6.2 релиз 1548. Кидайте свой проект гляну, т.к. с фото не очень то ясно, кода там почти не видно.
Re: micromenu-v2
Добавлено: Пт мар 20, 2015 11:19:32
binarick
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
eess9
Да не это я имел ввиду. Как я по картинке могу определить ошибки, если я не вижу строк кода, в которых возникают ошибки? Вы же понимаете, что часто одну и туже ошибку можно вызвать большим количеством способов

Re: micromenu-v2
Добавлено: Сб мар 21, 2015 09:49:38
binarick
binarick писал(а):Да не это я имел ввиду. Как я по картинке могу определить ошибки, если я не вижу строк кода, в которых возникают ошибки? Вы же понимаете, что часто одну и туже ошибку можно вызвать большим количеством способов
Спасибо я понял что не так делал в Студии.
Жаль что CV ни кто не знает как заставить работать
Re: micromenu-v2
Добавлено: Сб июн 27, 2015 19:48:17
uk8amk
Убил день на микроменю. Ковыряние показало что CV препроцессор не переваривает некоторые макросы, а через них там сделано многое.
Плюнул, написал своё похожее.
Re: micromenu-v2
Добавлено: Ср фев 28, 2018 08:56:32
DimAlt
Привет! Был проект на основе 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
serg_svd
Ребята, выручайте!
Завяз я с этим микроменю 2. Я слишком плохо ориентируюсь в этих указателях и просто запутался в некоторых моментах.
Я не пойму каким образом выводится поле Text при нажатии кнопок, если основная функция вывода строки
static void Generic_Write(const char* Text); находится в main.c и вызывается всего один раз перед бесконечным циклом опроса кнопок.
У меня сейчас дисплей 128х64. Хочу сделать меню по типу, как DimAlt реализовал, но с некоторыми изменениями.
Инверсию выбранной строчки хочу заменить на присутствие символа ">" перед строкой меню. Инверсию пробовал, строчка плохо читается.
Хочу вывести сразу все пункты выбранного меню. В оригинальной библиотеке выводится только один пункт. А что отвечает за его вывод я не пойму, о чем в начале и написал.
Программист я никакой, хотя и пишу прошивки для своих устройств. Но эта самая сложная из всех, что были.
Очень нужна помощь! Можно в форуме меня помидорами закидывать, можно в личке. Но вопросов реально много. Пока все не озвучиваю, потому как возможно после ваших советов я пойму суть проблемы и дальше пойдет легче. Но пока дело не движется
Смотрю код DimAlt, пока тоже не пойму, каким образом происходит вывод всех пунктов меню. В какой функции?
Re: micromenu-v2
Добавлено: Пт окт 26, 2018 08:18:56
DimAlt
- Ну да, все очень и очень запутано.
// Есть в 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);
Re: micromenu-v2
Добавлено: Пт окт 26, 2018 08:50:11
serg_svd
DimAlt? спасибо за пояснение. Попробую все это понять.
Но уже понял по Вашим пояснениям, что я язык СИ знаю на 2 странички учебника

Первое, что надо понять, как работает
static void (*MenuWriteFunc)(void) = NULL; 
Re: micromenu-v2
Добавлено: Пт окт 26, 2018 13:24:47
DimAlt
Дополнил предыдущий пост. Попытался объяснить как рисуется пункт меню. В моем исходнике, для прорисовки главного пункта меню, используется функция
Код: Выделить всё
//---Главное меню, рисует только пункты(без параметров)------------
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
serg_svd
[uquote="DimAlt",url="/forum/viewtopic.php?p=3491858#p3491858"]А первый блин имеет право быть комом

[/uquote]
Да ничего ж себе ком

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

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