но беда в том, что из-за недостатка опыта не могу его запустить в CodeVisionAVR 3.12 подскажите пожалуйста что от меня хочет компилятор ? и как пофиксить
/** 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) ; }
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 *'
А вы эти ошибки читали вообще? У вас есть 2 типа данных Menu_Item_t и Menu_Item. Если ожидается получение переменной первого типа, то не сьест переменную второто типа. Посмотрите их объявления, может эти типы данных одинаковы.
читал но мало что понял. в исходном примере переменные не задаются. я не специалист в данной теме, думал не сложно или кто-то уже делал подобное.... но видимо придётся разбираться с 0 самому.
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Собрал эту демку в студии для меги8. Все собирается вообще без проблем. Гдето косяки у вас при переносе этой библиотеки в свой проект. Смотрите еще раз внимательней
Проще написать самому, чем разбираться с чужими макросами, хотя, естественно, интересно
Проблема где-то в приведении типов
У вас выбран си компилятор?
вот так уходят часть ошибок, но на правоту не могу претендовать (естественно править нужно либу, она не совсем не кросс- компиляторная)
Код:
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;
Библиотека австралийцем писалась под AVR Studio. Вы же используете CVAVR, хотя язык си как бы одинаков, но кроссплатформенность в средах разработки реализована по разному. Отсюда и надо думать, почему CVAVR не хочет "съедать" данную структуру как новый тип данных.
Странно я собрал проект Атмел студии 6,2 и нефига не работает изменений не вносил вообще
уважаемый eess9 у вас какая версия ?
Вкладываю свой проект на CVAVR 3.12
я почему то грешу на #include <pgmspace.h> может по незнанию а может по тому что в студии эта библиотека нужна а CV вроде как сам всё умеет и скорее всего тут есть не совместимость.
я ради эксперимента собрал его в студии она сложнее CV потому мне с мои скудным знанием вопроса очень не удобно в ней работать и проект в ней я не смогу свой реализовать.
Я сейчас пока сам гляну что за беда и в чём разница
Да не это я имел ввиду. Как я по картинке могу определить ошибки, если я не вижу строк кода, в которых возникают ошибки? Вы же понимаете, что часто одну и туже ошибку можно вызвать большим количеством способов
Да не это я имел ввиду. Как я по картинке могу определить ошибки, если я не вижу строк кода, в которых возникают ошибки? Вы же понимаете, что часто одну и туже ошибку можно вызвать большим количеством способов
Спасибо я понял что не так делал в Студии. Жаль что CV ни кто не знает как заставить работать
Убил день на микроменю. Ковыряние показало что CV препроцессор не переваривает некоторые макросы, а через них там сделано многое. Плюнул, написал своё похожее.
Вложения:
Комментарий к файлу: Си, протеус menu_test.zip [21.42 KiB]
Скачиваний: 586
Привет! Был проект на основе 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
Ребята, выручайте! Завяз я с этим микроменю 2. Я слишком плохо ориентируюсь в этих указателях и просто запутался в некоторых моментах. Я не пойму каким образом выводится поле Text при нажатии кнопок, если основная функция вывода строки static void Generic_Write(const char* Text); находится в main.c и вызывается всего один раз перед бесконечным циклом опроса кнопок.
У меня сейчас дисплей 128х64. Хочу сделать меню по типу, как DimAlt реализовал, но с некоторыми изменениями. Инверсию выбранной строчки хочу заменить на присутствие символа ">" перед строкой меню. Инверсию пробовал, строчка плохо читается. Хочу вывести сразу все пункты выбранного меню. В оригинальной библиотеке выводится только один пункт. А что отвечает за его вывод я не пойму, о чем в начале и написал.
Программист я никакой, хотя и пишу прошивки для своих устройств. Но эта самая сложная из всех, что были. Очень нужна помощь! Можно в форуме меня помидорами закидывать, можно в личке. Но вопросов реально много. Пока все не озвучиваю, потому как возможно после ваших советов я пойму суть проблемы и дальше пойдет легче. Но пока дело не движется
Смотрю код 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);
Последний раз редактировалось DimAlt Пт окт 26, 2018 17:50:13, всего редактировалось 3 раз(а).
DimAlt? спасибо за пояснение. Попробую все это понять. Но уже понял по Вашим пояснениям, что я язык СИ знаю на 2 странички учебника Первое, что надо понять, как работает static void (*MenuWriteFunc)(void) = NULL;
_________________ "Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа." Ро́берт Ше́кли Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Дополнил предыдущий пост. Попытался объяснить как рисуется пункт меню. В моем исходнике, для прорисовки главного пункта меню, используется функция
Код:
//---Главное меню, рисует только пункты(без параметров)---------- 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.
Это первый и пока единственный мой проект меню. А первый блин имеет право быть комом
Да ничего ж себе ком . Для таких "программистов" как я, там поле не паханое в плане ковыряния учебников. Спасибо, пояснения подробные, но все равно требуют осмысления. Мне легко эти указатели не даются. Я первоначальную попытку с этим микро меню делал еще по статье http://easyelectronics.ru/organizaciya- ... menyu.html Тоже ее удалось запустить, только там автор реализовал прокрутку выбранного меню относительно центра экрана. Мне не очень это понравилось и я решил с нуля разобраться. Ну и закопался по самые уши Просто у меня этот вывод на дисплей тормозит весь проект. Я всеми правдами и неправдами пытаюсь его допилить, пусть и с костылями, но лишь бы он работал. Потому, что это пока единичное устройство, где я первый раз применил графический индикатор и где можно сделать интерфейс, а не жать комбинации кнопок, как ранее я делал.
_________________ "Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа." Ро́берт Ше́кли Я правильных ответов знаю мало, поэтому не стесняюсь и много спрашиваю.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 47
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения