arduino: delaymicroseconds () (Magyar)

Hogyan működik a delayMicroseconds () függvény. Amit megértettem, az időzítő előmérője 64-re van állítva. Egy 16 MHz-es órajelenként 4,0 uS-ot ad. Kicsit zavart vagyok a matematikában, hogy 1uS intervallumra jussak?

Megjegyzések

  • A A dokumentáció szerint " Ez a funkció nagyon pontosan működik a 3 mikroszekundumos és feletti tartományban. Nem garantálhatjuk, hogy a delayMicroseconds pontosan kisebb késleltetési idők esetén fog működni. " A micros() dokumentumai " 16 MHz-es Arduino táblákon (pl. Duemilanove és Nano) ennek a funkciónak négy mikroszekundum a felbontása (vagyis a visszaadott érték mindig négyes többszöröse). "
  • Lásd még: electronics.stackexchange.com/q/22584/2191

Válasz

A függvény forráskódja meglehetősen jól dokumentált és megtalálható a / usr / share / arduino / hardware könyvtárban /arduino/cores/arduino/wiring.c Linux rendszereken. A Windows rendszereknek hasonló az elérési útja, mint a wiring.c fájlnak. Tegyen erőfeszítéseket a fájl megkeresésére és böngészésére. Most csak erre az egyetlen funkcióra összpontosítson, és nem támaszkodik más funkciókra.

A kód megvizsgálásával észreveheti, hogy nem az időzítőkről, hanem az utasítások ciklusairól szól. A kód nagyban támaszkodik arra, hogy a fordító optimalizálása pontosan ugyanaz legyen az Ön számára, mint a könyvtár fejlesztőjének. Ez a szerző feltételezése! Az egyes utasítások által “elégetett” CPU-ciklusok száma jól dokumentálva van az Atmel AVR utasításkészlet dokumentumban .

Először a késleltetés értéke ellenőrzik, hogy egyenlő-e 1-vel, ebben az esetben csak visszatérve a már elköltött rutinból a mikroprocesszor egy mikroszekunduma alatt.

Ezután a késleltetési értéket megszorozzuk négyzel (<<=2). A __asm__ -loop 4 CPU ciklusba fordít. 4 ciklus × 4 = 16 ciklus. 16MHz / (4 × 4) = 1MHz, ami 1 ciklus időt vesz igénybe, az a felbontás, amelyet követünk.

Az utolsó -2 mikroszekundum (mielőtt a hurok elindulna) ismét korrekció a fordítóban bevezetett rezsi. A __asm__ -kód C-től történő meghívásához további utasításokra van szükség a CPU-regiszterek mentéséhez.

Normál Arduino @ 16MHz esetén csak a következő kód kerül összeállításra:

/* 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: A lefordított kód meglehetősen pontos, de vegye figyelembe a következőket: Az Arduino-n vannak olyan időzített megszakítások, amelyek nincsenek tisztában. Amikor a delayMicroseconds() végrehajtása közben megszakítás érkezik, a delayMicroseconds() időzítése hibás lesz. Természetesen leállíthatja a megszakításokat, mielőtt felhívja a delayMicroseconds() t, és utána engedélyezheti őket, de ez ismét befolyásolja az időzítés pontosságát az engedélyezés / letiltás fordított kódjának időtartamával.

Megjegyzések

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük