2x nekonečná smyčka

Zdravím Všechy,

Mám ATmegu8, používám interní 1Mhz, porgramuju v C#

Chtěl bych radu, můžu mít dvě nekonečné smyčky, které běží zároveň?

   while(1) // první nekonečná smyčka 
    {
      ...
     }
  // druhá zároveň běžící nekonečná smyčka 

ptal jsem se učitelky na programování, ale ta mě asi nepochopila, protože mi tvrdila, že ten program někdy skončit musí a musí být ukončen…

A ještě jeden dotaz
udělal jsem si počítadlo které počítá od 0 do 9 a stále se opakuje
problém je v tom, že cca 1 minuta (reálná) v zařízení trvá asi 58sec, napadlo mě, že bych upravil parametr _delay_ms(1000) za nižší číslo, ale to asi nepůjde protože to zpoždění je nelineární, takže za nějaký čas by došlo opět ke zpoždění. Jak udělat aby 1 minuta byla 6x se opakující 0 až 9?

Děkuji za rady.

přikládám kód

#define F_CPU 1000000

#include <avr/io.h> 
#include <util/delay.h>

int main(void) 
 {
  DDRD = 0xFF;
  while(1)
   {
    //zapni 0
    PORTD |= (1<<PD0);
    PORTD |= (1<<PD1);
    PORTD |= (1<<PD3);
    PORTD |= (1<<PD4);
    PORTD |= (1<<PD5);
    PORTD |= (1<<PD6);
    _delay_ms(1000);
    //vypni 0
    PORTD &= ~(1<<PD0);
    PORTD &= ~(1<<PD1);
    PORTD &= ~(1<<PD3);
    PORTD &= ~(1<<PD4);
    PORTD &= ~(1<<PD5);
    PORTD &= ~(1<<PD6);
    //zapni 1
    PORTD |= (1<<PD1);
    PORTD |= (1<<PD3);
    _delay_ms(1000);
    //vypni 1
    PORTD &= ~(1<<PD1);
    PORTD &= ~(1<<PD3);
    //zapni 2 
    PORTD |= (1<<PD0);
    PORTD |= (1<<PD1);
    PORTD |= (1<<PD2);
    PORTD |= (1<<PD4);
    PORTD |= (1<<PD5);
    _delay_ms(1000);
    //vypni 2
    PORTD &= ~(1<<PD0);
    PORTD &= ~(1<<PD1);
    PORTD &= ~(1<<PD2);
    PORTD &= ~(1<<PD4);
    PORTD &= ~(1<<PD5);
    //zapni 3
    PORTD |= (1<<PD0);
    PORTD |= (1<<PD1);
    PORTD |= (1<<PD2);
    PORTD |= (1<<PD3);
    PORTD |= (1<<PD4);
    _delay_ms(1000);
    //vypni 3
    PORTD &= ~(1<<PD0);
    PORTD &= ~(1<<PD1);
    PORTD &= ~(1<<PD2);
    PORTD &= ~(1<<PD3);
    PORTD &= ~(1<<PD4);
    //zapni 4
    PORTD |= (1<<PD1);
    PORTD |= (1<<PD2);
    PORTD |= (1<<PD3);
    PORTD |= (1<<PD6);
    _delay_ms(1000);
    //vypni 4 
    PORTD &= ~(1<<PD1);
    PORTD &= ~(1<<PD2);
    PORTD &= ~(1<<PD3);
    PORTD &= ~(1<<PD4);
    //zapni 5 
    PORTD |= (1<<PD0);
    PORTD |= (1<<PD2);
    PORTD |= (1<<PD3);
    PORTD |= (1<<PD4);
    PORTD |= (1<<PD6);
    _delay_ms(1000);
    //vypni 5    
    PORTD &= ~(1<<PD0);
    PORTD &= ~(1<<PD2);
    PORTD &= ~(1<<PD3);
    PORTD &= ~(1<<PD4);
    PORTD &= ~(1<<PD6);
    //zapni 6 
    PORTD |= (1<<PD0);
    PORTD |= (1<<PD2);
    PORTD |= (1<<PD3);
    PORTD |= (1<<PD4);
    PORTD |= (1<<PD5);
    PORTD |= (1<<PD6);
    _delay_ms(1000);
    //vypni 6
    PORTD &= ~(1<<PD0);
    PORTD &= ~(1<<PD2);
    PORTD &= ~(1<<PD3);
    PORTD &= ~(1<<PD4);
    PORTD &= ~(1<<PD5);
    PORTD &= ~(1<<PD6);
    // zapni 7
    PORTD |= (1<<PD0);
    PORTD |= (1<<PD1);
    PORTD |= (1<<PD3);
    _delay_ms(1000);
    //vypni 7
    PORTD &= ~(1<<PD0);
    PORTD &= ~(1<<PD1);
    PORTD &= ~(1<<PD3);
    //zapni 8
    PORTD |= (1<<PD0);
    PORTD |= (1<<PD1);
    PORTD |= (1<<PD2);
    PORTD |= (1<<PD3);
    PORTD |= (1<<PD4);
    PORTD |= (1<<PD5);
    PORTD |= (1<<PD6);
    _delay_ms(1000);
    //vypni 8
    PORTD &= ~(1<<PD0);
    PORTD &= ~(1<<PD1);
    PORTD &= ~(1<<PD2);
    PORTD &= ~(1<<PD3);
    PORTD &= ~(1<<PD4);
    PORTD &= ~(1<<PD5);
    PORTD &= ~(1<<PD6);
    //zapni 9
    PORTD |= (1<<PD0);
    PORTD |= (1<<PD1);
    PORTD |= (1<<PD2);
    PORTD |= (1<<PD3);
    PORTD |= (1<<PD4);
    PORTD |= (1<<PD6);
    _delay_ms(1000);
    //vypni 9
    PORTD &= ~(1<<PD0);
    PORTD &= ~(1<<PD1);
    PORTD &= ~(1<<PD2);
    PORTD &= ~(1<<PD3);
    PORTD &= ~(1<<PD4);
    PORTD &= ~(1<<PD6);
   }
 }

