arduino: delaymicroseconds () (Čeština)

Jak funguje funkce delayMicroseconds (). Z toho, co jsem pochopil, je předvolba časovače0 nastavena na 64. Pro hodiny 16MHz dává 4,0uS na počet. Jsem z matematiky trochu zmatený, abych se dostal k intervalu 1uS?

Komentáře

  • dokumentace říká " Tato funkce funguje velmi přesně od 3 mikrosekund a více. Nemůžeme zaručit, že delayMicroseconds bude fungovat přesně pro menší doby zpoždění. " Dokumenty pro micros() říká " Na 16 MHz deskách Arduino (např. Duemilanove a Nano) má tato funkce rozlišení čtyř mikrosekund (tj. vrácená hodnota je vždy násobkem čtyř). "
  • Viz také electronics.stackexchange.com/q/22584/2191

Odpověď

Zdrojový kód této funkce je poměrně dobře zdokumentován a lze jej najít v adresáři / usr / share / arduino / hardware /arduino/cores/arduino/wiring.c v systémech Linux. Systémy Windows budou mít podobnou cestu k souboru wiring.c. Snažte se najít soubor a procházet jej. Zatím se zaměřte pouze na tuto jedinou funkci, nespoléhá se na žádné jiné funkce.

Kontrolou kódu si všimnete, že nejde o časovače, ale o cykly instrukcí. Kód se silně spoléhá na to, že optimalizace kompilátoru je pro vás přesně stejná jako pro vývojáře knihovny. To je předpoklad autora! Počet cyklů CPU „spálených“ každou instrukcí je dobře dokumentován v dokumentu sady instrukcí Atmel AVR .

Nejprve je hodnota zpoždění zkontrolováno, že je rovno 1, v takovém případě se pouze vrací z rutiny již strávené po mikrosekundu času CPU.

Pak se hodnota zpoždění vynásobí čtyřmi (<<=2). __asm__ -loop se kompiluje do smyčky cyklu 4 CPU. 4 cykly × 4 = 16 cyklů. 16MHz / (4 × 4) = 1MHz, což vyžaduje dobu cyklu 1 us, rozlišení, které sledujeme.

Poslední -2 mikrosekundy (před spuštěním smyčky) jsou opět korekcí kompilátoru představil režii. Volání __asm__ -code z C vyžaduje nějaké další pokyny pro uložení registrů CPU.

U běžného Arduino @ 16MHz bude sestaven pouze následující kód:

/* Delay for the given number of microseconds. Assumes a 8 or 16 MHz clock. */ void delayMicroseconds(unsigned int us) { // calling avrlib"s delay_us() function with low values (e.g. 1 or // 2 microseconds) gives delays longer than desired. //delay_us(us); // for the 16 MHz clock on most Arduino boards // for a one-microsecond delay, simply return. the overhead // of the function call yields a delay of approximately 1 1/8 us. if (--us == 0) return; // the following loop takes a quarter of a microsecond (4 cycles) // per iteration, so execute it four times for each microsecond of // delay requested. us <<= 2; // account for the time taken in the preceeding commands. us -= 2; // busy wait __asm__ __volatile__ ( "1: sbiw %0,1" "\n\t" // 2 cycles "brne 1b" : "=w" (us) : "0" (us) // 2 cycles ); } 

BTW: Zkompilovaný kód je docela přesný, mějte však na paměti následující: Na Arduinu jsou nakonfigurována časovaná přerušení, o kterých většina neví. Pokud během provádění delayMicroseconds() dojde k přerušení, načasování delayMicroseconds() bude chybné. Přerušení můžete samozřejmě zastavit před voláním delayMicroseconds() a poté je povolit, ale to opět ovlivní přesnost časování podle doby trvání zkompilovaného kódu pro povolení / zakázání.

Komentáře

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *