Développement d'un convertisseur abaisseur sur STM32F334: principe de fonctionnement, calculs, prototypage

Dans mes deux derniers articles, j'ai parlé du module d'alimentation et de la carte de commande basés sur le microcontrôleur STM32F334R8T6, qui sont conçus spécifiquement pour la mise en œuvre de systèmes de commande pour les convertisseurs de puissance et les entraînements électriques. Un exemple de convertisseur DC / AC a également été considéré, qui était une démonstration et non une construction terminée. Il est maintenant temps de faire quelque chose de simple, mais d'utile et, surtout, de terminer.

La plupart des questions concernant le projet et l'électronique de puissance sont liées à des topologies spécifiques: quelqu'un souhaite apprendre l'algorithme de contrôle PFC, quelqu'un veut apprendre à construire un demi-pont LLC, mais la topologie la plus populaire est sans aucun doute buck. Après tout, le convertisseur buck (également appelé convertisseur buck) est le principal pour les projets les plus intéressants: c'est le pilote pour les lampes LED, la base du contrôleur MPPT pour les panneaux solaires, les chargeurs et bien plus encore.

Le réseau contient de nombreuses informations sur buck, y compris des fiches techniques, mais elles sont dispersées et je n'ai personnellement rencontré aucun document décrivant en détail le processus de création d'un convertisseur buck avec contrôle numérique. Il est temps de le réparer. Il n'y a pratiquement pas de mathématiques, l'explication est "sur les doigts", donc ce sera intéressant pour tous ceux qui sont en quelque sorte connectés à l'électronique.



Présentation


Vous devez d'abord comprendre ce que nous voulons obtenir à la fin et quelle introduction nous avons. La topologie buck est abaissée, c'est-à-dire qu'elle vous permet de construire un convertisseur de tension abaisseur. Comme vous le verrez plus tard, la tension à la sortie du convertisseur abaisseur dépend presque linéairement de la tension à l'entrée, vous devez donc ajouter un retour. Aujourd'hui, je vais parler du retour de tension simple, qui est le plus intuitif et vous permettra de comprendre le principe de fonctionnement, alors que ce retour vous suffit pour réaliser la plupart des tâches.

À la fin de l'article, nous obtiendrons une source de tension stabilisée de travail selon la topologie «buck synchrone», fonctionnant à une fréquence assez élevée avec contrôle numérique, implémentée sur le STM32F334R8T6 en utilisant PWM haute résolution (HRPWM). La plage de tension d'entrée est de 15 ... 60 V, la tension de sortie est de 12 V et le courant de sortie maximal est de 2 A.

Chapitre 1. Le principe de la topologie buck


Je vais commencer à raconter à partir des bases et améliorer progressivement notre convertisseur, comme "Buck synchrone" est une version de la version améliorée avec une efficacité et une complexité de contrôle accrues. La version de base de la topologie que vous avez probablement utilisée est la suivante:



Cette topologie est utilisée dans les convertisseurs de tension à faible puissance, par exemple, pour alimenter des circuits numériques et d'autres appareils à faible puissance. L'abaissement du courant continu / continu que vous utilisez dans vos appareils est probablement implémenté sur des microcircuits selon cette topologie. Un exemple d'une telle puce est le LMR16006 .

Le principe de fonctionnement de ce circuit est très simple, un signal PWM est fourni au transistor VT1, le travail lui-même est divisé en 2 étages, qui alternent l'un après l'autre:

  • L'étape de stockage d'énergie dans le circuit LC. À ce stade, le transistor VT1 est ouvert et le courant passe à travers le transistor vers la charge, emmagasinant simultanément de l'énergie dans l'inductance et la capacité de sortie:

  • Étape de décharge. A ce stade, le transistor VT1 se ferme puis le plaisir commence. Accélérateur - c'est une telle chose qui accumule de l'énergie si un potentiel lui est appliqué (VT1 ouvert) et la donne si le potentiel disparaît (VT1 est fermé). En même temps, il cherche non seulement à donner de l'énergie, mais à enregistrer la valeur du courant et sa direction, donc, pour utiliser cette propriété, vous devez ajouter la diode VD1 pour fermer le circuit, car le courant ne circule que dans un circuit fermé:


Lorsque j'ai pris connaissance de cette topologie dans la classe 6-7, je n'ai pas tout de suite compris pourquoi la diode ne conduisait pas de courant au 1er étage, maintenant cela semble banal, mais je pense que cela vaut la peine d'être mentionné. Lorsque VT1 est ouvert, le potentiel + VIN, par exemple + 20V, est appliqué à la cathode de la diode VD1 et le potentiel de terre, respectivement, à l'anode de la diode. Pour que le courant passe à travers la diode, il faut que ce soit exactement le contraire: le potentiel à l'anode doit être supérieur au potentiel à la cathode, donc, en buck-e, au stade du stockage d'énergie, la diode est «fermée». Au stade de la décharge, la diode ferme déjà le circuit, le potentiel + VIN n'agit pas sur sa cathode et ne la "verrouille" pas. J'espère que je l'ai clairement expliqué.

Ensuite, vous devriez avoir une question: "Et quelle tension sera à la sortie, si nous appliquions 20V à l'entrée?". Comme toujours, tout est simple:



Comme le montre la formule, la tension de sortie dépend linéairement du facteur de marche du signal PWM que nous fournissons au transistor VT1. Si quelqu'un ne connaît pas ou a oublié le «facteur d'utilisation», c'est le rapport entre le temps pendant lequel le transistor est à l'état ouvert et la durée de la période. Ce coefficient peut prendre une valeur de 0 à 1 ou de 0 à 100%. De plus, nous fonctionnerons avec cette figure particulière lors du contrôle du convertisseur, mais pour comprendre l'essence, substituons cette relation dans la formule:



La fréquence de fonctionnement du convertisseur abaisseur est constante et est sélectionnée lors de la conception, elle ne change pas pendant le fonctionnement, et donc la période (T) est constante. Il s'avère que la tension de sortie dépend directement de deux grandeurs physiques:

  • à partir du moment où nous ouvrons le transistor supérieur (VT1) - plus il est ouvert, plus l'énergie a le temps de s'accumuler dans le filtre LC et, en conséquence, la tension de sortie est plus élevée;
  • à partir de la tension d'entrée, par exemple, si nous fixons le remplissage de 50% et changeons Vin de 20 à 40V, la tension de sortie passera également de 10 à 20V.

Je pense que l'image générale et le principe du travail ont commencé à se dessiner en vous, fixons-le maintenant et regardons les vrais oscillogrammes et vérifions ce rapport dans la pratique. J'ai assemblé une disposition buck qui est chargée avec une LED de 10 W. J'ai utilisé 3 canaux de l'oscilloscope, qui sont inclus dans les points suivants:



Expérience n ° 1 - Tension d'entrée (Vin) constante 20V, le rapport cyclique change

  • Vin = 20V, D = 25%, Vout = D * Vin = 0,25 * 20V = 5V

  • Vin = 20V, D = 50%, Vout = D * Vin = 0,5 * 20V = 10V


Comme vous pouvez le voir sur les formes d'onde, la relation entre la tension de sortie et le rapport cyclique est correcte. Bien sûr, c'était une expérience «idéalisée», en réalité, la tension d'entrée n'est pas stable et flotte dans une plage assez large. Voyons maintenant quelle sera la dépendance à la tension d'entrée à un remplissage fixe.

Expérience n ° 2 - La tension d'entrée (Vin) change, le rapport cyclique est constant et égal à 50%

  • Vin = 15 V, D = 50%, Vout = D * Vin = 0,5 * 15 V = 7,5 V

  • Vin = 20V, D = 50%, Vout = D * Vin = 0,5 * 20V = 10V

  • Vin = 30V, D = 50%, Vout = D * Vin = 0,5 * 30V = 15V


Maintenant, nous avons vu dans la pratique que la tension de sortie dépend également linéairement de la tension d'entrée à un rapport cyclique fixe. Comprenez-vous déjà comment cela stabilisera la sortie? Le principe de stabilisation est simple comme la formule elle-même - Vout est 12V et constant, nous pouvons changer le rapport cyclique à l'aide d'un microcontrôleur, donc si Vin augmente, la tension de sortie augmente également et à ce moment nous diminuons le facteur d'utilisation jusqu'à ce qu'il redevienne 12V. En conséquence, lorsque Vin diminue, nous commençons à augmenter le rapport cyclique jusqu'à ce que la tension Vout redevienne 12V.

Sur quoi d'autre voudrais-je attirer l'attention dans la partie théorique ... Ah, oui! Vous vous demandez sûrement comment un PWM avec une amplitude de 20V après un transistor s'est finalement transformé en une tension constante avec des ondulations rares? En effet, si nous mettons la sonde rouge de l'oscilloscope à la source du transistor VT1, la sonde verte après le filtre LC, nous verrons l'image suivante:



Vous pouvez voir comment le filtre LC «lubrifie» la tension alternative en tension constante, mais le fait est que l'énergie stockée dans l'inductance et la capacité ne peut pas être consommée instantanément, donc la tension ne peut pas changer instantanément. Nous obtenons qu'au moment où le PWM devant l'inductance devient 0V, la tension de sortie est fournie par l'énergie stockée dans le filtre, qui n'absorbe pas immédiatement et est suffisante pour maintenir la tension au moment où VT1 se ferme. Tout est sur les doigts bien sûr, si c'est intéressant d'approfondir, alors comme toujours je conseille B. Yu. Semenova "Power Electronics: du simple au complexe" , il y a tout un chapitre sur le buck (chopper).

La lutte pour l'efficacité


Comme je l'ai écrit un peu plus tôt, c'était la version de base de la topologie. Son principal inconvénient est de fortes pertes sur la diode de verrouillage. Quel est le courant dans les systèmes simples fonctionnant sur MK et CPLD? Habituellement dans 1A, parfois 2A, s'il y a une sorte d'affichage TFT. Dans ce cas, la perte même lors de l'utilisation d'une diode Schottky sera de 0,4 V * 2 A = 0,8 watts. En principe, il est tolérable de se dissiper autant sur le boîtier SMA / SMB sans problème, bien qu'avec une tension de 3,3 V et 2 A, une perte de 0,8 V soit toujours 12% d'efficacité!

Imaginez maintenant le cas où le courant que nous avons est de 20 A. Il peut s'agir d'un contrôleur MPPT, d'un grand système d'alimentation FPGA et bien plus encore. Dans ce cas, la perte sera de 0,4 V * 20 A = 8 W! Qu'est-ce que cela signifie? Par exemple, dans le cas du MPPT, vous aurez moins d'énergie stockée dans la batterie, dans le cas de l'alimentation FPGA, ce seront 8 watts de chaleur supplémentaires qui doivent être dissipés quelque part et dans les deux cas, c'est sans aucun doute une perte d'efficacité globale. Que peut-on faire? Et remplaçons la diode VD1 par un autre Mosfet à canal N et obtenons ce circuit:



Maintenant, le transistor VT2 agit comme une diode, c'est-à-dire qu'il conduit le courant lorsque VT1 est fermé. La diode, qui était dans la version de base, ne nécessitait pas de contrôle, maintenant nous sommes obligés de payer un canal de contrôle supplémentaire avec un signal PWM pour améliorer les performances.

Tout d'abord, calculons combien nous avons réduit les pertes. La résistance de canal d'un mosfet moderne est de plusieurs mégohms. À titre d'exemple, prenons un transistor de mon module d'alimentation, dont j'ai parlé dans les articles précédents - IPP083N10N5AKSA1 avec une résistance de canal de 8,3 mOhm. Nous obtenons des pertes statiques égales à 0,0083 * 20A * 20A = 3,32 watts. Bien sûr, il y aura des pertes dynamiques, qui avec un pilote correctement conçu ne dépasseront pas 20%, c'est-à-dire que les pertes totales pour nous seront de 4 watts. Nous obtenons que la transition d'un buck conventionnel à un buck synchrone peut réduire de moitié la perte de la diode.

Voyons maintenant la gestion la plus compliquée. Comme nous l'avons déjà compris, la diode de verrouillage conduisait du courant lorsque VT1 était fermé. Il en résulte que VT2 doit être fermé lorsque VT1 est ouvert et, par conséquent, VT2 est ouvert lorsque VT1 est fermé. Si c'est plus simple, les transistors fonctionnent alternativement: soit l'un est ouvert, soit l'autre, si les deux transistors s'ouvrent, il y aura un courant traversant, car ils sont interconnectés entre VIN et GND. Voyons ce que devrait être le signal, où le "canal jaune" est le transistor VT1 et le "canal vert" est le transistor VT2:



Comme vous pouvez le voir, si le «1» logique est défini dans le canal jaune (sur VT1), alors le «0» logique doit être défini dans le canal vert (sur VT2). Nous obtenons que VT1 pompe l'énergie dans le filtre LC, et VT2 ferme le circuit à l'étape de décharge.

Il y a un autre point que vous avez déjà entendu ou lu ci-dessus - à travers le courant . Le fait est qu'un transistor réel (pas un idéal) (mosfet) a une certaine capacité sur la grille, c'est-à-dire qu'en réalité, il ne passe pas instantanément de log.0 à log.1, et l'énergie dans le transistor ne se dissout pas instantanément, ce qui entraîne des transistors pendant une courte période au moment de la commutation, les deux peuvent être ouverts. Cela peut entraîner, au mieux, une augmentation des pertes, ce qui signifie un échauffement et, au pire, un babah, car le courant traversant est un court-circuit commun (court-circuit). Pour éviter cela, un retard ou le soi-disant temps mort est introduit entre la fermeture d'un transistor et la mise en marche d'un autre. Cela ressemble à ceci:



Je pense que vous avez remarqué qu'il y a un petit écart à la limite de commutation du signal. Je l'ai installé sciemment grand (environ 3%) pour que vous puissiez le voir, en réalité il est beaucoup plus petit. En général, le temps mort (ci-après dt) est réglé le plus court possible, mais en même temps suffisant pour permettre la fermeture des transistors. Elle peut être calculée, ou elle peut être choisie empiriquement, je pense personnellement que telle ou telle option est normale, mais le Jedi barbu vous dira probablement: "Il faut y penser, mais il vaut mieux la modéliser!" C'est certainement correct, mais décidez par vous-même - si vous n'êtes pas trop paresseux, modélisez dans LTspice en tenant compte des inductances et des capacités parasites des conducteurs et des composants.

Pour le stand dans cet article, j'ai défini dt à ~ 100 ns (en fait 104). Mon module vous permet de l'installer beaucoup moins, car le pilote est très sévère appliqué, mais à coup sûr, beaucoup d'entre vous construiront votre mise en page sans mon module, ce qui signifie qu'il y aura très probablement de la morve. Pour ne pas rester coincé à cause de la morve, je laisse dt avec une marge et si vous avez un câblage normal sur la carte, vous pouvez vous-même le réduire - puis dans le chapitre sur le code, vous verrez comment, pour l'instant, nous voyons s'il y a vraiment dt:



