20.01.2017, 09:51
|
|
Прохожий
Регистрация: 17.07.2008
Сообщений: 7
Сказал спасибо: 4
Сказали Спасибо 1 раз в 1 сообщении
|
Проблема прототипа процедуры
Коллеги добрый день,
начинаю изучать МК
Корректирую имеющиеся исходники.
Суть такова:
Было меню отображаемое на дисплее, мне необходимо добавить дополнительные пункты меню, при этом они не влезают на один экран и я хочу сделать продолжение меню с отрисовкой новой страницы.
По кнопке "вниз" добавляю переход в процедуру второго меню.
При этом по кнопке "вверх" из второго меню, я должен попасть обратно в первую страницу меню.
Т.к. процедура второго меню описана выше первого, добавляю перед обоими прототип процедуры первого меню.
При этом при компиляции имею ошибку:
Linker warning: function 'key_menu' not used in data stack usage calculation due to possible recursive calls
со ссылкой на описание процедуры первого меню
Код:
|
void key_menu(void);
void key_menu2(void) //Вход во второе меню
{
lcd_clear();lcd_menu2();pp_menu=2;str_print(pp_men u);
do{
#asm("wdr")
if (UP_KEY)
{
#asm("wdr")
if(pp_menu›=3){pp_menu--;str_print(pp_menu);}
else key_menu(); //переход обратно в первое меню
while (UP_KEY){#asm("wdr")};delay_ms(30);
};
if (DOWN_KEY)
{
#asm("wdr")
if(pp_menu‹=6){pp_menu++;str_print(pp_menu);}
while (DOWN_KEY){#asm("wdr")};delay_ms(30);
};
if (OK_KEY)
{
#asm("wdr")
if(pp_menu==2)works_menu_8();
if(pp_menu==3)works_menu_8();
if(pp_menu==4)works_menu_8();
while (OK_KEY){#asm("wdr")};delay_ms(30);
};
}while (MENU_KEY==0);
lcd_clear();lcd_fon();GABARIT;
};
void key_menu(void) //Вход в главное меню
{
lcd_clear();lcd_menu();pp_menu=2;str_print(pp_menu );
do{
#asm("wdr")
if (UP_KEY)
{
#asm("wdr")
if(pp_menu›=3){pp_menu--;str_print(pp_menu);}
while (UP_KEY){#asm("wdr")};delay_ms(30);
};
if (DOWN_KEY)
{
#asm("wdr")
if(pp_menu‹=6){pp_menu++;str_print(pp_menu);}
else key_menu2(); //переход на вторую страницу меню
while (DOWN_KEY){#asm("wdr")};delay_ms(30);
};
if (OK_KEY)
{
#asm("wdr")
if(pp_menu==2)works_menu_2();
if(pp_menu==3)works_menu_3();
if(pp_menu==4)works_menu_4();
if(pp_menu==5)works_menu_5();
if(pp_menu==6)works_menu_6();
if(pp_menu==7)works_menu_7();
while (OK_KEY){#asm("wdr")};delay_ms(30);
};
}while (MENU_KEY==0);
lcd_clear();lcd_fon();GABARIT;
}; |
|
|
|
|
20.01.2017, 11:10
|
|
Прописка
Регистрация: 04.09.2009
Сообщений: 167
Сказал спасибо: 1
Сказали Спасибо 35 раз(а) в 25 сообщении(ях)
|
Re: Проблема прототипа процедуры
Прототип тут ни при чем. Это не ошибка, а предупреждение, это первое. А второе, у Вас по коду возможен рекурсивный вызов т.е. из key_menu вызывается key_menu2, а из key_menu2 возможен вызов key_menu, этот круг может замкнуться, со всеми вытекающими ( переполнение стека и зависание ). Об этом Вас компилятор и предупреждает. Весь код анализировать лениво, но вряд-ли эта рекурсия была изначально задумана. Надо Вам пересмотреть подход, а лучше поизучать примеры меню, в сети их полно.
Последний раз редактировалось shindax; 20.01.2017 в 11:15.
|
|
|
|
20.01.2017, 11:27
|
|
Прохожий
Регистрация: 17.07.2008
Сообщений: 7
Сказал спасибо: 4
Сказали Спасибо 1 раз в 1 сообщении
|
Re: Проблема прототипа процедуры
Сообщение от shindax
|
Это не ошибка, а предупреждение, это первое.
|
Действительно, спасибо
Рекурсия была задумана изначально, для перехода по страницам меню
|
|
|
|
20.01.2017, 12:12
|
|
Гуру портала
Регистрация: 06.05.2005
Адрес: Краснодар, возле укротворного моря.
Сообщений: 19,033
Сказал спасибо: 2,559
Сказали Спасибо 11,881 раз(а) в 5,958 сообщении(ях)
|
Re: Проблема прототипа процедуры
Сообщение от gorlanovmax
|
Рекурсия была задумана изначально, для перехода по страницам меню
|
Из нижнего меню должен быть ВОЗВРАТ в верхнее, а не очередной переход. Тогда и не будет рекурсивной неопределенности.
__________________
Не бейте больно, ежели чо, ну не удержался... А вааще,
"Мы за все хорошее, против всей х..., По лугам некошеным чтобы шли ступни,
Чтобы миром правила правда, а не ложь, Мы за все хорошее, нас не на...!
..." (Ленинград)
Я не несу ответственности за свои действия в Вашей голове.
|
|
|
|
20.01.2017, 12:16
|
|
Прохожий
Регистрация: 17.07.2008
Сообщений: 7
Сказал спасибо: 4
Сказали Спасибо 1 раз в 1 сообщении
|
Re: Проблема прототипа процедуры
Сообщение от akegor
|
Из нижнего меню должен быть ВОЗВРАТ в верхнее, а не очередной переход. Тогда и не будет рекурсивной неопределенности.
|
Подскажите, как правильно это сделать?
Не могу найти примеров
|
|
|
|
20.01.2017, 12:28
|
|
Прописка
Регистрация: 04.09.2009
Сообщений: 167
Сказал спасибо: 1
Сказали Спасибо 35 раз(а) в 25 сообщении(ях)
|
Re: Проблема прототипа процедуры
В функции key_menu2, вместо
напишите
Но повторюсь, код надо анализировать, чтобы дать вразумительный совет.
|
|
|
Эти 2 пользователя(ей) сказали Спасибо shindax за это сообщение:
|
|
|
20.01.2017, 19:33
|
|
Модератор
Регистрация: 04.08.2010
Адрес: Москва СЗАО
Сообщений: 11,257
Сказал спасибо: 11,169
Сказали Спасибо 3,858 раз(а) в 2,928 сообщении(ях)
|
Re: Проблема прототипа процедуры
А без двух подпрограмм в одной все сделать?
pp_menu - вроде как указатель на текущий пункт меню?
Вот и отрабатывать вывод меню на его основе.
А кнопки вверх-вниз отрабатывать в кольце - до начала/конца меню, отображать оставшиеся, в начале/конце переходить на конец/начало. Конец - общее количество - размер экрана или 1.
Листать можно хоть на пункт, хоть на экран.
Как то так.
__________________
rtfm forever должно быть основой для каждого. Альтернатива грустна, поскольку метод слепого щенка успешно работает при весьма малом числе вариантов…
|
|
|
Сказали "Спасибо" mike-y-k
|
|
|
20.01.2017, 21:18
|
|
Прохожий
Регистрация: 17.07.2008
Сообщений: 7
Сказал спасибо: 4
Сказали Спасибо 1 раз в 1 сообщении
|
Re: Проблема прототипа процедуры
Сообщение от mike-y-k
|
А без двух подпрограмм в одной все сделать?
pp_menu - вроде как указатель на текущий пункт меню?
Вот и отрабатывать вывод меню на его основе.
А кнопки вверх-вниз отрабатывать в кольце - до начала/конца меню, отображать оставшиеся, в начале/конце переходить на конец/начало. Конец - общее количество - размер экрана или 1.
Листать можно хоть на пункт, хоть на экран.
Как то так.
|
Спасибо за наводку, до этого я не допер.
|
|
|
|
20.01.2017, 23:44
|
|
Почётный гражданин KAZUS.RU
Регистрация: 29.10.2006
Сообщений: 1,446
Сказал спасибо: 99
Сказали Спасибо 317 раз(а) в 233 сообщении(ях)
|
Re: Проблема прототипа процедуры
Ещё подсказка:
Делается просто набор "экранов". У каждого свой ID.
Ну и вызывается функция отрисовки нужного "экрана".
При нажатии клавиш выбирается действие, исходя из ID текущего "экрана".
Этот простой алгоритм позволит создавать меню любой сложности. И никаких рекурсий.
|
|
|
Сказали "Спасибо" Godzilla82
|
|
|
25.01.2017, 07:15
|
|
Прописка
Регистрация: 04.09.2009
Сообщений: 167
Сказал спасибо: 1
Сказали Спасибо 35 раз(а) в 25 сообщении(ях)
|
Re: Проблема прототипа процедуры
Это называется "Метод конечных автоматов", когда переход из состояния в состояние, осуществляется на основе действия и текущего состояния. Т.е. заводится некая переменная state, которая принимает какие-то заранее описанные значения, т.е. нужно исключить переход системы в несуществующее состояние, логику нужно продумывать. Например state=st_cur_screen. При нажатии на кнопку next, переход к следующему экрану : state = st_cur_screen, при нажатии на кнопку prev, переход к предыдущему экрану : state = st_prev_screen. Обычно заводится большой case, в котором в зависимости от текущего состояния и произошедшего действия, происходит переход к новому состоянию и вызов какой-то функции. В сети есть примеры, например вот:
https://habrahabr.ru/post/241941/
или вот :
http://chipenable.ru/index.php/progr...e-machine.html
Есть ещё метод, когда в зависимости от нового состояния меняется глобальный указатель на заранее описанную функцию с нужным контекстом. Всё зависит от сложности меню и ресурсов МК.
|
|
|
Сказали "Спасибо" shindax
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 20:15.
|
|