K času v _delay_ms()

treba ešte pripočítať čas pre ralizáciu ďaľších príkazov.
A ten čas sa samozrejme neprejavuje “konštante”.

Preto je zhovadilosť na meranie času používať delay
Na to je časovač. Až k jeho fungovaniu prídeš, posunieš sa mentálne v chápaní poňatia MCU ďalej.

K prvej otázke.

Ak je nejaká slučka nekonečná, do ďalšej slučky sa program jednoducho nemá ako dostať. A je úplne jedno či konečná je alebo nie je. Ak pani profesorka tvrdí, že program sa jednoducho MUSÍ raz skončiť, pozdravuj ju a skús jej navrhnúť, či by vedela spraviť zariadenie/program, ktorý by si niekto naozaj bez toho aby ju poznal kúpil, len preto, že je kvalitný :slight_smile:

Držím palec :slight_smile:

Bohužel (Bohudík) 8mi bitové procesory multitasking neumí.

Souhlasím s Martinem, že se musíš naučit používat časovač,
protože pouze pomocí něj můžeš něco takového naprogramovat.

Nazdavam sa, ze 8bity multitasking vedia. Je pravda, ze s nim by sa dalo spustit X nekonecnych sluciek. O tejto moznosti som vzhladom na uroven programu ani neuvazoval. Ale je pravda, ze s multitaskingom by to slo.
Existuje niekolko nastrojov ako sa k tomu dopracovat. Treba googlit. No nerobil by som to bez zvladnutia (aj) toho casovaca a prerusenia.

.
Myšlenka upravit _delay() je správná. Nevím o žádné nelinearitě.
Chvíli ale trvá, než pomocí simulátoru najdeš hodnoty pro _delay().
(A pro různé kompilátory se může lišit.)

U mně funguje toto: (WINAVR-20100110)

int main(void) { while(1) { // invertuj bity PORTD ^= (1<<PD0)|(1<<PD1)|(1<<PD2)|(1<<PD3)|(1<<PD4)|(1<<PD5)|(1<<PD6); _delay_ms(961); _delay_us(555); } }
Ale všimni si, že tento kód zaměstnává stoprocentně procesor, takže už nemůže dělat nic jiného.
Proto se v praxi používají ke zpoždění časovače.

Jednoduše řečeno, dvě nekonečné smyčky nemohou běžet současně.
A v začátcích to určitě v žádném programu nebudeš potřebovat.

Ahoj,

myslím, že se pro začátek pouštíš do moc složité věci. Chceš postavit hodiny - OK, jenže tomu nutně musí předcházet několik věcí, které musíš zvládnout :

  1. VŽDY MÍT PO RUCE DATASHEET A ČÍST HO.
  2. Zvládnout rozblikat LEDku (ovládání výstupních pinů) - to bys měl za sebou.
  3. Zvládnout signalizovat LEDkou stisk tlačítka (načítání vstupních pinů) - pro jednoduchost zapojení se tlačítko připojuje proti GND a v procesoru nastavíš pin jako vstupní a zapneš u něj pull-up.
  4. Zvládnout přepínat LEDku stiskem tlačítka (zpracování vstupních pinů - náběžná/sestupná hrana).
  5. Zapomenout na delaye, spustit čítač a LEDkou začít blikat na základě čítače - delay použvat v řádu maximálně 10ms a i to je pro mikrokontroler věčnost - za 10ms zvládne při 1 MHz až 10000 instrukcí. Navíc, čím delší bude delay, tím nepřesnější bude, protože překladač prostě počítá počet tiků hodin, jenže k tomu musíš připočítat, kolik tiků Ti zaberou obsluhy přerušení a kolikrát se které přerušení vyvolá, což jsou naprosto nevypočitatelné hodnoty.
  6. Když už budeš mít spuštěný čítač, přesunout blikání LEDkou na přerušení od čítače.

Až budeš mít zvládnuté výše zmíněné body, máš základ k tomu, abys mohl efektivně začít programovat.

Děkuji všem za rady.

Balů: děkuju za seznam věcí, které se postupně pokusím naučit.