Arduino циклы


• О проекте
• Обратная связь
• Полезные ссылки
• Полезные программы
• Друзья сайта


Последние комментарии

Валерий: Работа с часами реального времени DS3231
http://radiolaba....

Алексей: Работа с часами реального времени DS3231
А в чем вопрос?...




           

Библиотека для AVR





AXLIB Генератор





Помощь сайту


   
				

Arduino циклы

	
	
	

Дата: 23 Апреля 2015. Автор: Алексей

	
	
Сегодня будем изучать не менее важную часть языка программирования, как циклы. Зачем они нужны. Давайте например поставим себе цель. Нужно зажигать шесть светодиодов по очереди с периодом в 50 мс, а потом по очереди их гасить с тем же интервалом. Ну что может быть проще. Пишем следующий код:


void setup() {

  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
}

void loop() {

  digitalWrite(2, HIGH);
  delay(50);
  digitalWrite(3, HIGH);
  delay(50);
  digitalWrite(4, HIGH);
  delay(50);
  digitalWrite(5, HIGH);
  delay(50);
  digitalWrite(6, HIGH);
  delay(50);
  digitalWrite(7, HIGH);
  delay(50);
  
  digitalWrite(2, LOW);
  delay(50);
  digitalWrite(3, LOW);
  delay(50);
  digitalWrite(4, LOW);
  delay(50);
  digitalWrite(5, LOW);
  delay(50);
  digitalWrite(6, LOW);
  delay(50);
  digitalWrite(7, LOW);
  delay(50);
}


Сначала мы про инициализировали шесть цифровых выводов со второго по седьмой как выходы, а в основной программе написали поочередно включение светодиода, задержка и так шесть раз. После тоже самое но каждый раз выключали светодиод. Теперь заливаем в Arduino и радуемся работой. Но все таки тут что-то не так. Если внимательно взглянуть на код программы, то можно заметить что есть части кода которые повторяются на протяжении всей программы. Например должно сразу бросится в глаза повторение паузы. А при инициализации выводов меняется только его номер. При включении и выключении тоже меняется только номер. Для такой маленькой программы конечно можно и так оставить, контроллер сожрет это и не поперхнется, а вот если нужно выполнить повторяющийся код, ну например 1000 раз. Я думаю терпения набивать его хватит, а вот хватит ли памяти у МК? Конечно можно спросить, а на кой фиг нам 1000 одинаковых операций? Ну да, тяжело представить. ) Но вот не задача, а если у нас есть массив на 1000 ячеек. Такое часто бывает, например несколько датчиков записывают параметры в массив и как скажете разбираться в этом бардаке. Надо бы как-нибудь разобрать его по каким-либо параметрам. Вот для таких казусов и придумали циклы. Цикл - это некая часть кода которая выполняется определенное количество раз. Одна выполненная часть программы в цикле называется итерация. Количество итераций может быть от 0 до бесконечности. Для выполнения циклов в языке программирования предусмотрено аж три варианта цикла. Поверьте, но этого хватает за глаза на любой изощренный кодинг. Давай те ка это все рассмотрим по подробнее.


Первый цикл while(условие) {}. Как он работает. После слова while в скобках должно быть условие. Условие может быть любы, лишь бы было истинным. Как только условие станет ложным, цикл прекратит свою работу и программа продолжит работать со следующей строки после цикла. Давайте на примере.


    char i = 0;  
    while(i < 10) 
    {
        i++;  
    }


Собственно что тут у нас написано. Сначала мы инициализируем счетную переменную i и обнуляем ее. Далее заходим в цикл и начинаем проверять условие в скобках. Если значение i меньше чем 10, то выполнить тело цикла. В самом теле цикла просто увеличиваем значение счетной переменной на единицу и снова проверяем условие. В нашем случае цикл будет выполнятся 10 раз. То есть сначала значение i равно нулю. Ноль меньше чем десять. Далее увеличили переменную на единицу и сравнили, единица меньше чем десять и так далее. Как только счетная переменная станет равна десяти, то проверяем, десять меньше чем десять? Конечно нет и после проверки цикл прекратит работу. Вот так работает этот цикл. А что делать если нужно по любому один раз выполнить код в теле цикла, даже если он не устраивает условие. Для этого есть друго цикл, под названием do {} while(условие). Работает он точно также как и предыдущий цикл, за исключением одного но. В этом цикле сначало выполняется тело цикла, а затем происходит проверка. Давайте посмотрим как это выглядит в коде.


    char i = 0;
    do
    {
        i++;
    }
    while((i > 0) & (i < 10));


