Как из цикла while перейти в loop&

Тема в разделе "Arduino & Shields", создана пользователем sanik, 24 фев 2021.

  1. sanik

    sanik Гик

    В двух функциях есть цикл while из одной функции переход в другую работает как надо а вот в том месте где надо выйти из обеих функций ни как не получается.
    Код (C++):
    byte flag;
    byte key() {
      int val = analogRead(0);
      if (val < 50) return 1; // set
      else if (val < 350) return 2; // -
      else if (val < 520) return 3; // +
      else return 0;
    }

    void setup() {
      Serial.begin(9600);
      // put your setup code here, to run once:

    }

    void loop() {
      byte KEY = key();
      if ( KEY == 0) {
        flag = 0;
      }
      if ((KEY == 1) && (flag == 0)) {
        Func_One();
      }
      // здесь выполняется длинный код
      Serial.print("KEY : ");
      Serial.print(KEY);
      Serial.println(" ");
      Serial.println("I'm here!");
      delay(100);
    }

    void Func_One() {
      byte fl = 0;
      byte kol_pos;
      byte menuPos = 0;
      do {
        byte KEY = key();
        if ( KEY == 0) {
          flag = 0;
        }
        if (KEY == 1 && flag == 0 ) {
          flag = 1;
          menuPos++;
          if (menuPos > 2) {
            menuPos = 0;
          }
        }
        if (menuPos == 0) {
          if ((KEY == 2)  && (flag == 0)) {
            flag = 1;
          }
        }
        if (menuPos == 1) {
          if ((KEY == 3) || (KEY == 2)  && (flag == 0)) {
            flag = 1;
            Func_Two(); // переходим во вторую
          }
        }
        if (menuPos == 2) {
          if ((KEY == 3) || (KEY == 2)  && (flag == 0)) {
            flag = 1;
            loop(); // нужно вернутся в луп
            // Exit = 0;
          }
        }
        Serial.print("Position : ");
        Serial.print(menuPos);
        Serial.println(" ");
        Serial.println("Now here");
        delay(100);
      } while (1);
    }

    void Func_Two() {
      byte Exit = 1;
      byte menu2Pos = 0;
      do {
        byte KEY = key();
        if ( KEY == 0) {
          flag = 0;
        }
        if (KEY == 1 && flag == 0) {
          flag = 1;
          menu2Pos++;
          if (menu2Pos > 2) {
            menu2Pos = 0;
          }
        }
        switch (menu2Pos) {
          case 0:
            if (KEY == 3) {
              // Здесь что то творим
              Serial.println(KEY);
            }
            if (KEY == 2) {
              // и здесь что то творим
              Serial.println(KEY);
            }
            break;
          case 1:
            if (KEY == 3) {
              // Здесь что то творим
              Serial.println(KEY);
            }
            if (KEY == 2) {
              // и здесь что то творим
              Serial.println(KEY);
            }
            break;
          case 2:
            if ((KEY == 3) || (KEY == 2)) {
              Func_One(); // вернутся в первую функцию или на крайний случай в луп
            }
            break;
        }
        Serial.print("Position : ");
        Serial.print(menu2Pos);
        Serial.println(" ");
        Serial.println("Stopped in here");
        delay(100);
      } while (1);
    }
     
  2. akl

    akl Гуру

    Func_One(); и Func_Two(); ничего никуда не вернут, а просто создают новую функцию внутри предыдущей. во что вся эта рекурсия может вылиться в итоге - неизвестно. скорее всего все зависнет и ардуина взорвется
     
  3. a1000

    a1000 Гуру

    У вас в конце обоих функций стоит while(1). Микроконтроллер через них к концу функции пробиться никак не сможет.
     
  4. parovoZZ

    parovoZZ Гуру

    Вы си совсем не учили??? Выйти из цикла
    Код (C++):
    break;
    Выйти из функции
    Код (C++):
    return;
     
    genia1991, Andrey12 и sanik нравится это.
  5. sanik

    sanik Гик

    Спасибо! Что то я совсем забыл про эти операторы!
     
  6. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Выйти из функции (цикла), то бишь - подпрограммы, нештатным образом можно. Но несколько таких вЫходов приведут к тн переполнению стека - области памяти хранения адресов точек возврата из подпрограмм (штатный выход - освобождает место для записи). А это приведет к тому, что программа "заблудится". Контролирует ли компилятор Си соблюдение этого правила - я не знаю.
    ПС. С ностальгией вспоминаю время ассемблера Intel8086.
     
    Последнее редактирование: 25 фев 2021
  7. parovoZZ

    parovoZZ Гуру

    Это как?
     
  8. Ariadna-on-Line

    Ariadna-on-Line Гуру

    В Си - не спец. Фантазировать не желаю, дабы не позориться. В Бейсике (в ассемблере тоже) - обычным переходом goto (jump) на произвольную метку в программе.
     
  9. a1000

    a1000 Гуру

    В СИ о стеке ничего не знают. Проблема переполнения стека ложится на плечи компилятора. Попробуйте из функции по goto выйти на метку расположенную вне тела функции.
    Другое дело ASM. Там полная свобода, что наваял - то и запустится. Выйти из подпрограмы по jump (rjump) никто не запрещает. Но такой код рано или поздно глюкнет, ибо стек заедет в оперативку. По сему из подпрограммы выходят по ret (reti из прерываний).
     
    Andrey12 нравится это.
  10. Asper Daffy

    Asper Daffy Иксперд

    И, что там? Проблемы?
     
  11. parovoZZ

    parovoZZ Гуру

    Ньюстон! У нас
    И_что там?
    Запятая после частицы "и" согласно какому правилу?
     
  12. Asper Daffy

    Asper Daffy Иксперд

    Авторское написание, а что?
     
  13. parovoZZ

    parovoZZ Гуру

    Нет такого понятия. Это двоечники придумали.
     
  14. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Центр космической связи - г. Хъюстон !!!
     
  15. parovoZZ

    parovoZZ Гуру

    А у меня Ньюстон!!! Центр программерской мысли!!!
     
  16. a1000

    a1000 Гуру

    Компилятор не разрешит вам сделать такую глупость.
    Как паровоз :):):)
     
  17. Asper Daffy

    Asper Daffy Иксперд

    Мне? Компилятор? Вы, наверное, меня с кем-то путаете или недостаточно хорошо знаете :) Мне он и не такое разрешает. :))) У нас с ним особые отношения. Вернее у меня к нему - я точно знаю, кто здесь хозяин, а компилятор ... он никто и звать его никак.
     
    Ariadna-on-Line и parovoZZ нравится это.
  18. Asper Daffy

    Asper Daffy Иксперд

    Так ото ж! Мы сами придумали и сами используем! Какие-то проблемы в Ньюстоне? :)
     
  19. a1000

    a1000 Гуру

    Ну так переходите на ASM. Там весело. Компилятор вообще уговаривать не надо. Лиш-бы синтаксис сходился и адреса не пересекались. Соглашается с любой хреновиной какую наваяешь.
     
  20. Asper Daffy

    Asper Daffy Иксперд

    Что значит "переходите". Я пишу на всём (и на ассемблере в том числе). Какие куски на чём удобнее, на том и пишу. И мне везде весело. А компилятор я не уговариваю (он что, девочка что-ли?), я ему приказываю :)

    Я тут глянул, Вы оказывается участвовали в дискуссии, где я как раз показывал пример кода с переходом по goto в другую функцию. Забыли?

    А вот тут есть ещё смешнее пример - там безо всякого goto - всё структурно, аж скулы сводит :))) Если будете читать, то лучше до поста №65 включительно. там кое-какие пояснения есть.
     
    Последнее редактирование: 26 фев 2021