J'ai réalisé un petit programme, non bloquant, qui génère une impulsion :
Une fonction "pulse" met au niveau haut une sortie et configure les paramètres adéquats du Timer2,
Quand le timer2 arrive au débordement, il génère une ISR qui remet au niveau bas la sortie.
Ça fonctionne très bien, mais j'y trouve un petit inconvénient. Tant que l'impulsion "pulse" n'est pas relancée, le timer2 continu à tourner et à chaque débordement génère une ISR. Celle-ci remet au niveau bas la sortie qui l'était déjà suite à la première ISR, donc, vu de l'extérieur, ça ne se voit pas. Par contre, chaque ISR me mange quelques micro-secondes de temps de calcul. C'est négligeable, mais pour le principe, ça me gêne.
Pour supprimer ces ISR consécutives, il m'est venu l'idée de remettre à zéro le bit TOIE2 de masquage des interruptions du registre TIMSK2 à la fin de l'ISR et de la remettre à un dans la fonction "pulse" afin de les démasquer à nouveau.
Voir lignes commentées dans le programme ci-joint.
Mais cela ne fonctionne pas et selon l'endroit où je place ces instructions dans la fonction "pulse" et dans l'ISR, soit la sortie reste constamment au niveau haut soit j'ai une impulsion de quelques micro-secondes ; ce temps étant totalement indépendant du temps que je programme.
Voilà. Si vous avez une idée de ce qui pourrait solutionner (pas saucissonner ) cela
Bon, il suffit que je pose un problème pour qu'en général, j'en trouve la solution :
J'avais oublié de réinitialiser le bit d'overFlow (TOV2 dans le registre TIFR2) dans ma fonction "pulse". Ça donne ca maintenant :
void pulse() { // Met la sortie à l'état haut
TIFR2 = 0b00000001; // TOV2 -> RaZ du bit d'overFlow
switch (port) {
case 2:
PORTB |= bit;
break;
case 4:
PORTD |= bit;
break;
}
TCNT2 = n; // Rechargement du timer à n
TIMSK2 = 0b00000001; // TOIE2 : masque ré-autorisant les interruptions du Timer 2
};
Quand on en a plus besoin, il suffit d'arrêter le timer dans l'ISR en faisant CS2 = 0 dans TCCR2B.
Concrètement, ajouter dans l'ISR :
TCCR2B = 0;
Pour lancer l'impulsion, il faut redémarrer le timer.
Avec les réglages utilisés prédiviseur de 8, il suffit d'ajouter, dans pulse(), après le chargement du compteur :
TCCR2B = 0b00000010; /* Démarre le timer avec un prescaler de 8 */
Avec cela, les réglages de TCCR2B dans l'init ne servent plus à rien.
S'il s'agit de faire du one-shoot, en gros, un monostable, il suffit, une fois dans l'ISR de désactiver l'int TOVF2 via le registre TIMSK2 (TIMSK2 &= 0xFE; ). Le timer continuera à tourner, mais l'int ne sera plus déclenchée. Pour relancer le monostable, il suffit de faire TCNT2=0; TIMSK2 |= 1;
J'utilise ça très souvent, car ça permet de gérer trois ISR de tempo sur le même timer, donc optimisation des ressources...
@ MicroQuettas : Cette solution a l'air simple, je l'essaierai.
@Super_Cinci : Ce que vous me proposez est ce que j'avais essayé de faire et qui ne fonctionnait pas ... mai qui fonctionne si je rajoute l'instruction "TIFR2 = 0b00000001; // TOV2 -> RaZ du bit d'overFlow" dans ma fonction "pulse()"
@ pepe : pour l'instant, je ne maitrise pas bien, voire pas du tout les modes PWM. Il faut que je les regarde de plus près avant que de pouvoir comprendre votre solution.
En tous cas, merci à chacun pour les idées que vous m'avez apportées.
@ pepe : J'ai essayé ce que vous me proposez à la réponse #2 (que j'ai cru comprendre après lecture des spécificités du Timer1), mais j'obtiens un calme plat aux sorties 9 ou 10 de mon Pro- Mini.
Merci pepe. Le fait que ma solution ne marchait pas était que je n'avais pas choisi le bon Mode "Compare Out Mode". J'avais pris le mode "toogle" (0:1) au lieu du mode "set/clear" (1:1).
Un petit inconvénient, s'il en est, est que ce mode impose d'utiliser la pin 9.
pepe:
Cela a plus de chance de le devenir dans le monde Arduino, notamment quand on utilise des shields, car la démarche de conception y est menée à l'envers : au lieu de réaliser un circuit et un logiciel en fonction des capacités et des limitations du micro-contrôleur, on impose a priori une configuration, quitte à ne plus pouvoir tirer partie des possibilités initialement offertes et à devoir éventuellement acheter le modèle au-dessus pour réaliser ce qui était prévu.
Entièrement d'accord.
D'un autre coté la vente de shields et de cartes plus performantes c'est alimentaire.
Le projet Arduino n'est pas un projet bizounours.