Go Down

Topic: PWM en utilisant les registres (Read 2419 times) previous topic - next topic

MrAlexis44600

Je me permet de créer un nouveau topic car le titre du topic sur lequel j'ai trouvé les infos qui m'intéressaient ne correspondait pas à mon problème.

Je réagis suite au post de Super_Cinci ici:


Les sorties PWM dépendantes d'un même timer auront forcément la même fréquence, mais les angles restent indépendants.
Après, tu peux configurer indépendamment chaque timer à une fréquence "de ton choix", selon la résolution que tu souhaites. Je déconseille l'utilisation de analogWrite(), car on obtient des résultats peu précis (et un fréquence PWM un peu dans les choux). Pour la config, et une PWM au top, je conseille de programmer les registres du timer concerné (Tn) en mode "Fast PWM" avec TOP=ICRn. De cette manière, on garde un contrôle total de la fréquence PWM en jouant entre les registres prescaler (CSn) et ICRn (voir datasheet pour les codes à utiliser), et en une seule instruction [OCRnX = valeur PWM;], on change l'angle (ou le alpha) de la sortie PWM. Mais c'est mon avis que je ne saurais imposer même si je suis convaincu que c'est la seule façon de savoir exactement ce que l'on fait...


Je suis en train de plancher sur 2 sorties PWM à 20kHz (donc on oublie l'instruction "analogWrite"), et j'ai défini qu'en "Fast PWM", sur le timer1, avec un clkI/O de 16MHz (un arduino 2009 ou nano), je devais, au choix, avoir un prescaler de 1 avec un TOP de 800 ou un prescaler de 8 avec un TOP à 100, d'apres la formule

F_pwm = F_clk_IO  /  (N*(TOP+1))

Mais j'ai plusieurs questions: le fait de mettre un TOP pour affiner la fréquence de PWM utilise un des deux comparateurs du timer, donc je n'ai plus qu'une sortie PWM par timer, vrai ou faux? ce qui fait que pour avoir une 2e sortie PWM, je vais devoir utiliser le timer2 qui a une resolution de 8 bits => donc TOP limité à 256 => donc obligé de mettre le TOP à 100 avec un prescaler de 8.... donc résolution du PWM limité?

Déja: est-ce que mon raisonnement est bon?
Ensuite: Il y a t il plus simple/plus efficace pour créer 2 pwm de 20kHz (environ), sur un arduino nano ou 2009?

Super_Cinci

#1
Feb 21, 2012, 11:25 pm Last Edit: Feb 21, 2012, 11:45 pm by Super_Cinci Reason: 1
La PWM est assez compliquée, à chaque fois que je veux faire un truc avec les timers, je passe au moins deux heures à redéchiffrer le datasheet, peut-être aussi parce que je ne suis plus tout jeune et que ma RAM commence à fatiguer, et mon EEPROM est verrouillée en écriture...

Je vais donc tenter d'être clair... Comme moi, tu n'as pas tout compris du premier coup. Tu parles du mode CTC (RAZ timer quand TCNTn = OCnA). Choisis un mode PWM ou le TOP sera le registre ICRn, laissant OCnA tranquille. Ensuite, tu choisis un prescaler et un TOP te donnant ta fréquence avec ta formule (mode fast PWM). Si ça ne te convient pas, sache que le mode "Phase correct" divise par deux ta fréquence PWM calculée précédemment (voir figure 15.8, page 130). dans ton cas, tu fais un calcul pour une PWM à 40KHz :
Fpwm = 16MHz / 2 / prescaler / ICRn.
si tu prends le Timer 2, ICRn est limité à 255, mais avec le Timer 1, il peut aller jusqu'à 65535... C'est bon à savoir pour ta résolution. C'est d'ailleurs ICRn qui te donne le nombre de "pas" de ta PWM.

Pour 20Khz, j'arrive à : ICR2 = 50  et CS22:0 = 2 (prescaler). Et ICR1 = 400  et CS12:0 = 1. Tu aurais peut-être interrêt à travailler avec une FPWM plus basse, non? avec timer2, pour une résolution de ICR2=255 et un prescaler CS22:0=2, FPWM = 7.8KHz en phase correct : WGM=1, ou 15.625KHz en mode=3.

Tu as peut-être peur que ça s'entende dans une bobine? un petit condensateur entre la bobine et la masse atténuera la chose.

Autant pour moi ! le registre ICR2 n'existe que sur le mega2560... désolé... tu es donc contraint à utiliser le top. mais tu peux configurer T2 à 31.25KHz en phase correct (WGM2:0=1). T1 est plus souple, puisqu'on peut définir une résolution à 0xFFFF, 0x0FF, 0x1FF, 0x3FF ou ICR1 de ton choix.

Mais clair que c'est pas facile, la vraie PWM sur la UNO...

je vais voir ce que je peux te proposer pour tes deux PWM à 20KHZ, mais je pense qu'utiliser timer1 sera mieux (avec ICR1 = 400, en mode 10 : WGM13:0=10 (1.0.1.0) voir tableau 15.4 page 137.

MrAlexis44600

Bonjour, merci ça m'avance déjà pas mal.

Je dispose aussi d'une équivalent mega2560, mais je préférerais utiliser un 328 (nano)... on dit toujours qu'on utilise qu'une petite portion de ses fonctionnalités.

En effet, c'est de mode CTC dont je voulais parler, avec un TOP pour affiner la fréquence. (en plus je n'étais pas sur la bonne datasheet donc ça n'aidait pas) Je vais faire un test en Phase correcte à 10 bits à 15.6kHz, si ça me convient ce sera beaucoup plus simple!
Mon PWM attaque un pont en H type L298, est-ce que mettre un condo aux bornes du moteur atténue le bruit? Au plus près c'est le mieux c'est ça? Je voulais la fréquence la plus haute pour ne pas avoir de vibration et/ou de pointes de courants... Je vais voir si je peux rajouter une inductance de lissage sur mon moteur en plus.

Le souci c'est que je n'ai aucun moyen de mesure, donc mes seuls critères sont le bruit du moteur et la température du pont (un peu léger je sais...).

Juste une précision: si dans les mode choisi le TOP n'est pas un OCRnX, ça veut dire que je peux utiliser deux sorties PWM sur le timer1? Sinon ça veut dire que "j'en sacrifie une" (la comparasion sert à RAZ au TOP) pour affiner la fréquence de l'autre? Sinon je peux créer des routines d'interruption avec les OCRnX qui changent les niveaux logiques d'une sortie pour faire un PWM...

Enfin en tout cas il me reste pas mal de choses à comprendre, mais c'est très intéressant, je remplis mon EEPROM a chaque visite sur ce forum ;)

zoroastre

Yep!

Je vais commencé à regarder cet aspect pwm aussi. Je m'entraine actuellement avec un 368 et je vais piloter 3 pwm. J'essaierais ensuite de reproduire la programmation sur un tiny2313.

J'ai un peu galéré à produire un code pour piloter un registre à décalage (perdu 1 journée pour cause de mauvais cablage  :smiley-eek-blue: )

On pourrait s'entraider afin d'arriver à nos fins ;)

