Автор Тема: Одновременная работа двух циклов в МК  (Прочитано 12468 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн tim

  • Читаю форум
  • *****
  • Сообщений: 1024
  • Репутация: -1
  • Андрей. город Орел
  • Поблагодарили: +51
    • Сайт ламповика
Как в Си организовать одновременную работу двух циклов for, чтобы одновременно на 2 порта выводились два различных сигнала?

Или как это реализовать в одном цикле?

Оффлайн blindman

  • Старожил
  • *****
  • Сообщений: 798
  • Репутация: 13
  • Андрей
  • Поблагодарили: +18
Re: Одновременная работа двух циклов в МК
« Ответ #1 : 28 Июня 2012, 15:08:01 »
0
Как в Си организовать одновременную работу двух циклов for
Никак

Или как это реализовать в одном цикле?

Зависит от того, какие сигналы, в основном - как часто изменяется состояние ног, и что надо делать кроме этого

Оффлайн aleyer

  • Наш человек
  • ****
  • Сообщений: 361
  • Репутация: 5
  • Леша
  • Поблагодарили: +10
Re: Одновременная работа двух циклов в МК
« Ответ #2 : 28 Июня 2012, 15:11:31 »
0
В этих циклах время участвует? Может, через прерывания таймера (-ов) можно решить задачу?

Оффлайн tim

  • Читаю форум
  • *****
  • Сообщений: 1024
  • Репутация: -1
  • Андрей. город Орел
  • Поблагодарили: +51
    • Сайт ламповика
Re: Одновременная работа двух циклов в МК
« Ответ #3 : 28 Июня 2012, 15:19:24 »
0
В общем ситуация такая:

Необходимо, чтобы с одного порта светодиод просто мигал, а со второго порта другой светодиод в таком режиме: 4 мигания - пауза, 4 мигания - пауза, 4 мигания - пауза...

И все это должно происходить одновременно.

и добавил...
Я "повис" в таком состоянии:

 while (1)  //Организовываем бесконечный цикл

       {
         
         for (i = 0; i<4 ; i++)               // Цикл мигание первого светодиода, 4 раза
          {
          PORTD.0=1; //Включаем светодиод на 0 выходе порта D.0   
          delay_ms(40); //Делаем задержку     
                       
          PORTD.0=0; //Выключаем светодиод на 0 выходе порта D.0 
          delay_ms(180); //Делаем задержку   
          }
           
                   
              L2:
       for (i = 0; i<4 ; i++)            // Мигание второго светодиода, 4 раза
         {
         PORTD.1=1; //Включаем светодиод на 0 выходе порта D.1 
         delay_ms(40); //Делаем задержку   
                       
         PORTD.1=0; //Выключаем светодиод на 0 выходе порта D.1 
         delay_ms(30); //Делаем задержку
         }
          delay_ms(400);
       goto L2;
         
       };

 }     
 
« Последнее редактирование: 28 Июня 2012, 15:25:44 от tim »

Оффлайн blindman

  • Старожил
  • *****
  • Сообщений: 798
  • Репутация: 13
  • Андрей
  • Поблагодарили: +18
Re: Одновременная работа двух циклов в МК
« Ответ #4 : 28 Июня 2012, 15:47:36 »
0
Ну я бы сделал так: задержки изменил бы, чтобы они были кратными одному числу - например 30 мс. В цикле организуем счетчик, и в зависимости от его состояния дергаем ногами. После каждого прохода цикла, увеличиваем счетчик и делам паузу 30 мс

Оффлайн tim

  • Читаю форум
  • *****
  • Сообщений: 1024
  • Репутация: -1
  • Андрей. город Орел
  • Поблагодарили: +51
    • Сайт ламповика
Re: Одновременная работа двух циклов в МК
« Ответ #5 : 28 Июня 2012, 16:15:09 »
0
Усиливием решение:

#include <mega8.h> //Включаем библиотеку для работы с микроконтроллером ATMega8
#include <delay.h> //Включаем библиотеку для организации задержек



 void main(void)
{       
char i1 = 1;
char i2 = 1;
char i2count = 0;
int i;  // описание переменной "і" как целое число Int - (Integer)

 PORTD=0x00; //Выставляем все выходы порта D на 0, то есть, выключаем весь порт D
 DDRD=0xFF;  //Делаем порт D, как выход, чтобы на выходах порта было напряжение 5В

while(1)
{
  if (i1==1)  // на первой миллисекунде включаем
    PORTD.0=1; //Включаем светодиод на 0 выходе порта D.0
  else if (i1==40) // на сороковой выключаем
    PORTD.0=0; //Выключаем светодиод на 0 выходе порта D.0
  else if (i1>=220) // на 220 миллисекунде (40+180) сбрасываем счётчик на ноль
    i1 = 0;
  else  // в противном случае просто увеличиваем счётчик
    i1++;
 
  if (i2==1) // для первой светодиода на нулевой включаем
    PORTD.1=1; //Включаем светодиод на 0 выходе порта D.1
  else if (i2==40) // на сороковой выключаем
    PORTD.1=0; //Выключаем светодиод на 0 выходе порта D.1
  else if (i2>=140) // если больше 140 (40+100), то принимаем решение, нужно ли ещё мигать или делать паузу
  {
    if (i2count<4) // если было меньше 4 миганий, то просто мигаем ещё
    {
      i2 = 0;  // сбрасываем счётчик миллисекунд
      i2count++; // и увеличиваем счётчик миганий
    } else
    {           // если было уже 4 мигания, то счётчик не сбрасываем, а ожидаем ещё 400 мс
      if (++i2 >= 540) // увеличиваем счётчик и если он стал больше 540 мс (40+100 с последнего мигания +400)
      {
        i2=0;  // сбрасываем все счётчики, относящиеся ко второму диоду
        i2count=0;
      }
    }
  }
  i1++; // увеличивам оба счётчика на 1 мс
  i2++;
  delay_ms(1); // задержка 1 мс для цикла
}
}

