| Форум РадиоКот https://radiokot.ru/forum/ |
|
| Меню в stm32 & LCD https://radiokot.ru/forum/viewtopic.php?f=59&t=190710 |
Страница 1 из 2 |
| Автор: | ioan dobrev [ Пн ноя 06, 2023 22:40:47 ] |
| Заголовок сообщения: | Меню в stm32 & LCD |
Как правильно создать меню на указателях и в чём его суть? |
|
| Автор: | >TEHb< [ Пн ноя 06, 2023 22:52:27 ] |
| Заголовок сообщения: | Re: Меню в stm32 & LCD |
Указатель суть есть адрес вызываемой функции обработчика меню. По нажатию кнопки вызывается соответствующая функция, где уже прописана реакция. |
|
| Автор: | ioan dobrev [ Вт ноя 07, 2023 11:41:56 ] |
| Заголовок сообщения: | Re: Меню в stm32 & LCD |
Указатель суть есть адрес вызываемой функции обработчика меню. По нажатию кнопки вызывается соответствующая функция, где уже прописана реакция. вы имеете ввиду что на любую кнопку нужна функция?Или как? |
|
| Автор: | Martian [ Вт ноя 07, 2023 12:06:33 ] |
| Заголовок сообщения: | Re: Меню в stm32 & LCD |
если подобное условие возникло, то это и есть суть - решение этого условия. как правильно программировать - слишком общий вопрос |
|
| Автор: | >TEHb< [ Вт ноя 07, 2023 12:33:56 ] |
| Заголовок сообщения: | Re: Меню в stm32 & LCD |
ioan dobrev писал(а): на любую кнопку нужна функция На любое состояние нужна функция. Наверное, проще будет показать пример. Попозже старый проект отрою. |
|
| Автор: | ioan dobrev [ Вт ноя 07, 2023 20:48:57 ] |
| Заголовок сообщения: | Re: Меню в stm32 & LCD |
Ну если можете покажите пример .И как допустим одна кнопка допустим в режиме UP и "+". Добавлено after 2 minutes 4 seconds: И любое состояние функция .И вывод информации. |
|
| Автор: | >TEHb< [ Вт ноя 07, 2023 21:53:43 ] |
| Заголовок сообщения: | Re: Меню в stm32 & LCD |
Тэээк-с, ну допустим. Вот один из вариантов реализации. Оно было скорее как эксперимент, но тем не менее. Итак. Во-первых, надо объявить тип, который будет отвечать за один элемент меню. Код: typedef struct menuitem { char name[17]; //выводимое имя пункта int32_t min; //минимальное значение параметра, который настраивается в меню int32_t max; //максимальное значение int32_t value; //текущее значение, Меняется кнопками "вверх" и "вниз" int32_t oldvalue; //значение до сохранения int32_t step; //шаг изменения значения struct menuitem *left; //соседнее меню слева struct menuitem *right; //соседнее меню справа int32_t (* action)(); //действие пункта меню. Может быть как просто применение текущего значения параметра, так и целая подпрограмма. uint8_t id; //просто номер } menuitem; Далее описываются конкретные пункты. Для каждого пункта прописываются все эти поля. То есть громкость, допустим, регулируется от 5 условных единиц до 100 с шагом 5. Тогда переменная volume типа menuitem должна иметь volume.min=5, volume.max=100, volume.step=5. Ну и так далее со всеми элементами. Код: menuitem mainmenu={{0x41, 0xBC, 0xBE, 0xBB, 0xB8, 0xBF, 0x79, 0xE3, 0x61, 0x20, 0x79, 0xE3, 0x61, 0x70, 0x61, 0x3A, 0x00}, 0, 65000, 0, 0, 0, NULL, NULL, NULL, 0}; menuitem cortres={{0xA8, 0x6F, 0x70, 0x6F, 0xB4, 0x20, 0x4B, 0x3A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00}, 0, 100000, 5000, 5000, 100, NULL, NULL, NULL, 1}; menuitem voltres={{0xA8, 0x6F, 0x70, 0x6F, 0xB4, 0x20, 0x48, 0x3A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00}, 1, 4000, 500, 500, 50, NULL, NULL, NULL, 2}; menuitem blanktime={{0x42, 0x70, 0x65, 0xBC, 0xC7, 0x20, 0xB4, 0xBB, 0x79, 0x78, 0x6F, 0xBF, 0xC3, 0x3A, 0x20, 0x20, 0x00}, 0, 1000, 30, 30, 1, NULL, NULL, NULL, 3}; menuitem dynamic={{0xE0, 0xB8, 0xBD, 0x61, 0xBC, 0xB8, 0xBA, 0x61, 0x20, 0xB8, 0xB4, 0x70, 0xC3, 0x3A, 0x20, 0x20, 0x00}, 0, 1, 0, 0, 1, NULL, NULL, NULL, 4}; menuitem channels={{0x4B, 0x61, 0xBD, 0x61, 0xBB, 0x6F, 0xB3, 0x20, 0xB3, 0x78, 0x6F, 0xE3, 0x61, 0x3A, 0x20, 0x20, 0x20}, 1, 2, 1, 1, 1, NULL, NULL, NULL, 5}; menuitem learn={"Start learning? ", 0, 1, 0, 0, 1, NULL, NULL, NULL, 6}; //запас menuitem soundsample={"Sound sample №:", 0, 1, 0, 0, 1, NULL, NULL, NULL, 7}; menuitem *curitem; Curritem это, собственно, текущий активный элемент меню. Далее описываем необходимые функции для каждого пункта меню. У меня эти функции вызывается по нажатию на кнопку ОК. Например Код: int32_t save() { curitem->oldvalue=curitem->value; FramStoreValue(curitem->value, curitem->id); LedOn(3, 1000); return 0; }; Вот эта функция выполняет сохранения выбранного значения во внешнюю энергонезависимую память и зажигает красный светодиод на секунду. И так любые функции, которые надо выполнять по нажатию кнопки ОК. Дальше начинается само формирования структуры меню. Само меню не древовидное, а в виде двусвязного списка. А можно и ещё связей добавить, сколько хватит кнопок и фантазии. То есть, для, так сказать, главного экрана присваиваем соответствующим полям ссылки на прочие элементы меню. Остальные поля не назначаются, поскольку прочих функций там не предусмотрено. Код: mainmenu.left=&cortres; mainmenu.right=&blanktime; И для всех остальных та же Код: cortres.left=&channels; cortres.right=&blanktime; cortres.action=&save; cortres.oldvalue=FramLoadValue(cortres.id); cortres.value=cortres.oldvalue; blanktime.right=&dynamic; blanktime.left=&cortres; blanktime.action=&save; blanktime.oldvalue=FramLoadValue(blanktime.id); blanktime.value=blanktime.oldvalue; И так далее для всех прочих пунктов. На этом же этапе происходит загрузка ранее сохранённых значений. Проверки нет, но было бы неплохо это предусмотреть. Ну да ладно, это дело завтрашнего дня. Ну и собственно, антидребезг и реакция на каждую кнопку. Можно это дело хоть в прерывания засунуть. Для кнопок влево и вправо предусмотрено просто переключение пунктов, вверх и вниз изменяют параметры, ОК чаще всего просто сохраняет и применяет параметры, ВЫХ не делает ничего, просто возвращает в главное меню. Код: while(millis<presstime+PRESSDELAY){}; //антидребезг delay(100); if(up()){ curitem->value+=curitem->step; if(curitem->value > curitem->max){curitem->value = curitem->max;}; presstime=millis; redraw=1; }; if(down()){ curitem->value-=curitem->step; if(curitem->value < curitem->min){curitem->value = curitem->min;}; presstime=millis; redraw=1; }; if(ok()){ curitem->action(); }; if(esc()){ curitem->value=curitem->oldvalue; curitem=&mainmenu; redraw=1; }; if(left()){ curitem->value=curitem->oldvalue; curitem=curitem->left; redraw=1; }; if(right()){ curitem->value=curitem->oldvalue; curitem=curitem->right; redraw=1; }; Ну и ещё раз повторюсь, что можно увеличить количество связей, можно назначить на каждую кнопку не жёсткую функцию, а тоже вызов заранее определённой функции, можно придумать ещё много всего. Это лишь моя такая небольшая попытка переизобрести меню заново, не обязательно линейное или древовидное. |
|
| Автор: | Martian [ Вт ноя 07, 2023 22:06:42 ] |
| Заголовок сообщения: | Re: Меню в stm32 & LCD |
>TEHb< писал(а): Во-первых, надо объявить тип, который будет отвечать за один элемент меню. Точнее, за каждый элемент. И это и есть ответ на вопрос ioan dobrev писал(а): в чём его суть? . И чтобы окончательно понять преимущество такого подхода, необходимо изучить, что есть ООП (объектно-ориентированное программирование).
|
|
| Автор: | ioan dobrev [ Ср ноя 08, 2023 19:46:35 ] |
| Заголовок сообщения: | Re: Меню в stm32 & LCD |
ООП-а что это такое и с чем его едят.А то у меня меню какое то примитивное хочется пограммотнее |
|
| Автор: | >TEHb< [ Ср ноя 08, 2023 20:06:04 ] |
| Заголовок сообщения: | Re: Меню в stm32 & LCD |
Ну типа каждый пункт меню это такой объект со своими свойствами и функциями. Да пофигу, код-то вполне С-шный. |
|
| Автор: | ioan dobrev [ Чт ноя 09, 2023 10:30:05 ] |
| Заголовок сообщения: | Re: Меню в stm32 & LCD |
Меня заинтересовал 1 код и 2 код.Вопрос 1 структура есть а в структуре есть две структуры .А что в этих структурах?.2 код Это пункты меню? В скопках что указано код для регулировки ? Или что А где же вывод на экран? Добавлено after 7 minutes 33 seconds: Код: menuitem mainmenu={{0x41, 0xBC, 0xBE, 0xBB, 0xB8, 0xBF, 0x79, 0xE3, 0x61, 0x20, 0x79, 0xE3, 0x61, 0x70, 0x61, 0x3A, 0x00}, 0, 65000, 0, 0, 0, NULL, NULL, NULL, 0}; menuitem cortres={{0xA8, 0x6F, 0x70, 0x6F, 0xB4, 0x20, 0x4B, 0x3A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00}, 0, 100000, 5000, 5000, 100, NULL, NULL, NULL, 1}; menuitem voltres={{0xA8, 0x6F, 0x70, 0x6F, 0xB4, 0x20, 0x48, 0x3A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00}, 1, 4000, 500, 500, 50, NULL, NULL, NULL, 2}; menuitem blanktime={{0x42, 0x70, 0x65, 0xBC, 0xC7, 0x20, 0xB4, 0xBB, 0x79, 0x78, 0x6F, 0xBF, 0xC3, 0x3A, 0x20, 0x20, 0x00}, 0, 1000, 30, 30, 1, NULL, NULL, NULL, 3}; menuitem dynamic={{0xE0, 0xB8, 0xBD, 0x61, 0xBC, 0xB8, 0xBA, 0x61, 0x20, 0xB8, 0xB4, 0x70, 0xC3, 0x3A, 0x20, 0x20, 0x00}, 0, 1, 0, 0, 1, NULL, NULL, NULL, 4}; menuitem channels={{0x4B, 0x61, 0xBD, 0x61, 0xBB, 0x6F, 0xB3, 0x20, 0xB3, 0x78, 0x6F, 0xE3, 0x61, 0x3A, 0x20, 0x20, 0x20}, 1, 2, 1, 1, 1, NULL, NULL, NULL, 5}; menuitem learn={"Start learning? ", 0, 1, 0, 0, 1, NULL, NULL, NULL, 6}; //запас menuitem soundsample={"Sound sample №:", 0, 1, 0, 0, 1, NULL, NULL, NULL, 7}; menuitem *curitem; Вот этот пункт. А также последняя строка. Добавлено after 15 minutes 33 seconds: Код: int32_t save() { curitem->oldvalue=curitem->value; FramStoreValue(curitem->value, curitem->id); LedOn(3, 1000); return 0; }; Указатель без"&" ,будет ли он работать.И функция внутри функции а где она? Добавлено after 8 minutes 52 seconds: Код: cortres.left=&channels; cortres.right=&blanktime; cortres.action=&save; cortres.oldvalue=FramLoadValue(cortres.id); cortres.value=cortres.oldvalue; blanktime.right=&dynamic; blanktime.left=&cortres; blanktime.action=&save; blanktime.oldvalue=FramLoadValue(blanktime.id); blanktime.value=blanktime.oldvalue; Я не спец по указателям по меню.Вот эти две структуры я не вижу. Добавлено after 14 minutes 31 second: Код: mainmenu.left=&cortres; mainmenu.right=&blanktime; И вот разименование структуры элемента .А где сами структуры. Код: struct { volatile uint16_t Ua; volatile uint16_t Ub; volatile uint16_t Uc; volatile uint16_t Ia; volatile uint16_t Ib; volatile uint16_t Ic; }par,*par_p; par_p=∥ или я не так понимаю .Это мой пример. |
|
| Автор: | >TEHb< [ Чт ноя 09, 2023 10:35:33 ] |
| Заголовок сообщения: | Re: Меню в stm32 & LCD |
>TEHb< писал(а): struct menuitem *left; //соседнее меню слева struct menuitem *right; //соседнее меню справа Вот это? Это не сами структуры, это лишь поле, содержащее ссылку на другой элемент того же типа. Указатель. По факту просто адрес другого экземпляра структуры. Собственно, в этом и заключается ioan dobrev писал(а): меню на указателях ioan dobrev писал(а): В скопках что указано ioan dobrev писал(а): {0x41, 0xBC, 0xBE, 0xBB, 0xB8, 0xBF, 0x79, 0xE3, 0x61, 0x20, 0x79, 0xE3, 0x61, 0x70, 0x61, 0x3A, 0x00} Вот это? Это поле >TEHb< писал(а): char name[17]; //выводимое имя пункта А в шестнадцатеричном виде потому что это номера кириллических символов в знакосинтезирующем экранчике 1602. А сам вывод это совершенно отдельная независимая функция. Она берёт значения из curitem и выводит уже их. А вот сам *curitem это ссылка на текущий пункт меню. И эта ссылка подменяется по мере надобности. |
|
| Автор: | ioan dobrev [ Чт ноя 09, 2023 10:46:25 ] |
| Заголовок сообщения: | Re: Меню в stm32 & LCD |
Ну хорошо я как аматор спрошу вас.Вот эта строчка. Код: cortres.right=&blanktime; Я имею ввиду с правой стороны что это функция или переменная? если переменная то у меня. Код: /nastroyki.flag_obriv_a=&c; Пишет Cubeide ошибку. |
|
| Автор: | >TEHb< [ Чт ноя 09, 2023 10:57:14 ] |
| Заголовок сообщения: | Re: Меню в stm32 & LCD |
Справа это фактически указатель на пункт меню (структура) blanktime. То есть даже и не переменная как таковая, а адрес в памяти. Чтобы такое присвоение получалось элемент right структуры menuitem объявлен как Код: struct menuitem *right; То есть мы сразу говорим, что это ссылка на структуру типа menuitem. Потом берём blanktime, который имеет тип menuitem, и присваиваем его адрес полю right. |
|
| Автор: | ioan dobrev [ Чт ноя 09, 2023 11:04:34 ] |
| Заголовок сообщения: | Re: Меню в stm32 & LCD |
Код: char name[17]; Так это у вас буфер Для LCD?. А то пункты меню?.Но я не увидел Какие кнопки какие уменьшают или увеличивают параметры в меню?Покажите.Если это буфер то как он выводит пункты меню? |
|
| Автор: | >TEHb< [ Чт ноя 09, 2023 11:16:02 ] |
| Заголовок сообщения: | Re: Меню в stm32 & LCD |
Функция вывода на экран это совершенно отдельная независимая функция. К организации меню она не относится. name это по сути просто строка с выводимым названием меню. ioan dobrev писал(а): какие уменьшают или увеличивают параметры в меню Так вот же: >TEHb< писал(а): if(up()){ curitem->value+=curitem->step; if(curitem->value > curitem->max){curitem->value = curitem->max;}; presstime=millis; redraw=1; }; Если каким-либо способом пришла команда на увеличение параметра (кнопка, ДУ, генератор случайных чисел, не столь важно), то происходит увеличение value в указанных пределах с указанным шагом. Конкретно в данном случае функция UP проверяет состояние ножки. Так что кнопки одновременно нажимать в таком алгоритме нельзя. Но правильный опрос кнопок это опять-таки отдельная задача. |
|
| Автор: | ioan dobrev [ Чт ноя 09, 2023 11:34:59 ] |
| Заголовок сообщения: | Re: Меню в stm32 & LCD |
Код: UP - верх .Doun- вниз Это шагаете вниз и вверх? А допустим есть какой то параметр G в меню как бы вы записали G++; G--?.А эти символы .Покажите как вы выводите на LCD?Много вопросов. |
|
| Автор: | >TEHb< [ Чт ноя 09, 2023 11:51:37 ] |
| Заголовок сообщения: | Re: Меню в stm32 & LCD |
ioan dobrev писал(а): какой то параметр G Объявил бы ещё одну переменную menuitem Gtune и уже внутри неё Gtune.value и устанавливал. И в любом месте программы где надо было бы использовать это значение уже брал бы Gtune.value . ioan dobrev писал(а): Покажите как вы выводите на LCD? Так это же вообще отдельная задача. Ну вот так Код: utoa(curitem->value, string2, 10); stringlenght=0; while(string2[stringlenght]){stringlenght++;}; for(stringcounter=16; stringcounter>=0; stringcounter--) { if (stringlenght>=0){string2[stringcounter]=string2[stringlenght]; stringlenght--;} else {string2[stringcounter]=20;}; }; LCD1602_PrintStringOfPosition(0, curitem->name); LCD1602_PrintStringOfPosition(16, string2); Вначале преобразование числа в десятичную строку, потом что-то про выравнивание строк или вроде того. Не помню уже. А потом вывод библиотечной функцией. Первой строкой название пункта меню (то самое поле name), а второй строкой текущее значение параметра. |
|
| Автор: | ioan dobrev [ Чт ноя 09, 2023 12:00:13 ] |
| Заголовок сообщения: | Re: Меню в stm32 & LCD |
Код: utoa а sprintf как вывести.?
|
|
| Автор: | >TEHb< [ Чт ноя 09, 2023 12:04:01 ] |
| Заголовок сообщения: | Re: Меню в stm32 & LCD |
Не имею ни малейшего понятия. |
|
| Страница 1 из 2 | Часовой пояс: UTC + 3 часа |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|