Pour revenir un petit peu sur la 2313, j'avais lors de mes recherches entrevue un code utilisant les 4 pwm du core simultanément. Bon !!! c'est encore des hieroglyphes pour moi...mais je commence à comprendre les contours.

@+

Zoroastre.
Gné! ;)

Super_Cinci

Quote
Juste une précision: si dans les mode choisi le TOP n'est pas un OCRnX, ça veut dire que je peux utiliser deux sorties PWM sur le timer1? Sinon ça veut dire que "j'en sacrifie une" (la comparasion sert à RAZ au TOP) pour affiner la fréquence de l'autre? Sinon je peux créer des routines d'interruption avec les OCRnX qui changent les niveaux logiques d'une sortie pour faire un PWM...
Non, pas du tout. Il faut que tu choisisses un MAX=autre chose que OCRnA. le timer1 en 10 bits te permettra de jouer avec OC1A et OC1B. pareil pour le timer2, éviter le mode CTC (qui te remets à 0 le timer sur OCRnA), prends un PWM phase correct, c'est le mieux que j'ai trouvé.

il y a quelques jours, j'ai codé un gradateur (dimmer) avec une mega2560, en utilisant les 3 comparateurs des timers 1, 3, 4 et 5, ça marche impec et l'UC est complètement déchargée de toute fonction autre que modifier les registres ACRnX pour changer les valeurs du dimmer (donc de l'éclairage). c'est super puissant quand on maitrise les timers! Mais faut les comprendre, et l'oscillo est ton meilleur et seul ami dans cette histoire, car j'ai mis du temps à découvrir certaines subtilités...

je vois demain si j'ai un peu de temps pour te faire une double PWM à 15.6KHz.

Go Up