Теперь первый светодиод мигает адекватно, второй - 1 раз вместо четырех

Оффлайн aleyer

  • Наш человек
  • ****
  • Сообщений: 361
  • Репутация: 5
  • Леша
  • Поблагодарили: +10
Re: Одновременная работа двух циклов в МК
« Ответ #6 : 28 Июня 2012, 16:24:50 »
0
tim, все очень перемудрено. Достаточно switch, case'ов и одного счетчика.
int i=0;
while(1)
{
switch(i)
{
case 0:
case 22:
     PORTD.0=1;
case 4:
case 26:
     PORTD.0=0;

//и так далее
case какой-то там:
i=-1;
}
delay_ms(10);
++i; //каждые 10мс (все значения кратны 10мс) увеличиваем счетчик на 1.
}
Надо еще только определить значение "какой-то там", как НОК длин циклов работы обеих мигалок.

Оффлайн blindman

  • Старожил
  • *****
  • Сообщений: 798
  • Репутация: 13
  • Андрей
  • Поблагодарили: +18
Re: Одновременная работа двух циклов в МК
« Ответ #7 : 28 Июня 2012, 16:39:50 »
0
Если это именно светодиоды, для индикации, то наверно не так принципиально сделать такие тайминги.

Вот например. Один светодиод включается раз каждые 4 прохода цикла, второй - 8 проходов погашен, затем 4 раза мигает
for (;;)  {
PORTD.0 = ((counter & 3) == 0);
PORTD.1 = ((counter & 8) == 0) && (counter & 1);
counter++;
delay_ms(30);
}
}

Оффлайн tim

  • Читаю форум
  • *****
  • Сообщений: 1024
  • Репутация: -1
  • Андрей. город Орел
  • Поблагодарили: +51
    • Сайт ламповика
Re: Одновременная работа двух циклов в МК
« Ответ #8 : 28 Июня 2012, 16:42:16 »
0
aleyer, Не канает о_О На Протеусе - темнота

А со вторым портом что делать?

и добавил...
Если это именно светодиоды, для индикации, то наверно не так принципиально сделать такие тайминги.

Вот например. Один светодиод включается раз каждые 4 прохода цикла, второй - 8 проходов погашен, затем 4 раза мигает
for (;;)  {
PORTD.0 = ((counter & 3) == 0);
PORTD.1 = ((counter & 8) == 0) && (counter & 1);
counter++;
delay_ms(30);
}
}


В конечном варианте - это 2 канала светододов

Компилятор ругается на слово "counter"  о_О
« Последнее редактирование: 28 Июня 2012, 16:50:20 от tim »

Оффлайн blindman

  • Старожил
  • *****
  • Сообщений: 798
  • Репутация: 13
  • Андрей
  • Поблагодарили: +18
Re: Одновременная работа двух циклов в МК
« Ответ #9 : 28 Июня 2012, 17:00:09 »
0
Ну так надо объявить эту переменную - как в твоем коде с i

Оффлайн tim

  • Читаю форум
  • *****
  • Сообщений: 1024
  • Репутация: -1
  • Андрей. город Орел
  • Поблагодарили: +51
    • Сайт ламповика
Re: Одновременная работа двух циклов в МК
« Ответ #10 : 28 Июня 2012, 17:35:57 »
0
Ну так надо объявить эту переменную - как в твоем коде с i

ой, а я думал, что это - функция такая...  ;-[

и добавил...
Всё работает. В Протеусе всё адекватно. А как быть при прошивке МК с фьюзами?

и добавил...
Вопрос снят
« Последнее редактирование: 29 Июня 2012, 11:45:42 от tim »

 

Похожие темы

  Тема / Автор Ответов Последний ответ
24 Ответов
23819 Просмотров
Последний ответ 09 Января 2013, 00:55:24
от Гocть
27 Ответов
28862 Просмотров
Последний ответ 05 Декабря 2012, 18:47:32
от Nick
9 Ответов
12267 Просмотров
Последний ответ 19 Февраля 2013, 06:52:36
от WolfTheGrey
4 Ответов
6186 Просмотров
Последний ответ 14 Сентября 2017, 10:12:43
от Станислав
41 Ответов
20876 Просмотров
Последний ответ 19 Октября 2018, 17:21:02
от GoRs