Go Down

Topic: Fonction millis() ,boucle "for" (Read 1 time) previous topic - next topic

kamill

#30
Apr 15, 2019, 10:04 am Last Edit: Apr 15, 2019, 10:10 am by kamill
Bonjour,

digitalWrite() ce n'est pas une instruction, mais des dizaines d'instructions.

dbrion06

https://stackoverflow.com/questions/27496873/explanation-of-digitalwrite-in-arduino-toggling-led-of-digital-pin confirme le post de Kamill:
l'appel à digitalWrite nécessite de calculer le port (groupe de 8 pattes), le numéro dans le port, et si c'est un timer (ceci fait déjà 3 appels de fonctions ...chaque appel nécessite de stocker/destocker des registres).
Il vérifie ensuite que le port est valide, que le numéro dans le port est valide, et que la patte n'est pas impliquée dans un timer ("montre patte blanche"). Alors, il invalide les interruptions, fait effectivement la mise à jour de la patte, revalide les interruptions... Toutes ces précautions sont chronophages...

lesept

Il me semble que J-M-L (ou quelqu'un d'autre ?) avait posté sur ce forum une alternative à digitalWrite un peu plus rapide
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

hbachetti

Si tu veux aller plus vite :

Code: [Select]

  #define PIN     2

  // pin = D0 à D7
  DDRC |= PIN;      // pinMode(PD_SCK, OUTPUT)
  PORTC |= PIN;     // digitalWrite(PD_SCK, HIGH)
  PORTC &= ~PIN;  // digitalWrite(PD_SCK, LOW)
  // pin = D8 à D13
  DDRD |= PIN;      // pinMode(PD_SCK, OUTPUT)
  PORTD |= PIN;     // digitalWrite(PD_SCK, HIGH)
  PORTD &= ~PIN;  // digitalWrite(PD_SCK, LOW)
  // pin = A0 à A5
  DDRC |= PIN;      // pinMode(PD_SCK, OUTPUT)
  PORTC |= PIN;     // digitalWrite(PD_SCK, HIGH)
  PORTC &= ~PIN;  // digitalWrite(PD_SCK, LOW)


Mais dans ce cas, tu n'est plus indépendant de la plateforme.

Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

kamill

#34
Apr 15, 2019, 10:44 am Last Edit: Apr 15, 2019, 10:47 am by kamill
Si tu veux aller encore plus vite
Code: [Select]
PIND=0x04;  // toggle pin 2
63ns pour inverser une sortie !

lesept

Tu veux dire, pour mettre la sortie 2 à HIGH (et les autres de 0 à 7 à LOW):
Code: [Select]
PORTD = 0x04;ou
Code: [Select]
PORTD = B00000100;
PIND est en lecture seule, non ?

La méthode d'hbachetti permet de ne pas toucher aux autres IO:
Code: [Select]
PORTD |= 2;ou
Code: [Select]
PORTD |= B00000100;
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

kamill

#36
Apr 15, 2019, 11:44 am Last Edit: Apr 15, 2019, 11:48 am by kamill
PIND est en lecture seule, non ?
Oui, mais c'est une particularité des processeurs AVR: quand tu écris dans PINX ça inverse la (les) sortie(s) correspondante(s).
Il faut bien sur qu'elles soient déclarées en sortie.

Cette méthode aussi ne touche pas aux autres bits.

hbachetti

Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

ATOS_VQ

Merci pour vos réponses
En fait moi qui tente de voir autre chose que l'assembleur ,je vais être contraint d'y retourner avec Atmega, je pensais innocemment que ce langage plus évolué était plus rapide
Merci encore

kamill

Pourquoi veux tu retourner à l'assembleur? Quel est ton application?

un programme écrit à la main en assembleur sera plus optimisé qu'un programme en langage C/C++ (bien que les compilateurs actuels soient très performants coté génération de code et optimisation).
Par contre c'est au détriment du temps de développement qui est beaucoup plus long en assembleur (écriture et debug), et je ne parle pas de la maintenabilité qui est bien plus facile en C/C++.

dbrion06

Quote
un programme écrit à la main en assembleur sera plus optimisé qu'un programme en langage C/C++
... a condition que ce soit de la main d'un expert en assembleur (prenez un débutant; donnez lui un bon livre d'assembleur et 3 mois de formation et quelque temps pour un sujet simple : je parierais que le code assembleur généré par ses mains sera plus lent et plus volumineux que le programme équivalent, écrit en C et compilé avec un optimiseur moderne)

fdufnews

si les IO sont fixés à la compilation, il y a la librairie digitalWriteFast qui est beaucoup plus rapide.

hbachetti

HEU ...

Code: [Select]

  PORTC |= 0x04;
  PORTC &= ~0x04;
  PIND = 0x04;


Ceci est du C, et non pas de l'assembleur.
Linux is like a wigwam: no Windows, no Gates, and an Apache inside ...

ATOS_VQ

Super toutes vos contributions.....

Pourquoi retourner à l'assembleur , en fait je ne le quitte pas mais j'aurais souhaité pouvoir faire des programmes plus facilement , je reconnais que c'est le cas bien sur, quand on maitrise.! C'est pas mon cas

Toute fonction plus évoluée est comme une recette de cuisine dont on ne connait pas tous les secrets
sans s'être cassé les dents, bien plus difficile à appréhender qu'une instruction assembleur

En assembleur on maitrise tout sans exception, dans les langages plus évolues il faut toujours se référer à une doc pas toujours facile ,pour connaitre les méandres des fonctions ,objet ou autres, cf la recherche des objets et de leur utilisation .En C# par exemple je m'inspire d'exemples dans différents documents sans vraiment maitriser
En assembleur je n'ai pas de doute sur l'efficacité du code ,par contre pas sur que la taille du programme soit plus court mais à notre époque on s'en fou !
J'ai fait un drone programmé en assembleur sur dsPic4013 (16bit) en faisant tous les calculs en 32 bit, il m'a fallu redécouvrir la roue , faire des programmes de multiplication d'addition ,division racine trigo, tout ca avec des entiers 16 bit alors qu'il m'a fallu représenter tout type de nbr ,petit, grand ,décimaux...un enfer mais je sais exactement à 33ns prés tout ce qui se passe....
Par contre pour visualiser le fonctionnement de 'l'IMU c'est avec C# sur ordi mais je ne comprends pas tout ce que j'ai fait !!!
Pour répondre à hbachetti qui dit que le code qui n'est pas de l'assembleur mais du C, je ne me prononce pas trop mais sur les PIC c'est ce genre d'instruction.....
Naïvement je pensais par exemple qu'un digitalwrite aurait fait après compilation ce que j'aurais pu faire en assembleur....mais c'est comme si le langage était interprété , l'instruction digitalwrite est transformé en une succession d'instructions, même si cette instruction a déjà été utilisé ....(?)

merci encore
 

lesept

Ici, le code de digitalWrite décortiqué (et d'autres aussi intéressantes si vous voulez)
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

Go Up