J'ai fait beaucoup de recherches et je n'ai pas trouve le moyen de changer la fréquence des PWM a 10khz et 1khz... En utilisant la division par prescaler on n'obtient pas ces valeurs... J'utilise un arduino mega 2560.
Mon projet me demande de faire 9 signaux PWM : 6 a 10hkz et 3 a 1khz
Timer 0 --> pin 4 and 13 ( valeur par défaut :980 hz)
Timer 1 --> pin 11 and 12 (490 hz)
Timer 2 --> pin 9 and 10 (490 hz)
Timer 3 --> pin 2, 3 and 4 (490 hz)
Timer 4 --> pin 6, 7 and 8 (490 hz)
Timer 5 --> pin 44, 45, and 46 (490 hz)
Je pense utiliser les timers 3,4 et 5. J'ai trouvé des méthodes sur ce site mais ça parle d'interruptions alors je ne sais pas si c'est possible...
Ah d'accord ! c'est donc comme le lien que j'ai mis au dessus? On divise par un prescaler puis ensuite par un compteur?! ca serait parfait ^^ !
Je souhaite faire des signaux PWM. Mon sujet me donne une frequence pwm de base puis ensuite je dois pouvoir jouer avec le duty cycle... J'ai pris cette arduino ADK mega 2560 parce que j'ai besoin de 9 PWM et ce n'est pas un nombre très commun sur les cartes ! Et lui en propose 15
TCCR2A = bit (CS20) | bit (CS22) ; // prescaler of 128
OCR2A = 124; // count up to 125
This is an idea...
Il faut que tu étudies la datasheet du micro. Dedans tu trouveras des explications sur LES PWM.
J'ai bien écrit LES parce qu'il existe 3 types de PWM sur les AVR :
Fast PWM
Phase correct PWM
Phase and Frequency correct PWM.
Pour compliquer le tout chaque timer ne dispose pas de tous les types de PWM. En principe (je n'ai regardé que pour l'ATMega328p de la UNO) le seul type commun aux différents timers est la Fast PWM, c'est pour cela que les librairies Arduino ne gèrent que celle là.
La fréquence dépends des pré-diviseurs (prescaler) qui sont tous égaux à des puissance de 2.
A moins de changer le quartz de la carte ou d'utiliser une fréquence extérieure pour l'entrée du prescaler en lieu et place de la fréquence système du micro (16 MHz pour les cartes arduino) , je ne vois pas comment obtenir précisément du 1 kHz.
Pour cela seule la lecture de la datasheet peut donner le mode opératoire.
J'ai fait les calculs pour les différents PWM avec les formules de la datasheet... Par contre je ne suis pas sur de ma valeur TOP... Est-ce que je peux mettre ce que je veux ? ou est-elle limitée ? Dans mon tableau j'ai mis ce qui m'arrangeait....
Merci pour vos réponses en tout cas !
Il me semble que oui il y a des modes ou TOP peut être fixé par OCRAn mais, du moins avec un 328p, c'est très dépendant du timer. Je n'ai pas sous la main la datasheet du micro de la mega donc faut voir.
ATMega 328p
T0 = possible en mode 7 fast PWM
T1 = possible en mode 9 Phase et frequence correct et en mode 15 fast PWM
T2 = possible en mode en mode 5 Phase correct et en mode 7 Fast PWM
Si "SuperCinci" passe dans les parages peut-être pourra-t-il confirmer (ou infirmer) je sais qu'il s'est penché attentivement sur la question.
J'ai trouve ces formules dans la datasheet pour les Timer 1, 3. 4 et 5.... Je comptais utiliser les 3 derniers pour avoir mes neufs signaux! Je vais pouvoir faire des tests très prochainement.
Les timers 0 et 2 sont spécifiés PWM dans la datasheet c'est ce qui me fait un peu peur...
En effet si qqun qui a réfléchit au sujet peut m'aider en effet ça serait top ! Merci 68tjs
D'accord super le changement de frequence fonctionne !
Par contre quand j'utilise la fonction analogWrite(numPin, dutycycle), pour une même valeur de duty cycle je n'observe pas le même sur l'oscillo. En clair : je mets 127 ce qui représente 50% du duty cycle et pour un signal a 1khz j'ai bien 50 mais pour un signal a 10khz j'ai 60. Est-ce que cela peut venir de la résolution dont tu parles?
une fois parti dans le codage par registre, éviter de mélanger avec les fonction Arduino qui incluent souvent beaucoup de choses derrière, destinées à la base à simplifier l’expérience utilisateur
Je ne pense pas pouvoir faire ça car je dois faire une fonction qui passe en paramètre le duty cycle.... c'est l'utilisateur qui le choisira... Alors le code en dur dans les registres risque de poser pb.... non?
Non tu écris tes propres fonctions pour que l'utilisateur entre son choix.
Ce sera comme avec Arduino sauf que dans ce cas tu maîtrise tout et tu évitera les problèmes annoncés par @Batto :
"des fonction Arduino qui incluent souvent beaucoup de choses derrière, destinées à la base à simplifier l’expérience utilisateur".
J'ai repris le modèle de analogWrite dans la librairie... Et je me suis dit que je pouvais peut être utiliser cette méthode : Arduino PWM - Mega 2560 pins, registers and changing the frequency and range
J'essaie de faire un exemple pour le timer 3 que je souhaite faire fonctionner a 10khz. Je me demande tout de meme si c'est ici que je dois faire les changement ... Ma fonction analogWrite ne prendrait tjrs que le duty cycle en paramètre. Les timers utilises seraient paramétrer directement a la fréquence désirée
Voici le code de la fonction analogWrite original puis modifie pour le timer 3A :
// ORIGINAL
#if defined(TCCR3A) && defined(COM3A1)
case TIMER3A:
// connect pwm to pin on timer 3, channel A
sbi(TCCR3A, COM3A1);
OCR3A = val; // set pwm duty
break;
#endif
// MODIFIE
#if defined(TCCR3A) && defined(COM3A1)
case TIMER3A:
// connect pwm to pin on timer 3, channel A
sbi(TCCR3A, COM3A1);
// prescaler choice (8)
cbi(TCCR4B, CS40);
sbi(TCCR4B, CS41);
cbi(TCCR4B, CS42);
// mode Fast PWM (14)
sbi(TCCR4B, WGM43);
sbi(TCCR4B, WGM42);
sbi(TCCR4A, WGM41);
cbi(TCCR4A, WGM40);
// counter
ICR3 = 199;
OCR3A = val; // set pwm duty
break;
#endif
Nan mais ne modifie pas le core directement, il te suffit juste de mettre ta fonction dans ton code. A la fin si tu veux faire plus clair, tu peux écrire une librairie.