Смотрите как интересно. Сначала мы как и в прошлый раз инициализируем счетную переменную нулем, но в условии записали чтобы i было больше нуля и меньше десяти. То есть значение переменной должно лежать в диапазоне от единицы до девяти. Если бы мы так написали с применением предыдущего цикла, то он не разу бы не выполнился. Но у нас есть волшебное слово do. То есть что произойдет. Сначала в теле цикла значение счетной переменной увеличится и станет единицей, а это больше чем ноль, условие станет истинно. соответственно цикл будет продолжать выполнятся пока счетная переменная не станет равна десяти. И на по следок третий вариант цикла. Как он работает:


    char i;
    for(i = 0; i<10; i++)
    {
        Тело цикла
    }


Как это работает. Сначала опять инициируем счетную переменную, но уже без конкретного значения. Далее пишем слово for, а вот в скобках пишем сначала нашу счетную переменную и присваиваем ей начальное значение. Затем проверяем условие и если оно истинно, то выполняем тело цикла и увеличиваем значение счетной переменной. По сути это тоже самое что и while() {} поэтому какой цикл использовать это уже на ваше усмотрение. Пару слов о некоторых моментах. Если например написать while(1);, то цикл будет выполнятся вечно. Или если с for, то это будет выглядеть так for(;;);. Будте внимательны. Иногда при выполнении цикла ну просто очень хочется все бросить и выйти из него, а условие не позволяет. Как быть? Для этого есть еще одна команда break;. Как только в теле цикла МК наткнется на эту команду, он тут же выйдет из цикла и продолжит выполнение программы со следующей строки после цикла. А вот если у нас при работе цикла возникает условие не удовлетворяющие условие или к примеру момент при котором нам не нужно продолжать выполнять конец тела цикла? Тут нам поможет команда continue;. Как только МК наткнется на эту команду, он брасает все и переходит к выполнению следующей итерации цикла. Надеюсь я все понятно объяснил. Теперь получив данные знания, давайте перепишем нашу программу, но уже используя циклы.


void setup() {
  
  byte i = 2; // Счетная переменная
  
  while(i < 8) // Если i меньше 8, то выполняем тело цикла
  {
    pinMode(i, OUTPUT); //  Инициализация выводов начиная с 2
    i++; // Увеличиваем счетную переменную на единицу
  }

}

void loop() {

  byte i = 2;
  while(i < 8)
  {
    digitalWrite(i, HIGH);
    delay(50);
    i++;
  }

  i = 2;
  while(i < 8)
  {
    digitalWrite(i, LOW);
    delay(50);
    i++;
  }

}


Давайте рассмотрим по ближе. Сначала мы инициализировали счетную переменную i и присвоили ей значение два. Почему два? А потому что я специально выбрал пины со второго по седьмой, дабы убедится что начальное значение не имеет ни какого значения. Каламбур какой-то получился) Ну понятно, да. Далее пишем условие цикла. Нам нужно сделать шесть итераций, так как у нас шесть светодиодов. Замечательно, считаем два плюс шесть будет восемь. Ага, значит нам нужно проверять счетную переменную до тех пор пока она будет меньше восьми. Так и написали while(i < 8). Теперь у нас цикл отработает шесть раз. Что нам нужно сделать внутри тела цикла. Да ничего сложного, просто вписать функцию инициализации вывода на выход, только вместо номера вывода подставить счетную переменную. В чем фокус. Как только МК зайдет в тело цикла, он перед тем как выполнять функцию инициализации вывода, посмотрим на передаваемые аргументы. Один из них должен нести в себе номер вывода, а у нас там счетная переменная. Что делать? А ничего, умный МК посмотрит что там переменная и гордо вытянет из нее число. А у нас там двойка. Ну и замечательно, про инициализируем второй вывод. После увеличим значение счетной переменной еще на единицу и проверим условие. Ага, три меньше восьми, давайте ка все снова и по хорошему, только в переменной теперь три. Значит инициализировать вывод будем уже третий, а затем увеличим счетную переменную на единицу. Вот таким образом перебирая цикл мы настроим все нужные нам выводы. Причем увеличение на единицу счетную переменную это не жесткое условие. Никто не мешает написать например так: i = ((127*i)/31) & 0xF4; И это тоже будет работать, если после выполнения условие будет истинно. Для цикла не важно что происходит в теле, его интересует истинно ли условие или нет. Вот и все. В следующем уроке будем разбирать функции, зачем они нужны и попробуем написать свою.

Читать предыдущий урок

JW Player goes here






Чтобы вставить ссылку используйте форму вида[url]http://www.адрес.ru[/url][text]текст ссылки[/text]
Чтобы вставить код используйте форму вида[code]код[/code]

Имя:   





  








Вверх


Рейтинг@Mail.ru Яндекс.Метрика