Клуб DiyAudio

Начинающим и не только... => Спроси совет => Тема начата: tim от 28 Июня 2012, 14:57:30

Название: Одновременная работа двух циклов в МК
Отправлено: tim от 28 Июня 2012, 14:57:30
Как в Си организовать одновременную работу двух циклов for, чтобы одновременно на 2 порта выводились два различных сигнала?

Или как это реализовать в одном цикле?
Название: Re: Одновременная работа двух циклов в МК
Отправлено: blindman от 28 Июня 2012, 15:08:01
Как в Си организовать одновременную работу двух циклов for
Никак

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

Зависит от того, какие сигналы, в основном - как часто изменяется состояние ног, и что надо делать кроме этого
Название: Re: Одновременная работа двух циклов в МК
Отправлено: aleyer от 28 Июня 2012, 15:11:31
В этих циклах время участвует? Может, через прерывания таймера (-ов) можно решить задачу?
Название: Re: Одновременная работа двух циклов в МК
Отправлено: tim от 28 Июня 2012, 15:19:24
В общем ситуация такая:

Необходимо, чтобы с одного порта светодиод просто мигал, а со второго порта другой светодиод в таком режиме: 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;
         
       };

 }     
 
Название: Re: Одновременная работа двух циклов в МК
Отправлено: blindman от 28 Июня 2012, 15:47:36
Ну я бы сделал так: задержки изменил бы, чтобы они были кратными одному числу - например 30 мс. В цикле организуем счетчик, и в зависимости от его состояния дергаем ногами. После каждого прохода цикла, увеличиваем счетчик и делам паузу 30 мс
Название: Re: Одновременная работа двух циклов в МК
Отправлено: tim от 28 Июня 2012, 16:15:09
Усиливием решение:

#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 раз вместо четырех
Название: Re: Одновременная работа двух циклов в МК
Отправлено: aleyer от 28 Июня 2012, 16:24:50
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.
}
Надо еще только определить значение "какой-то там", как НОК длин циклов работы обеих мигалок.
Название: Re: Одновременная работа двух циклов в МК
Отправлено: blindman от 28 Июня 2012, 16:39:50
Если это именно светодиоды, для индикации, то наверно не так принципиально сделать такие тайминги.

Вот например. Один светодиод включается раз каждые 4 прохода цикла, второй - 8 проходов погашен, затем 4 раза мигает
for (;;)  {
PORTD.0 = ((counter & 3) == 0);
PORTD.1 = ((counter & 8) == 0) && (counter & 1);
counter++;
delay_ms(30);
}
}
Название: Re: Одновременная работа двух циклов в МК
Отправлено: tim от 28 Июня 2012, 16:42:16
aleyer, Не канает о_О На Протеусе - темнота

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

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

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


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

Компилятор ругается на слово "counter"  о_О
Название: Re: Одновременная работа двух циклов в МК
Отправлено: blindman от 28 Июня 2012, 17:00:09
Ну так надо объявить эту переменную - как в твоем коде с i
Название: Re: Одновременная работа двух циклов в МК
Отправлено: tim от 28 Июня 2012, 17:35:57
Ну так надо объявить эту переменную - как в твоем коде с i

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

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

и добавил...
Вопрос снят