arduino: delaymicroseconds () (Suomi)

Kuinka delayMicroseconds () -toiminto toimii. Sen perusteella, mitä ymmärsin, ajastimen 0 esisalkkaaja on asetettu arvoon 64. 16 MHz: n kello antaa 4,0 uS / laskenta. Olen hieman hämmentynyt matematiikassa päästäksesi 1uS-väliin?

Kommentit

  • dokumentaatiossa sanotaan " Tämä toiminto toimii erittäin tarkasti välillä 3 mikrosekuntia. Emme voi taata, että delayMicroseconds toimii tarkasti pienemmillä viiveillä. " micros() -asiakirjoissa sanotaan " 16 MHz: n Arduino-levyillä (esim. Duemilanove ja Nano) tämän toiminnon resoluutio on neljä mikrosekuntia (ts. palautettu arvo on aina neljän kerroin). "
  • Katso myös electronics.stackexchange.com/q/22584/2191

vastaus

Tämän toiminnon lähdekoodi on melko hyvin dokumentoitu ja löytyy hakemistosta / usr / share / arduino / hardware /arduino/cores/arduino/wiring.c Linux-järjestelmissä. Windows-järjestelmillä on samanlainen polku kuin wiring.c-tiedostolla. Pyri löytämään tiedosto ja selaamaan sitä. Nyt vain keskitytään tähän yksittäiseen toimintoon, se ei luota mihinkään muuhun toimintaan.

Tarkastamalla koodin huomaat, että kyse ei ole ajastimista, vaan opetusjaksoista. Koodi luottaa vahvasti siihen, että kääntäjän optimointi on täsmälleen sama sinulle kuin kirjaston kehittäjälle. Se tekijän oletus! Kunkin käskyn ”palaneen” suorittimen jaksojen lukumäärä on hyvin dokumentoitu Atmel AVR -käskyjoukkoasiakirjassa .

Ensin viive-arvo on tarkistettu, että se on yhtä suuri kuin 1, tällöin palataan vain rutiinista, joka on jo käytetty mikrosekunnin prosessorin ajan.

Sitten viivearvo kerrotaan neljällä (<<=2). __asm__ -silmukka kääntyy 4 suorittimen jaksosilmukaksi. 4 sykliä × 4 = 16 sykliä. 16 MHz / (4 × 4) = 1 MHz, joka vie yhden jakson ajan, tarkkuuden, jonka olemme saavuttaneet.

Viimeiset -2 mikrosekuntia (ennen kuin silmukka käynnistetään) on jälleen korjaus kääntäjässä käyttöön yleiskustannukset. __asm__ -koodin soittaminen C: ltä vaatii joitain lisäohjeita suorittimen rekisterien tallentamiseksi.

Normaalille Arduino @ 16MHz: lle vain seuraava koodi kootaan:

/* 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: Käännetty koodi on melko tarkka, mutta ole tietoinen seuraavista: Arduinossa on määritetty ajastettuja keskeytyksiä, joista suurin osa ei ole tietoinen. Kun keskeytys vastaanotetaan delayMicroseconds(): n suorituksen aikana, delayMicroseconds() -kohdan ajoitus on väärä. Voit tietysti pysäyttää keskeytykset ennen delayMicroseconds() -soiton soittamista ja ottaa ne käyttöön jälkikäteen, mutta tämä vaikuttaa jälleen ajoituksen tarkkuuteen kootun koodin keston mukaan sallimisen / poistamisen käytöstä.

Kommentit

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *