Меню в stm32 & LCD
-
ioan dobrev
- Открыл глаза
- Сообщения: 72
- Зарегистрирован: Вт сен 19, 2023 07:07:05
Меню в stm32 & LCD
Как правильно создать меню на указателях и в чём его суть?
- Реклама
- >TEHb<
- Друг Кота
- Сообщения: 5742
- Зарегистрирован: Ср ноя 11, 2009 17:19:30
- Откуда: Воронеж
- Контактная информация:
Re: Меню в stm32 & LCD
Указатель суть есть адрес вызываемой функции обработчика меню. По нажатию кнопки вызывается соответствующая функция, где уже прописана реакция.
"Привет!" - соврал он.
-
ioan dobrev
- Открыл глаза
- Сообщения: 72
- Зарегистрирован: Вт сен 19, 2023 07:07:05
Re: Меню в stm32 & LCD
[uquote=">TEHb<",url="/forum/viewtopic.php?p=4498944#p4498944"]Указатель суть есть адрес вызываемой функции обработчика меню. По нажатию кнопки вызывается соответствующая функция, где уже прописана реакция.[/uquote]
вы имеете ввиду что на любую кнопку нужна функция?Или как?
вы имеете ввиду что на любую кнопку нужна функция?Или как?
Re: Меню в stm32 & LCD
если подобное условие возникло, то это и есть суть - решение этого условия.
как правильно программировать - слишком общий вопрос
как правильно программировать - слишком общий вопрос
- >TEHb<
- Друг Кота
- Сообщения: 5742
- Зарегистрирован: Ср ноя 11, 2009 17:19:30
- Откуда: Воронеж
- Контактная информация:
Re: Меню в stm32 & LCD
На любое состояние нужна функция. Наверное, проще будет показать пример. Попозже старый проект отрою.ioan dobrev писал(а): на любую кнопку нужна функция
"Привет!" - соврал он.
- Реклама
-
ioan dobrev
- Открыл глаза
- Сообщения: 72
- Зарегистрирован: Вт сен 19, 2023 07:07:05
Re: Меню в stm32 & LCD
Ну если можете покажите пример .И как допустим одна кнопка допустим в режиме UP и "+".
Добавлено after 2 minutes 4 seconds:
И любое состояние функция .И вывод информации.
Добавлено after 2 minutes 4 seconds:
И любое состояние функция .И вывод информации.
- >TEHb<
- Друг Кота
- Сообщения: 5742
- Зарегистрирован: Ср ноя 11, 2009 17:19:30
- Откуда: Воронеж
- Контактная информация:
Re: Меню в stm32 & LCD
Тэээк-с, ну допустим. Вот один из вариантов реализации. Оно было скорее как эксперимент, но тем не менее.
Итак. Во-первых, надо объявить тип, который будет отвечать за один элемент меню.
Далее описываются конкретные пункты. Для каждого пункта прописываются все эти поля. То есть громкость, допустим, регулируется от 5 условных единиц до 100 с шагом 5. Тогда переменная volume типа menuitem должна иметь volume.min=5, volume.max=100, volume.step=5. Ну и так далее со всеми элементами.
Curritem это, собственно, текущий активный элемент меню.
Далее описываем необходимые функции для каждого пункта меню. У меня эти функции вызывается по нажатию на кнопку ОК. Например
Вот эта функция выполняет сохранения выбранного значения во внешнюю энергонезависимую память и зажигает красный светодиод на секунду.
И так любые функции, которые надо выполнять по нажатию кнопки ОК.
Дальше начинается само формирования структуры меню. Само меню не древовидное, а в виде двусвязного списка. А можно и ещё связей добавить, сколько хватит кнопок и фантазии. То есть, для, так сказать, главного экрана присваиваем соответствующим полям ссылки на прочие элементы меню. Остальные поля не назначаются, поскольку прочих функций там не предусмотрено.
И для всех остальных та же
И так далее для всех прочих пунктов. На этом же этапе происходит загрузка ранее сохранённых значений. Проверки нет, но было бы неплохо это предусмотреть. Ну да ладно, это дело завтрашнего дня.
Ну и собственно, антидребезг и реакция на каждую кнопку. Можно это дело хоть в прерывания засунуть. Для кнопок влево и вправо предусмотрено просто переключение пунктов, вверх и вниз изменяют параметры, ОК чаще всего просто сохраняет и применяет параметры, ВЫХ не делает ничего, просто возвращает в главное меню.
Ну и ещё раз повторюсь, что можно увеличить количество связей, можно назначить на каждую кнопку не жёсткую функцию, а тоже вызов заранее определённой функции, можно придумать ещё много всего. Это лишь моя такая небольшая попытка переизобрести меню заново, не обязательно линейное или древовидное.
Итак. Во-первых, надо объявить тип, который будет отвечать за один элемент меню.
Код: Выделить всё
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;Код: Выделить всё
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;Далее описываем необходимые функции для каждого пункта меню. У меня эти функции вызывается по нажатию на кнопку ОК. Например
Код: Выделить всё
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;
};"Привет!" - соврал он.
Re: Меню в stm32 & LCD
Точнее, за каждый элемент. И это и есть ответ на вопрос>TEHb< писал(а):Во-первых, надо объявить тип, который будет отвечать за один элемент меню.
. И чтобы окончательно понять преимущество такого подхода, необходимо изучить, что есть ООП (объектно-ориентированное программирование).ioan dobrev писал(а):в чём его суть?
-
ioan dobrev
- Открыл глаза
- Сообщения: 72
- Зарегистрирован: Вт сен 19, 2023 07:07:05
Re: Меню в stm32 & LCD
ООП-а что это такое и с чем его едят.А то у меня меню какое то примитивное хочется пограммотнее
- >TEHb<
- Друг Кота
- Сообщения: 5742
- Зарегистрирован: Ср ноя 11, 2009 17:19:30
- Откуда: Воронеж
- Контактная информация:
Re: Меню в stm32 & LCD
Ну типа каждый пункт меню это такой объект со своими свойствами и функциями.
Да пофигу, код-то вполне С-шный.
Да пофигу, код-то вполне С-шный.
"Привет!" - соврал он.
-
ioan dobrev
- Открыл глаза
- Сообщения: 72
- Зарегистрирован: Вт сен 19, 2023 07:07:05
Re: Меню в stm32 & LCD
Меня заинтересовал 1 код и 2 код.Вопрос 1 структура есть а в структуре есть две структуры .А что в этих структурах?.2 код Это пункты меню? В скопках что указано код для регулировки ? Или что А где же вывод на экран?
Добавлено after 7 minutes 33 seconds:
Вот этот пункт. А также последняя строка.
Добавлено after 15 minutes 33 seconds:
Указатель без"&" ,будет ли он работать.И функция внутри функции а где она?
Добавлено after 8 minutes 52 seconds:
Я не спец по указателям по меню.Вот эти две структуры я не вижу.
Добавлено after 14 minutes 31 second:
И вот разименование структуры элемента .А где сами структуры.
или я не так понимаю .Это мой пример.
Добавлено 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<
- Друг Кота
- Сообщения: 5742
- Зарегистрирован: Ср ноя 11, 2009 17:19:30
- Откуда: Воронеж
- Контактная информация:
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}
А в шестнадцатеричном виде потому что это номера кириллических символов в знакосинтезирующем экранчике 1602. А сам вывод это совершенно отдельная независимая функция. Она берёт значения из curitem и выводит уже их.>TEHb< писал(а):char name[17]; //выводимое имя пункта
А вот сам *curitem это ссылка на текущий пункт меню. И эта ссылка подменяется по мере надобности.
"Привет!" - соврал он.
-
ioan dobrev
- Открыл глаза
- Сообщения: 72
- Зарегистрирован: Вт сен 19, 2023 07:07:05
Re: Меню в stm32 & LCD
Ну хорошо я как аматор спрошу вас.Вот эта строчка.
Я имею ввиду с правой стороны что это функция или переменная? если переменная то у меня.
Пишет Cubeide ошибку.
Код: Выделить всё
cortres.right=&blanktime;Код: Выделить всё
/nastroyki.flag_obriv_a=&c;
- >TEHb<
- Друг Кота
- Сообщения: 5742
- Зарегистрирован: Ср ноя 11, 2009 17:19:30
- Откуда: Воронеж
- Контактная информация:
Re: Меню в stm32 & LCD
Справа это фактически указатель на пункт меню (структура) blanktime. То есть даже и не переменная как таковая, а адрес в памяти. Чтобы такое присвоение получалось элемент right структуры menuitem объявлен как
То есть мы сразу говорим, что это ссылка на структуру типа menuitem. Потом берём blanktime, который имеет тип menuitem, и присваиваем его адрес полю right.
Код: Выделить всё
struct menuitem *right;"Привет!" - соврал он.
-
ioan dobrev
- Открыл глаза
- Сообщения: 72
- Зарегистрирован: Вт сен 19, 2023 07:07:05
Re: Меню в stm32 & LCD
Код: Выделить всё
char name[17]; А то пункты меню?.Но я не увидел Какие кнопки какие уменьшают или увеличивают параметры в меню?Покажите.Если это буфер то как он выводит пункты меню?
- >TEHb<
- Друг Кота
- Сообщения: 5742
- Зарегистрирован: Ср ноя 11, 2009 17:19:30
- Откуда: Воронеж
- Контактная информация:
Re: Меню в stm32 & LCD
Функция вывода на экран это совершенно отдельная независимая функция. К организации меню она не относится. name это по сути просто строка с выводимым названием меню.
Так вот же:ioan dobrev писал(а):какие уменьшают или увеличивают параметры в меню
Если каким-либо способом пришла команда на увеличение параметра (кнопка, ДУ, генератор случайных чисел, не столь важно), то происходит увеличение value в указанных пределах с указанным шагом. Конкретно в данном случае функция UP проверяет состояние ножки. Так что кнопки одновременно нажимать в таком алгоритме нельзя. Но правильный опрос кнопок это опять-таки отдельная задача.>TEHb< писал(а): if(up()){
curitem->value+=curitem->step;
if(curitem->value > curitem->max){curitem->value = curitem->max;};
presstime=millis;
redraw=1;
};
"Привет!" - соврал он.
-
ioan dobrev
- Открыл глаза
- Сообщения: 72
- Зарегистрирован: Вт сен 19, 2023 07:07:05
Re: Меню в stm32 & LCD
Код: Выделить всё
UP - верх .Doun- вниз- >TEHb<
- Друг Кота
- Сообщения: 5742
- Зарегистрирован: Ср ноя 11, 2009 17:19:30
- Откуда: Воронеж
- Контактная информация:
Re: Меню в stm32 & LCD
Объявил бы ещё одну переменную menuitem Gtune и уже внутри неё Gtune.value и устанавливал. И в любом месте программы где надо было бы использовать это значение уже брал бы Gtune.value .ioan dobrev писал(а):какой то параметр G
Так это же вообще отдельная задача. Ну вот так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);"Привет!" - соврал он.
-
ioan dobrev
- Открыл глаза
- Сообщения: 72
- Зарегистрирован: Вт сен 19, 2023 07:07:05
Re: Меню в stm32 & LCD
Код: Выделить всё
utoa