On peut voir que dt dure 2,5 divisions et que chaque division est de 40 ns, ce qui signifie que la durée est de ~ 100 ns, comme prévu. J'espère que vous comprenez pourquoi le dt est nécessaire, combien de temps il devrait être en durée et comment le convertisseur fonctionne selon la topologie buck. Si vous ne comprenez pas, alors comme d'habitude, les questions dans les commentaires, PM et mail sont acceptées, alors que je semble répondre à tout le monde.

Chapitre 2. Le calcul des principaux composants


Dans cette partie de l'article, je montrerai comment calculer rapidement et facilement les principaux composants de puissance d'un convertisseur abaisseur synchrone, à savoir: inductance, condensateurs d'entrée et de sortie, transistors.

Permettez-moi de vous rappeler les données d'entrée:

  • Tension d'entrée: 15 ... 30V
  • Tension de sortie: 12V
  • Courant de sortie nominal: 2A
  • Fréquence de commutation: 100 kHz

La tension de sortie de 12V est sélectionnée car Je prévois d'utiliser une LED 12V 20W comme charge, qui s'est avérée être à portée de main et est une charge très évidente. Anticiper les questions des «experts» dans les commentaires - oui, je suis conscient que la LED a besoin d'une stabilisation de courant, mais nous faisons alors un stabilisateur de tension et la LED n'est qu'une charge.

La tension d'entrée est sélectionnée à partir du bulldozer, vous pouvez faire 15 ... 60V, donc si vous êtes intéressé par une plage différente, vous pouvez alors calculer vous-même la valeur des composants. Un courant nominal de 2A est choisi pour obtenir la puissance de sortie de 12V * 2A = 24 W, c'est-à-dire un peu plus que ce qui est nécessaire pour la LED. La LED elle-même à 12V consomme environ 1,82 ... 1,9A.

Le paramètre le plus intéressant est resté - la fréquence de fonctionnement du convertisseur. Qu'est-ce que ça devrait être? Vous devrez répondre ici vous-même, dans mon cas c'est 100 kHz. Le choix est basé sur deux points:

  • Une augmentation de la fréquence entraîne une diminution de l'inductance nécessaire de l'inductance, du condensateur d'entrée et de sortie. Autrement dit - avec une augmentation de la fréquence, les dimensions de l'appareil diminuent. Avec une fréquence décroissante, les dimensions augmentent.
  • Une diminution de la fréquence entraîne une augmentation de l'efficacité, car les pertes dynamiques lors de la commutation des transistors sont réduites. L'augmentation de la fréquence augmente la composante dynamique des transistors et réduit en conséquence l'efficacité.

Maintenant, je ne vais pas discuter du choix de la fréquence, il suffit de supposer que 100 kHz. Après avoir montré la méthodologie de calcul, nous reviendrons sur cette question, car selon les formules, la dépendance des valeurs nominales des principaux composants à la fréquence de fonctionnement sera plus clairement visible.

Étape 1. Choisir des transistors

Nous nous intéresserons principalement à 3 paramètres: la tension maximale «drain-source», la résistance de canal à l'état ouvert et la capacité de grille. Le plein potentiel de la source de tension (Vin) est appliqué au transistor, et il y a également des surtensions au moment de la commutation. Vous avez 2 options: prendre le transistor VT1 et VT2 avec une marge de tension ou l'histoire du snubber RC sur VT2. Dans mon cas, le module de puissance a des transistors 100V, et avec une entrée de 30V, c'est une énorme marge de tension, même 60V était suffisant pour se passer des amortisseurs et protéger le transistor contre les pannes.

Résistance de canal - le plus petit est le mieux, mais il y a un MAIS. Avec une diminution de la résistance du canal, nous réduisons les pertes statiques (I 2 * R), mais la technologie est telle que la capacité de la grille augmente, ce qui entraîne une augmentation des pertes dynamiques. Vous devez trouver un juste milieu entre la «résistance de canal» et la «capacité d'obturation». Pour les tensions jusqu'à 100V, je vous conseille de faire attention aux transistors de la série Infineon OptiMOS, regardez déjà vous-même les hautes tensions par recherche paramétrique ou même vers les transistors IGBT. Ces derniers sont également pris en charge par mon module d'alimentation et ne nécessitent aucune modification du pilote.

Étape 2. Le calcul de l'inductance de l'inductance

Il est nécessaire de calculer la valeur minimale de l'inductance, ce qui permettra à notre convertisseur DC / DC de fonctionner en mode courant continu (L min ):



En termes de variables, je pense que tout est clair sauf - k ind . Ce sont des courants d'ondulation admissibles dans l'inductance, ils choisissent généralement une valeur de 20 ... 50%, mais je règle presque toujours 30%. Plus l'ondulation du courant est petite, plus nous nous éloignerons de la frontière de saturation du noyau sur lequel l'inducteur est enroulé, mais comme le montre la formule, une grande inductance de l'inducteur est nécessaire.

Maintenant, nous calculons la valeur minimale de l'inductance, qui sera nécessaire pour mes données d'entrée, l'ondulation que je pondrai à 30% comme je l'ai écrit ci-dessus:



Il faut comprendre qu'il s'agit de l'inductance minimale requise pour que le convertisseur abaisseur fonctionne en mode de courants inextricables, mais là encore, il y a une nuance. Dans le processus d'augmentation du courant agissant dans l'enroulement, la perméabilité du noyau et l'inductance de l'inductance SANS courant et avec courant sont quelque peu différentes, la dépendance est différente pour différents matériaux.Pour éviter la situation où, avec une augmentation du courant dans l'inductance, l'inductance diminue en dessous de L min et que dc / dc ne passe pas en mode de courant de coupure, il est nécessaire d'augmenter quelque peu l'inductance, c'est-à-dire d'ajouter quelques tours supplémentaires pendant l'enroulement. Une augmentation de l'inductance de 10 à 15% sera suffisante pour le matériau Kool Mu, et mon étranglement sera là-dessus.

Étape 3. Calcul et fabrication de l'inductance

Je voudrais décrire cette procédure dans la section «prototypage», mais ensuite l'étape de calcul de l'inductance serait restée moins claire pour vous, et j'ai probablement raté les images intéressantes, donc je vais tout décrire ici. Pour la fabrication de l'accélérateur, je prendrai l'accélérateur R26 / 14/11 (R est l'anneau et les chiffres sont des dimensions) en matériau Kool Mu avec une perméabilité 60, vous pouvez télécharger la documentation pour cela et acheter ici -Lepkos .



Vous devez maintenant calculer le nombre de tours et le fil à enrouler. Commençons peut-être par le nombre de tours. Il y a un tel paramètre pratique dans la documentation pour le noyau - A L , qui est égal à 75 nH / tour 2 . Ici soigneusement - se transforme en carré! Pour trouver l'inductance du noyau, multipliez A L par le nombre de tours dans le carré. De là, la formule pour trouver le nombre de tours ressemble à ceci:



Pour obtenir l'inductance minimale requise, il faut enrouler 40 tours, mais comme nous l'avons déjà discuté, il est nécessaire d'augmenter légèrement l'inductance, ajoutons 3 tours. On prend l'anneau et on tourne 43 tours, on obtient un tel accélérateur:



Maintenant, pour l'intérêt, nous calculons quelle inductance devrait se produire:



Et pour la fiabilité, nous vérifions l'inductance de l'inductance avec une pince à épiler:



137 μH, super! Les résultats ont convergé, une erreur de ± 8% de A L . Il convient de mentionner que si vous n'avez pas la capacité de mesurer l'inductance, n'achetez pas de noyaux pour aliexpress, dans ChiD, ordinateur, ingénieur en électronique et autres "restaurants" - il y a une chance d'obtenir le noyau à partir d'un autre matériau ou avec une mauvaise perméabilité, mais avec le marquage correct - vérifié. Sans la capacité de mesurer l'inductance, vous ne pourrez pas vérifier A L et vous pourrez vous tourmenter grandement à la recherche de la cause du "babakh" de votre convertisseur.

Cela soulève une question raisonnable - «aurons-nous suffisamment de noyau et ses dimensions? Peut-être que c'était plus nécessaire? ". Pour le matériau Kool Mu, la limite d'induction magnétique est de 0,5 T; en pratique, il vaut mieux ne pas ramper au-delà d'un seuil au-dessus de 0,45 T sans avoir clairement besoin. Il s'avère que l'enroulement enroulé sur le noyau n'a pas à créer d'induction à chaque point du noyau de plus de 0,45 T, nous vérifions donc:



Comme vous pouvez le voir, la valeur de l'induction magnétique de 0,06 T est bien inférieure à la limite de 0,5 T. Deux conclusions peuvent en être tirées: d'une part, l'accélérateur n'entrera pas en saturation, et d'autre part, le noyau est très gros et il est puissant de prendre un anneau beaucoup plus petit. J'ai pris la bague R26 simplement parce que j'ai toute leur boite, il n'y a pas d'autre sens secret.

Il reste à déterminer quelle section du fil prendre pour l'inductance. Tout d'abord, je vous déconseille fortement de prendre un fil d'un diamètre supérieur à 1 ... 1,2 mm à des fréquences aussi élevées, car l'effet peau a déjà un effet significatif et réduit la section efficace. Deuxièmement, la densité de courant dans le fil doit être sélectionnée en fonction des conditions de refroidissement et de la puissance. À faibles puissances (jusqu'à 10-20 W), vous pouvez appliquer en toute sécurité une densité de courant de 8..10 A / mm 2 même sans flux d'air. À des puissances allant jusqu'à plusieurs kilowatts, il est préférable de placer la densité de courant dans la plage de 5 ... 6 A / mm 2 , et à des puissances à partir de 10 kW, il sera raisonnable de réduire la densité de courant à 3 ... 4 A / mm 2 .

Au bout de mes doigts, il y avait un fil verni d'un diamètre de 0,8 mm. Sa section transversale, respectivement, est de ~ 0,5 mm 2 . A un courant de 2A, on obtient une densité de courant dans l'enroulement d'environ 4 A / mm 2 . Je pourrais utiliser un fil avec la moitié de la section, mais mon noyau est assez grand, donc un fil de section plus grande s'adapte sans aucun problème. Lorsque vous optimisez votre appareil, vous devrez d'abord compter, puis acheter le fil de la section souhaitée, puis vous pourrez obtenir les dimensions optimales de l'inductance.

Étape 4. Calcul du condensateur de sortie

A ce stade, comme dans le cas de l'inductance, nous considérerons la valeur minimale de la capacité qui doit être installée dans le filtre LC à la sortie du convertisseur abaisseur. En conséquence, si vous en installez plus, ce sera mieux et voyez pourquoi. Calculons la capacité:



bien sûr, la capacité doit également être mise avec une certaine marge, surtout si vous n'utilisez que de la céramique à la sortie, car sa capacité est fortement réduite en fonction de la tension qui lui est appliquée. Il convient également de prêter attention à la dépendance aux pulsations - l' impulsion V variable. Il s'agit de la valeur maximale de l'ondulation à la sortie, c'est-à-dire, idéalement, avec une capacité de 147,8 μF, l'amplitude de l'ondulation sera de 0,2 V, c'est-à-dire que la tension de sortie flottera dans la plage 11,9 ... 12,1 V. Vous voulez réduire l'ondulation? Réduisez-les ensuite dans la formule et la valeur de la capacité résultante augmentera en conséquence, bien sûr, vous n'obtiendrez pas une alimentation électrique de laboratoire simplement en augmentant la capacité de sortie. Il est également nécessaire de prendre en compte la nécessité d'un faible ESR, pour cela, ils mettent généralement 1-2 électrolytes en parallèle et accrochent plusieurs céramiques en parallèle avec un diélectrique X7R, de préférence. Si le budget le permet, il est possible de remplacer le condensateur électrolytique par du tantale polymère (comme dans le GPU), et donc la céramique n'est pas nécessaire, ils ont un minuscule ESR.

Considérations de fréquence

Maintenant, comme je l'ai dit, nous reviendrons sur la question du choix de la fréquence de fonctionnement du convertisseur. Permettez-moi de diviser les conclusions en quelques réflexions:

  • Comme vous le voyez dans la formule, la fréquence apparaît, plus la fréquence de fonctionnement est élevée, plus l'inductance de l'inductance sera faible et moins de tours devront être enroulés - nous économisons sur le cuivre et simplifions la fabrication des produits de bobinage
  • L'inductance et le nombre de tours sont présents dans la formule de calcul de l'induction magnétique, bien que, comme vous vous en souvenez, l'inductance a une dépendance quadratique sur les tours, ce qui signifie que lorsque le nombre de tours est réduit de 2 fois, l'inductance diminue de 4 fois. Il en résulte que, avec l'augmentation de la fréquence, l'inductance et la valeur de l'induction magnétique diminuent, ce qui signifie qu'un noyau plus petit peut être utilisé, c'est-à-dire que nous réduisons les dimensions
  • , — , , . !
  • … , . buck- mosfet- 200 . ( ) ? GaN

Je pense qu'à partir de ces thèses, il est devenu clair pour vous ce que la fréquence de commutation affecte, maintenant vous devez apprendre à trouver vous-même le "moyen d'or" entre les pertes sur les transistors et la taille de l'appareil. Dans l'un des articles suivants je vais vous apprendre à optimiser la fréquence de fonctionnement pour une efficacité maximale, l'essentiel est de ne pas oublier que j'allais le faire.

Chapitre 3. Assemblage d'une disposition de convertisseur abaisseur


Ainsi, la partie la plus fastidieuse mais la plus importante est terminée, maintenant le matériel et le code disparaîtront. Mettons ensemble un schéma sur lequel nous allons implémenter des calculs théoriques. Pour ce faire, vous aurez besoin de deux modules dont j'ai parlé dans les articles précédents: le module de puissance et le module de contrôle sur le STM32F334 . Vous pouvez également assembler vous-même un demi-pont à partir de n'importe quelle poubelle improvisée de type IR2110 sur une planche à pain, et utiliser n'importe quel MK comme contrôle: STM32-Discovery, LaunchPad, Arduino et simplement adapter la logique de travail et le code à votre MK préféré, rien ne sera compliqué si vous avez compris dans les deux premiers chapitres comment fonctionne le convertisseur abaisseur.

Rendons maintenant notre diagramme buck plus «réaliste» en y ajoutant les valeurs de tous les composants et reflétons correctement le nombre de condensateurs, et notons quelle partie mon module d'alimentation peut réaliser:



Comme vous pouvez le voir sur le schéma, le module contient déjà un demi-pont (deux transistors) pour implémenter un buck synchrone et un condensateur d'entrée, soit dit en passant, il est dans le module avec une énorme marge - il y a 3 électrolytes de 1000 uF et 100V chacun, cela suffit pour assembler facilement un buck pour 500 -800 watts Il nous reste à rajouter une self, que nous avons déjà fabriquée et des condensateurs de sortie, ces derniers d'ailleurs d'ailleurs avec une marge, car Je n'ai trouvé que 4700 uF 25V pour la basse tension, mais ce sont des chinois, j'ai donc décidé de paralléliser un couple. En fait, il y a assez de 470 uF là-bas, mais je n'avais tout simplement pas une telle bagatelle dans la version de sortie. Il s'avère que cette conception:



Comme mentionné précédemment, une puissante LED de 20 W est utilisée comme charge. Je ne sais pas combien de lumière il brille, et ce n'est pas très intéressant, mais il consomme seulement 21 ... 22 W à 12 V pour lequel mon convertisseur abaisseur est conçu. La LED elle-même a recouvert le KPT-8 et l'a vissé au radiateur, bien sûr, ce n'est pas suffisant, mais cela dure 5-7 minutes sans problème (il chauffe jusqu'à +40 ... 50 o C), et je n'en ai pas besoin de plus. Nous connectons 2 signaux HRPWM, GND du module de commande et, via le diviseur, nous raccordons la sortie buck à l'ADC, en conséquence, nous avons un tel support:



Chapitre 4. Écrire un logiciel et démarrer le convertisseur


Nous avons maintenant tout ce dont nous avons besoin pour commencer à écrire du code et à revitaliser notre convertisseur buck. Tout d'abord, regardons le brochage du microcontrôleur STM32F334R8T6, qui se trouve dans le module de contrôle:



Nous savons maintenant quelles broches de microcontrôleur seront utilisées. Sur le module lui-même, je n'ai besoin que de 1 canal sur 5 pour contrôler le bloc d'alimentation, nous utiliserons le canal «A». Ce canal, comme tout le reste, possède 2 sorties PWM de haute précision (HRPWM), 1 entrée d'erreur (nous ne l'utilisons pas), GND pour combiner la masse des cartes et 2 canaux ADC (nous n'en utiliserons qu'une pour la tension).

Un peu sur HRPWM

Dans les étendues du segment de langue russe d'Internet, je n'ai presque pas rencontré de matériel de formation sur HRPWM et je n'ai pas du tout rencontré de matériel sur le travail avec HRPWM basé sur des microcontrôleurs STM32, et c'est un périphérique très utile.

Je ne m'attarderai pas sur la théorie de cette périphérie dans le cadre de cet article, je décrirai donc l'essentiel. HRPWM ou PWM haute résolution est notre module PWM habituel, qui a une résolution accrue pour le réglage du facteur de marche et a en outre généralement des paramètres plus flexibles.



  • Le microcontrôleur STM32F334R8T6 possède 10 canaux HRPWM, qui sont combinés en 5 groupes de 2 canaux. Ces 2 canaux au sein du groupe peuvent fonctionner à la fois indépendamment et former une paire complémentaire - nous avons besoin de ce dernier;
  • À l'intérieur de la paire complémentaire entre 2 signaux PWM, il est possible d'installer un temps mort matériel pour la protection contre le courant traversant;
  • Les 10 canaux sont synchronisés à partir d'une seule minuterie - Minuterie principale, de sorte qu'ils sont tous synchronisés les uns avec les autres et vous n'avez pas à configurer manuellement une chaîne de temporisateurs. Il suffit d'activer les temporisateurs Master et Timer A ... E pour en être synchronisés;
  • La fréquence à HRPWM est doublée, c'est-à-dire qu'à une fréquence centrale de 72 MHz, à HRPWM, elle est de 144 MHz après un multiplicateur supplémentaire (x2) avec PLL. Cela permet de contrôler les convertisseurs à une fréquence de centaines de kHz;
  • De nombreux paramètres pour le contrôle PWM, par exemple, ainsi que la possibilité de lier la génération PWM au début et à la fin de la période, il y a 4 autres événements configurables (comp) qui vous permettent de traduire le PWM en 0 ou 1 à tout moment de la période autre que le début / la fin de la période;
  • Il existe des modes pour des topologies spécifiques, par exemple, le mode push-pull, qui vous permet d'implémenter de nombreuses topologies push-pull.

Et ce n'est qu'une petite partie des fonctionnalités, sur le diagramme de l'appareil HRPWM, vous pouvez voir les capacités de synchronisation avec un tas d'événements, DAC, comparateurs intégrés au MK, et avec ce diagramme, il y a beaucoup plus de possibilités documentées.

Il reste la dernière question qui doit être abordée - "pourquoi ce bit haut PWM?". Pour ce faire, considérons un exemple simple. Imaginez que nous avons décidé d'utiliser MK sans HRPWM, disons STM32F103C8T6, qui fonctionne également à une fréquence de 72 MHz. Nous devons contrôler le demi-pont à une fréquence de 70 kHz, nous considérons quel pas de régulation nous pouvons obtenir: 72 000 000/1025 pas = 70 243 Hz. Oui, nous avons 1025 étapes et lors du réglage, nous pouvons changer la tension de sortie avec une étape théorique de 1/1025 = ~ 0,1%. Maintenant, nous prenons STM32F334, avec une fréquence d'horloge de 144 MHz et une largeur de décalage de la minuterie de 32 bits, nous obtenons la fréquence équivalente de 144 MHz * 32 = 4,608 GHz. Pour ceux qui ont eu peur et ont douté du chiffre:



Non, ce n'est pas une fréquence de fonctionnement, c'est une fréquence équivalente. Qu'est-ce que cela nous donne? On prend la fréquence équivalente de 4 608 000 000 Hz / 70 300 Hz = 65 535 pas. Nous pouvons maintenant ajuster la tension (ou le courant) à la sortie par incréments de 1/65 535 = ~ 0,001%, c'est-à-dire 100 fois plus précis!

Et maintenant, faisons-le - nous avons une fréquence de 700 kHz, ce qui est normal pour un buck multiphasé, par exemple. Le F103 obtiendra 72 000 000 Hz / 700 000 Hz = 102 pas, ce qui vous permet d'obtenir au mieux une régulation de 1%, mais c'est 1% pour le service, c'est-à-dire qu'en réalité avec autant de pas vous aurez une tension flottante à la sortie comme si elle se stabilisait et pas vraiment. Alors que pour F334, le nombre de pas sera d'environ 6500, ce qui vous permet de construire un régulateur de tension ou de courant très précis. Nous obtenons que la résolution (étape) du paramètre de rapport cyclique est beaucoup plus élevée / plus souvent qu'avec un MK conventionnel avec un module PWM standard à l'intérieur.

Configuration du système d'horloge

J'ai utilisé TrueSTUDIO comme environnement de développement dans cet article, car il est gratuit, pas aussi misérable que Keil ou IAR oui oui, parlez-moi de son merveilleux débogueur , multiplateforme et peut-être la meilleure solution pour les débutants et pas seulement. À la fin de l'article, il y aura une archive avec le projet spécifiquement pour cet IDE. Je ne vais pas vous dire comment créer et configurer un projet, je vais juste laisser un lien vers la vidéo où tout est montré en détail - regardez .

Après avoir créé un projet et fait clignoter une LED, vous devez configurer le système d'horloge, à savoir, de 8 MHz augmenter la fréquence à 72 MHz et appliquer au cœur, puis ajuster le diviseur pour réduire la fréquence fournie à l'ADC:

void StartInitClock (void) { RCC->CR |= RCC_CR_HSEON; // Enable HSE while (!(RCC->CR & RCC_CR_HSERDY)); FLASH->ACR |= FLASH_ACR_LATENCY_1; RCC->CFGR |= RCC_CFGR_PLLMUL9; // PLL mult x9 RCC->CFGR |= RCC_CFGR_PLLSRC; // Source HSE RCC->CFGR2 |= RCC_CFGR2_ADCPRE12_DIV10; // ADC source AHB/10 RCC->CR |= RCC_CR_PLLON; while((RCC->CR & RCC_CR_PLLRDY) == 0){} RCC->CFGR &= ~RCC_CFGR_SW; RCC->CFGR |= RCC_CFGR_SW_PLL; // Select source SYSCLK = PLL while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_1) {} // Wait PLL } 

Ici, je pense juste que l'algorithme de réglage est le suivant: il passe au quartz externe (HSE) -> nous attendons lorsque la transition est terminée et le drapeau prêt est défini -> nous envoyons le signal du quartz à l'entrée PLL -> nous multiplions 8 MHz par 9 -> nous divisons la fréquence par 72 MHz par 10 pour synchroniser l'ADC -> allumez PLL -> attendez qu'il s'allume et définissez le drapeau prêt -> envoyez un signal de PLL au bus système et au cœur -> attendez que le commutateur soit terminé -> fait.

Configuration de HRPWM

Ici, tout est un peu plus compliqué, car Ce module a beaucoup de fonctionnalités, un tas de paramètres et la quantité de documentation est très grande, mais c'est un inconvénient et en même temps un plus - vous devez payer pour la flexibilité.

 RCC->CFGR3 |= RCC_CFGR3_HRTIM1SW_PLL; RCC->APB2ENR |= RCC_APB2ENR_HRTIM1EN; 

Vous devez spécifier que HRTIM est cadencé à partir de PLL, le multiplicateur x2 est déjà activé par défaut. Ensuite, nous allumons simplement l'horloge pour HRTIM, voici la première fonctionnalité - si nous comprenons que la minuterie est cadencée à partir de PLL, mais nous l'allumons pour APB2. Ce n'est pas tout à fait logique, mais il est facilement recherché dans le fichier avec CMSIS ou dans la documentation.

  RCC->AHBENR |= RCC_AHBENR_GPIOAEN; GPIOA->MODER &= ~GPIO_MODER_MODER8; GPIOA->MODER |= GPIO_MODER_MODER8_1; // Alternative PP GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR8; // Very high speed GPIOA->MODER &= ~GPIO_MODER_MODER9; GPIOA->MODER |= GPIO_MODER_MODER9_1; GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR9; GPIOA->AFR[1] |= 0xDD; // PA8 and PA9 - AF13 

PA8 et PA9 sont la sortie du temporisateur A, qui sur mon module va au canal n ° 1, que vous pouvez voir dans le diagramme et le brochage. Les jambes sont configurées en push-pull avec une fonction alternative, le numéro de la fonction elle-même pour les deux jambes est le 13ème. Il est également important de régler la fréquence GPIO maximale, sinon il y aura un blocage incompréhensible du front et de la chute du signal, ce qui est extrêmement critique pour l'électronique de puissance.

 HRTIM1->sCommonRegs.DLLCR |= HRTIM_DLLCR_CAL | HRTIM_DLLCR_CALEN; while ((HRTIM1->sCommonRegs.ISR & HRTIM_ISR_DLLRDY) == RESET); 

Avant de commencer, vous devez calibrer la minuterie, car Cela fonctionne avec des délais minimaux, puis attendez simplement le drapeau prêt.

 HRTIM1->sTimerxRegs[0].PERxR = PeriodTimerA; // Period for timer A HRTIM1->sTimerxRegs[0].CMP1xR = 0; // Duty for timer A 

C'est ça la flexibilité. Tout d'abord, nous pouvons définir notre propre fréquence pour chaque temporisateur A ... E, ici nous enregistrons simplement la période de notre PWM. Deuxièmement, par défaut, nous avons l'alignement PWM au début de la période, c'est-à-dire que le signal passe à log.1 au début d'une nouvelle période, et maintenant nous devons choisir quand il reviendra à log.0, dans ce cas, par le comparateur n ° 1, c'est-à-dire J'y demande essentiellement le facteur de droit.

Par exemple, vous pouvez traduire PWM non pas au début de la période, mais par le comparateur n ° 1, et revenir à log.0 par le comparateur n ° 2 et ainsi déplacer en phase le matériel.

 // Deadtime enable HRTIM1->sTimerxRegs[0].OUTxR |= HRTIM_OUTR_DTEN; // Tdtg = 6.94 ns HRTIM1->sTimerxRegs[0].DTxR |= HRTIM_DTR_DTPRSC_0 | HRTIM_DTR_DTPRSC_1; // Deadtime rising = 15*Ttg = 104 ns HRTIM1->sTimerxRegs[0].DTxR |= HRTIM_DTR_DTR_0 | HRTIM_DTR_DTR_1 | HRTIM_DTR_DTR_2 | HRTIM_DTR_DTR_3; // Deadtime falling = 15*Ttg = 104 ns HRTIM1->sTimerxRegs[0].DTxR |= HRTIM_DTR_DTF_0 | HRTIM_DTR_DTF_1 | HRTIM_DTR_DTF_2 | HRTIM_DTR_DTF_3; HRTIM1->sTimerxRegs[0].DTxR |= HRTIM_DTR_DTFSLK | HRTIM_DTR_DTRSLK; 

A ce stade, nous activons le temps mort et le configurons, en principe, les commentaires contiennent toutes les formules, elles peuvent également être trouvées dans le manuel de référence. DT avec une durée de ~ 100 ns que vous avez déjà vu sur la forme d'onde dans le chapitre théorique de cet article. Le temps mort peut être réglé séparément sur le bord et sur le déclin du signal. Soit dit en passant, [0] est le temporisateur A, respectivement [1] est le temporisateur B et ainsi de suite.

 // Samples in middle of ON time HRTIM1->sTimerxRegs[0].CMP2xR = PeriodTimerA / 10; // ADC trigger 1 update: Timer A HRTIM1->sCommonRegs.CR1 |= HRTIM_CR1_ADC1USRC_0; // ADC trigger 1 event: Timer A compare 2 HRTIM1->sCommonRegs.ADC1R |= HRTIM_ADC1R_AD1TAC2; 

Pour moi, ce n'était pas le moment le plus évident. L'essentiel est - je veux m'assurer que pendant 10% de la durée de la période du temporisateur A, un événement est généré qui déclenche la conversion ADC et mesure le signal de rétroaction. Pourquoi 10%? Simplement, idéalement, la mesure ne devrait pas avoir lieu au moment de la transition du PWM de 0 à 1 ou vice versa, car en ce moment dans l'unité de puissance il y a des transitoires et des interférences, mais nous n'avons pas besoin de les mesurer. Par conséquent, 10% dans mon cas est optimal, car à une sortie de 12 V et à 30 V, la tension d'entrée du facteur de marche ne tombera pas à 10% et le moment de la commutation du transistor ne correspondra pas exactement à la mesure ADC.

Maintenant, vous devez regarder le système de communication événementielle entre HRTIM et l'ADC:



Dans la première ligne, nous choisissons quand le comparateur sera déclenché, dans mon cas c'est 10% de la période du temporisateur A. Ensuite, nous sélectionnons un déclencheur spécifique dans l'ADC qui contactera le MK, nous avons accès au 1er ou au 3ème. Maintenant, il indique simplement quel événement enverra le signal à l'ADC, dans mon cas, c'est le comparateur n ° 2.

 // Enable output PWM for TA1 and TA2 HRTIM1->sCommonRegs.OENR |= HRTIM_OENR_TA1OEN | HRTIM_OENR_TA2OEN; // Continuous mode HRTIM1->sTimerxRegs[0].TIMxCR |= HRTIM_TIMCR_CONT; // Period for master timer HRTIM1->sMasterRegs.MPER = 65000; // Enable counter for Master and timer A HRTIM1->sMasterRegs.MCR |= HRTIM_MCR_MCEN | HRTIM_MCR_TACEN; 

Et l'accord final! Nous permettons à HRTIM d'émettre des signaux du temporisateur A vers notre GPIO. Maintenant, nous sélectionnons le mode, cela se produit sans fin (je l'ai), mais il arrive que le minuteur soit allumé pendant 1 période et après cela, il doit être redémarré. Ensuite, définissez la période de la minuterie principale et allumez-la comme dernière étape, elle commence à synchroniser les temporisateurs de canal et le signal PWM apparaît à la sortie.

C'était une fonction de réglage, il reste à faire une fonction qui fixera le facteur de marche, c'est avec elle que nous travaillerons lors de la création du contrôleur:

 void SetDutyTimerA (uint16_t duty) { HRTIM1->sTimerxRegs[0].CMP1xR = duty; } 

Liste des paramètres de fonction et définition du cycle de service
 // f = 102,4 kHz #define PeriodTimerA ((uint16_t)45000) void InitHRPWM (void) { RCC->CFGR3 |= RCC_CFGR3_HRTIM1SW_PLL; RCC->APB2ENR |= RCC_APB2ENR_HRTIM1EN; /************************************************ * Setting GPIO ***********************************************/ RCC->AHBENR |= RCC_AHBENR_GPIOAEN; // Alternative PP GPIOA->MODER &= ~GPIO_MODER_MODER8; GPIOA->MODER |= GPIO_MODER_MODER8_1; // Very high speed GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR8; GPIOA->MODER &= ~GPIO_MODER_MODER9; GPIOA->MODER |= GPIO_MODER_MODER9_1; GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR9; // PA8 and PA9 - AF13 GPIOA->AFR[1] |= 0xDD; /************************************************ * Setting timer A ***********************************************/ HRTIM1->sCommonRegs.DLLCR |= HRTIM_DLLCR_CAL | HRTIM_DLLCR_CALEN; while ((HRTIM1->sCommonRegs.ISR & HRTIM_ISR_DLLRDY) == RESET); // Period for timer A HRTIM1->sTimerxRegs[0].PERxR = PeriodTimerA; // Duty for timer A HRTIM1->sTimerxRegs[0].CMP1xR = 0; // Deadtime enable HRTIM1->sTimerxRegs[0].OUTxR |= HRTIM_OUTR_DTEN; // Tdtg = 6.94 ns HRTIM1->sTimerxRegs[0].DTxR |= HRTIM_DTR_DTPRSC_0 | HRTIM_DTR_DTPRSC_1; // Deadtime rising = 15*Ttg = 104 ns HRTIM1->sTimerxRegs[0].DTxR |= HRTIM_DTR_DTR_0 | HRTIM_DTR_DTR_1 | HRTIM_DTR_DTR_2 | HRTIM_DTR_DTR_3; // Deadtime falling = 15*Ttg = 104 ns HRTIM1->sTimerxRegs[0].DTxR |= HRTIM_DTR_DTF_0 | HRTIM_DTR_DTF_1 | HRTIM_DTR_DTF_2 | HRTIM_DTR_DTF_3; HRTIM1->sTimerxRegs[0].DTxR |= HRTIM_DTR_DTFSLK | HRTIM_DTR_DTRSLK; // Event forces the output to active state for TA1 HRTIM1->sTimerxRegs[0].SETx1R |= HRTIM_SET1R_PER; // Event forces the output to inactive state for TA1 HRTIM1->sTimerxRegs[0].RSTx1R |= HRTIM_RST1R_CMP1; /************************************************ * ADC trigger intialization (with CMP2 event) ************************************************/ // Samples in middle of ON time HRTIM1->sTimerxRegs[0].CMP2xR = PeriodTimerA / 10; // ADC trigger 1 update: Timer A HRTIM1->sCommonRegs.CR1 |= HRTIM_CR1_ADC1USRC_0; // ADC trigger 1 event: Timer A compare 2 HRTIM1->sCommonRegs.ADC1R |= HRTIM_ADC1R_AD1TAC2; /************************************************ * HRTIM start ***********************************************/ // Enable output PWM for TA1 and TA2 HRTIM1->sCommonRegs.OENR |= HRTIM_OENR_TA1OEN | HRTIM_OENR_TA2OEN; // Continuous mode HRTIM1->sTimerxRegs[0].TIMxCR |= HRTIM_TIMCR_CONT; // Period for master timer HRTIM1->sMasterRegs.MPER = 65000; // Enable counter for Master and timer A HRTIM1->sMasterRegs.MCR |= HRTIM_MCR_MCEN | HRTIM_MCR_TACEN; } void SetDutyTimerA (uint16_t duty) { HRTIM1->sTimerxRegs[0].CMP1xR = duty; } 


Voyons maintenant si nous allons dans le bon sens. Dans la fonction principale , initialisez le paramètre HRTIM et définissez le rapport cyclique, disons 22500. Avec une tension d'entrée de 20V et une période de 45000, notre rapport cyclique sera de 50% et la sortie sera d'environ 10V. Cela ne suffit pas pour étendre la LED au maximum, mais cela devrait s'allumer et nous comprendrons si la section d'alimentation fonctionne, tout est ok avec dt et ainsi de suite. J'ai tout commencé la première fois:



Vous pouvez voir que tous les calculs théoriques précédents ont été confirmés. Avec un facteur de marche fixe de 50%, la tension de sortie était simplement divisée par 2: 20V -> 10V, 22V -> 11V, 18V -> 9V. Maintenant, rendons la tension de sortie stable et indépendante de l'entrée, c'est-à-dire ajoutons un retour.

ADC et réglage du contrôleur

Beaucoup de choses ont déjà été écrites sur les ADC dans STM32 avant moi, je ne m'arrête que sur la configuration du déclencheur associé au comparateur HRTIM. Je vais parler brièvement du reste des paramètres ADC. Nous regardons la fonction d'initialisation:

 void InitBasicADC (void) { RCC->AHBENR |= RCC_AHBENR_ADC12EN; RCC->AHBENR |= RCC_AHBENR_GPIOCEN; /************************************************ * Calibration ***********************************************/ ADC2->CR &= ~ADC_CR_ADVREGEN; ADC2->CR |= ADC_CR_ADVREGEN_0; // Vref enable Delay(10); ADC2->CR &= ~ADC_CR_ADCALDIF; ADC2->CR |= ADC_CR_ADCAL; // Start calibration while (ADC2->CR & ADC_CR_ADCAL); // Wait end calibration /************************************************ * Select event trigger and channel ***********************************************/ // Enable start conversion external trigger ADC2->CFGR |= ADC_CFGR_EXTEN_0; // Event 7 - HRTIM ADC2->CFGR |= ADC_CFGR_EXTSEL_0 | ADC_CFGR_EXTSEL_1 | ADC_CFGR_EXTSEL_2; // Select ADC2 channel IN5 ADC2->SQR1 |= ADC_SQR1_SQ1_0 | ADC_SQR1_SQ1_2; // Length regular ADC channel = 1 ADC2->SQR1 &= ~ADC_SQR1_L; ADC2->IER |= ADC_IER_EOCIE; // Interrupt enable NVIC_EnableIRQ(ADC1_2_IRQn); // enable interrupt ADC1 and ADC2 /************************************************ * Start ADC ***********************************************/ ADC2->CR |= ADC_CR_ADEN; // Enable ADC2 Delay(10); ADC2->CR |= ADC_CR_ADSTART; } 

J'utilise le mode canal normal, je n'ai qu'un canal et il est sélectionné dans le registre SQR1 . Impliqué ADC numéro 2, à savoir son entrée IN5, il est rapide et peut fonctionner à la fréquence d'échantillonnage maximale, mais pas cette fois. La fréquence d'échantillonnage est égale à la fréquence PWM, car 1 période = 1 échantillon, en principe, c'est largement suffisant.

De plus, dans le registre CFGR , nous devons sélectionner l'événement par lequel la conversion commencera, c'est-à-dire l' événement 7 , pourquoi exactement? On regarde en RM:



Le déclencheur 1 du module HRPWM arrive à l'événement 7 pour notre ADC n ° 2, qui dans ce cas fonctionne comme un esclave, puis il est contrôlé à partir du module HRPWM. Je pense que maintenant il est clair comment connecter 2 modules, en principe, l'algorithme est similaire pour n'importe quelle périphérie et n'importe quelle minuterie, seul le nom du registre différera.

Lorsque le compteur de période du temporisateur principal est atteint, une conversion démarre, qui après environ 15 cycles (pour combien exactement voir en RM) provoquera une interruption et vous pourrez y récupérer le résultat. C'est dans cette interruption que nous organisons l'algorithme de contrôle. Oui, à l'intérieur de l'interruption, quelque chose de massif vaut mieux ne pas le faire, il vaut mieux mettre le drapeau et passer l'exécution, mais je me permettrai une telle simplification, car dans ce cas mon contrôleur n'est pas particulièrement chargé et il arrivera à calculer et sortir de l'interruption avec une probabilité de 146% à l'émergence d'un nouveau.

Un peu sur la gestion

Imaginez que vous êtes entré dans la salle de bain et avez décidé de vous laver les mains dans l'évier. Vous ouvrez légèrement l'eau, la touchez avec votre main, froide? Ajouter plus d'eau chaude, plus chaude? Bon! Ajouter plus d'eau chaude? Presque ce dont vous avez besoin? Bon! Ajouter plus d'eau chaude, essayer avec la main, se brûler? Baissons un peu le chaud maintenant. D'accord? Et donc à l'infini, vous tournerez le robinet jusqu'à ce que la température de l'eau devienne idéale. C'est le bouton le plus simple!

Seulement, nous ne réglementons pas la quantité d'eau chaude, mais le cycle de service PWM. Au lieu d'une main, nous avons un ADC avec un résultat mesuré. Il ne reste plus qu'à mettre en œuvre la logique. Nous calculerons ce que l'ADC devrait produire à une sortie 12V, puis en utilisant la condition if , nous forcerons notre contrôleur à maintenir cette valeur en changeant le facteur de marche.

Pour commencer, raccrochons un diviseur de tension pour réduire le 12V à 2-2,5V, par exemple, car L'ADC peut mesurer de 0 à + 3,3V et si 12V est fourni, le microcontrôleur s'éteindra simplement. Par conséquent, je mettrai un diviseur avec des valeurs nominales de 10 kOhm et 2 kOhm, ce qui donnera un rapport de division de 6 et, en conséquence, notre + 12V se transformera en + 2V. Notre ADC produira le résultat: adcResult = (V out / k) / V ref * 2 12 = (12V / 6) / 3.3 * 4095 = 2481. Maintenant, nous écrivons le code du gestionnaire d'interruption:

 void ADC1_2_IRQHandler (void) { ADC2->ISR |= ADC_ISR_EOC; adcResult = ADC2->DR; if (adcResult > 2480) { dutyControl = dutyControl - 10; } else { dutyControl = dutyControl + 10; } SetDutyTimerA(dutyControl); } 

Tout d'abord, après être entré dans le gestionnaire d'interruption, vous devez effacer le drapeau de cette interruption, sinon la deuxième fois, vous n'y entrerez pas. Ensuite, nous lisons le résultat et l'enregistrons en tant que variable adcResult . Maintenant, connaissant la tension à la sortie, vous devez ajuster le rapport cyclique pour le PWM, je l'ai implémenté simplement via la condition if . Dans chaque période PWM, nous prenons une mesure, augmentons ou diminuons le rapport cyclique et définissons le résultat pour la période suivante. Tout est simple, rapide et l'essence est visible. Nous regardons le résultat du travail:



Comme vous pouvez le voir, tout fonctionne et lorsque la tension d'entrée change, la sortie elle-même reste stable à 12V. Très attentif, vous remarquerez que de petites aiguilles glissent, alors il vous suffit de suspendre la céramique X7R à la sortie de 1-10 microfarades et elles partiront, je suis juste trop paresseux pour la chercher et la souder. Maintenant l'oscillogramme lui-même, pour ne pas gâcher les yeux:



Ici, vous pouvez voir comment la tension de sortie augmente. Le fait est qu'en raison de l'algorithme de contrôle, pour que le remplissage atteigne une valeur de 0 à 10000, par exemple, mille périodes ou environ 10 ms sont nécessaires. Cela me convient car un démarrage en douceur, si vous voulez réduire le temps de montée, compliquez un peu l'algorithme et ajoutez +1000, pas +10, et plus vous vous rapprochez du 12V spécifié, moins vous réglez jusqu'à ce que vous atteigniez +10 . En général, beaucoup de choses peuvent être faites en termes de gestion, vous avez donc un champ d'expérimentation.

Un autre point intéressant est l'oscillation au moment de l'arrêt, un tel "harmonica". Le fait est qu'après avoir coupé l'alimentation, ma partie numérique continue de fonctionner à partir d'une autre alimentation et essaie de conserver la valeur souhaitée à la sortie. D'où vient l'énergie? Oui, à partir du condensateur d'entrée, ce sont ceux qui font déjà 1 000 microfarads en 3 pièces, c'est un phénomène tellement intéressant.

Conclusion


L'article n'était pas petit, mais vous vouliez tout et immédiatement, ils disent: préparons le morceau de fer - faites-le. J'espère que vous apprécierez l'article, j'ai essayé de le rendre non pas scientifique, mais populaire, afin que le matériel soit accessible à des personnes ayant différents niveaux de connaissances et d'expérience. Peut-être qu'à l'avenir, j'analyserai de manière similaire d'autres topologies telles que boost, pont complet et autres.

À propos, cet article et ce code serviront au nouveau contrôleur MPPT sur 20A, que je conçois. J'attends maintenant les cartes PCBway , qui se sont portées volontaires pour parrainer mes projets open-source avec des cartes de circuits imprimés, les sources MPPT seront également ouvertes comme pour tous mes modules.

J'ai oublié la chose la plus importante! Conservez le projet avec le code TrueSTDIO - RAR .

Source: https://habr.com/ru/post/fr432778/


All Articles