arduino: delaymicroseconds () (Français)

Comment fonctionne la fonction delayMicroseconds (). Daprès ce que jai compris, le prescaler de timer0 est réglé sur 64. Pour une horloge à 16 MHz, il donne 4,0uS par compte. Je suis un peu confus sur le calcul pour arriver à lintervalle 1uS?

Commentaires

  • Le la documentation dit " Cette fonction fonctionne très précisément dans la plage de 3 microsecondes et plus. Nous ne pouvons pas garantir que delayMicroseconds fonctionnera précisément pour des temps de retard plus petits. " La documentation pour micros() dit " Sur les cartes Arduino 16 MHz (par exemple Duemilanove et Nano), cette fonction a une résolution de quatre microsecondes (cest-à-dire que la valeur renvoyée est toujours un multiple de quatre). "
  • Voir aussi electronics.stackexchange.com/q/22584/2191

Réponse

Le code source de cette fonction est assez bien documenté et peut être trouvé dans / usr / share / arduino / hardware /arduino/cores/arduino/wiring.c sur les systèmes Linux. Les systèmes Windows auront un chemin similaire vers le fichier de câblage.c. Faites leffort de trouver le fichier et de le parcourir. Pour linstant, concentrez-vous sur cette seule fonction, elle ne repose sur aucune autre fonction.

En inspectant le code, vous remarquerez quil ne sagit pas de minuteries, mais de cycles dinstructions. Le code repose fortement sur loptimisation du compilateur qui est exactement la même pour vous que pour le développeur de la bibliothèque. Cest une hypothèse de lauteur! Le nombre de cycles CPU « brûlés » par chaque instruction est bien documenté dans le document sur le jeu dinstructions Atmel AVR .

Premièrement, la valeur du délai est vérifié pour être égal à 1, dans ce cas juste revenir de la routine déjà dépensée plus dune microseconde de temps CPU.

Ensuite, la valeur du retard est multipliée par quatre (<<=2). La boucle __asm__ se compile en une boucle à 4 cycles CPU. 4 cycles × 4 = 16 cycles. 16MHz / (4 × 4) = 1MHz, ce qui prend 1 temps de cycle us, la résolution que nous recherchons.

Les -2 dernières microsecondes (avant le lancement de la boucle) sont à nouveau une correction sur le compilateur introduit les frais généraux. Lappel de __asm__ -code à partir de C nécessite des instructions supplémentaires pour enregistrer les registres du processeur.

Pour un Arduino normal à 16 MHz, seul le code suivant sera compilé:

/* 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: Le code compilé est assez précis, mais soyez conscient de ce qui suit: Sur Arduino, il y a des interruptions chronométrées configurées que la plupart ignorent. Lorsquune interruption est reçue pendant lexécution de delayMicroseconds(), la synchronisation de delayMicroseconds() sera erronée. Vous pouvez bien sûr arrêter les interruptions avant dappeler delayMicroseconds() et les activer par la suite, mais cela a encore une fois un impact sur la précision de la synchronisation de la durée du code compilé pour lactivation / la désactivation.

Commentaires

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *