Génération de signal PWM multiphasé sur TMS320F28027

Il était une fois dans une galaxie lointaine lointaine J'ai écrit un court article sur le contrôleur spécialisé Piccolo de Texas Instruments, qui est conçu pour contrôler les convertisseurs de puissance et les entraînements électriques. Ces contrôleurs sont des outils de développement très puissants dans de nombreuses tâches et je voulais écrire autre chose à leur sujet ... simple et utile.


Récemment, j'ai été perplexe de développer un contrôleur pour la commande de moteur et, en conséquence, un sujet pour l'article a été formé - aujourd'hui, je vais parler du processus de formation d'un PWM triphasé pour la commande de moteur, ainsi que d'expliquer les différences bénéfiques entre le TMS320F28 et d'autres contrôleurs tels que STM32F334, STM32G484, XMC4200 et autres.


En tant que stand, je vais utiliser le contrôleur en cours de développement, hélas, je ne peux pas parler de la partie en fer en détail. Cependant, si je dis que le contrôleur est construit sur la base du bundle TMS320F28027 + DRV8353RSRGZT, alors vous pouvez consulter la fiche technique du pilote et voir le concept général des circuits + il y a un débogage sur cette pierre et la conception de référence est ouverte dessus.


Pilote BLDC


En principe, sur le même type de circuits, il est possible de contrôler des moteurs BLDC qui "consomment" des niveaux de tension et des triphasés ordinaires, qui veulent déjà une sortie sinusoïdale. Je vais montrer les deux options, comme le chemin vers le sinus passe par la formation de niveaux de tension.


Oscillogramme numéro 1


Un peu de fer


La partie puissance du pilote se compose idéologiquement de 3 convertisseurs demi-pont, probablement tous les chastotniks et contrôleurs pour contrôler les moteurs BLDC dans tous les copters sont fabriqués de la même manière:


Pont triphasé


Une différence - je n'ai pas de redresseur d'entrée, car le contrôleur est initialement alimenté par une tension constante. La source d'alimentation dans mon cas est un assemblage de batteries Li-ion sous la forme de cellules 18650. Le pilote DRV8353RSRGZT utilisé peut contrôler seulement 3 demi-ponts de puissance, également dans la version utilisée de la pierre, il y a également des amplis opérationnels intégrés pour travailler avec des shunts comme capteurs de courant, intégrés dc / dc, qui peut digérer jusqu'à 70 ... 80V et tout cela est configuré de manière très flexible via SPI. Par exemple, il est très pratique de pouvoir régler le courant d'impulsion maximum de la commande du transistor.


Dans cette série, il existe également des pilotes avec un ensemble de fonctions différent, par exemple, avec un contrôle analogique et non SPI ou sans courant continu / courant continu intégré et sans ampli opérationnel. Pour le prix elles ne sont pas très différentes et j'ai pris les plus "hardies" comme vous l'avez probablement déjà compris. Tout cela est très beau, mais j'ai abordé de manière plutôt frivole la conception de la liaison du pilote et j'ai eu 2 problèmes importants. En fait, il n'y a qu'un seul problème - c'est une forte surchauffe:


Imageur thermique


Mais ce problème a été causé par 2 raisons. En fait, l'essence du problème est la surchauffe du conducteur lui-même. Sur le thermogramme, le driver est chargé avec un courant de 5A (pour lui c'est presque inactif) et rien que le driver et le MK lui-même sont un peu chauffés. Les transistors ne sont même pas visibles, ils ont une température PCB, à 5A il y a peu de pertes de chaleur.


  • Erreur n ° 1
    J'ai été incité par un de mes amis, honnêtement, j'aurais pensé à cela comme la dernière chose - le pilote a un courant continu / continu intégré, qui reçoit une entrée de 15 à 50 V et une sortie de 3,3 V pour alimenter le MK, la logique, les comparateurs et les amplificateurs opérationnels. Il semblerait que mes projets ont des micropuces LM5008 et LM5017 sous forme de micropuces séparées et j'ai calmement réduit 60V à ​​3,3V sans chauffage notable à un courant de 100-150 mA, mais tout s'est avéré plus délicat - l'efficacité globale du convertisseur s'est avérée être d'environ 65-70% à un courant 300 mA! Le fait est que le convertisseur lui-même peut fournir 3,3 V, mais l'efficacité sera faible, il est optimal de régler la tension de sortie 10-12-15V. Lorsque la sortie était de 12V 100 mA, mon pilote a pratiquement cessé de chauffer et l'efficacité a atteint un agréable 88%. La solution au problème est de baisser l'entrée 15 ... 50V à 12V avec le DC / DC intégré, puis de la baisser de 12V à 3,3V avec un DC / DC externe déjà bon marché.


  • Erreur n ° 2
    La deuxième erreur est plus évidente et la première chose que j'ai péché comme j'ai pu. Le fait est que pour les puces dans le paquet QFN, la chaleur principale est évacuée par le "ventre", elle repose généralement sur le GND et, à travers plusieurs vias (via), s'accroche au sol et toute la chaleur y va calmement. Au départ, je ne tenais pas compte de la faible efficacité du courant continu / continu intégré avec une grande différence de tension, donc cela ne me dérangeait pas que la goutte thermique ("ventre") s'accrochât à un polygone GND solide sur la couche intérieure, sur la couche extérieure, je n'avais pas de cuivre sous le ventre comme polygone GND En conséquence, il s'est avéré que ~ 0,5 W de chaleur est libéré sur la puce, et il se dissipe dans la couche interne de la carte, c'est-à-dire que l'efficacité est très médiocre. La solution au problème est que vous devez faire un test de terre sur la couche externe (couche inférieure) et ne pas le faire:

Circuit imprimé


En conséquence, dans la deuxième révision du fer, ces erreurs ont été corrigées: un convertisseur externe CC / CC 12-3,3 V a été ajouté et le polygone GND a en outre été rempli sur la couche inférieure et le tampon à puce a été planté dessus + le polygone de masse solide interne a été préservé. Après de telles améliorations, la température en fonctionnement continu est passée de +82 à +43 o C:


Thermogramme


Comme vous pouvez le voir, en raison de la réduction des pertes, la température a considérablement diminué dans les mêmes conditions, ainsi que la chaleur est maintenant répartie plus uniformément sur la zone de la carte et ne surchauffe localement ni le pilote ni le microcontrôleur. En principe, tout était en fer, rien de plus intéressant ne s'est produit et n'a fonctionné de manière stable. Par conséquent, ils peuvent recommander l'utilisation du pilote DRV8353 .


Mise en place d'un déphasage matériel de 120 o


Une caractéristique du réseau triphasé est que le courant dans les phases n'est pas synchrone, mais est décalé de 120 o par rapport au voisin. Quel est ce déphasage de 120 o en général? En termes simples, il s'agit d'un décalage du point de départ de la génération d'un tiers de la période. D'un point de vue mathématique, la période du signal est de , ce qui signifie que le deuxième signal doit être déplacé de 2π / 3 et le troisième de 4π / 3. D'un point de vue électronique, la période est fixée par le compte à rebours de notre temporisateur. Par exemple, lors d'un cadencement à 60 MHz, nous voulons obtenir un PWM avec une fréquence de 50 kHz, ce qui signifie que la période de compte à rebours sera de 0 à 1200 (60000000 Hz / 50000 Hz = 1200). Maintenant, pour obtenir 3 phases avec un décalage de 120 o, nous n'avons pas besoin de toucher la 1ère phase, d'ajouter +400 à la valeur actuelle pour la 2ème phase, d'ajouter +800 à la phase actuelle.


Si nous utilisons des microcontrôleurs sur le noyau du cortex, nous pouvons alors implémenter le décalage soit en écrivant une formule mathématique, soit en utilisant la synchronisation des événements. J'ai toujours été étonné que ST, NXP et d'autres n'aient pas simplement enregistré où la valeur de décalage serait écrite. Heureusement, TI l'a fait dans son TMS320F28xxx, pour régler le décalage, il suffit d'écrire un registre! Je ne vais pas vous expliquer pourquoi la solution logicielle n’est pas optimale, je dirai simplement qu’elle considère les formules MK pas très rapidement. La version avec synchronisation des événements est déjà plus adéquate et sur stm je ferais juste cela, mais cette option ne permet pas de changer la valeur de phase "à la volée", c'est-à-dire que pour certains ponts déphasés, seule la version logicielle reste. L'avantage est-il de pouvoir contrôler le matériel de phase? C'est à vous de décider, ma tâche est de vous dire que c'est possible. Pour moi, c'est un plus évident lorsque nous parlons de contrôler un entraînement électrique ou des onduleurs avec une sortie triphasée.


Configurons maintenant la génération de signaux PWM sous forme de 3 paires complémentaires avec temps mort et déphasage. Jusqu'ici sans sinus. J'utiliserai les paires suivantes: EPWM1A + EPWM1B, EPWM2A + EPWM2B et EPWM4A + EPWM4B. Ce sont les signaux qui vont du microcontrôleur au pilote.


  • Étape 1
    Il est nécessaire de configurer le multiplexeur GPIO à l'aide du registre GPAMUX pour fonctionner avec PWM et de désactiver les tractions de la sortie vers l'alimentation, de sorte que lorsque vous l'allumez, il n'y ait pas de log.1 sur toutes les jambes et les touches ne s'ouvrent pas. La protection actuelle sauvera certainement, mais il vaut mieux ne pas le faire. Il convient également de se rappeler que pour accéder aux registres de configuration, vous devez l'obtenir avec la commande EALLOW , puis réactiver la protection contre l'écrasement avec la commande EDIS .

void InitGPIOforPWM (void) { EALLOW; GpioCtrlRegs.GPAPUD.bit.GPIO0 = 1; // Disable pull-up on GPIO0 (EPWM1A) GpioCtrlRegs.GPAPUD.bit.GPIO1 = 1; // Disable pull-up on GPIO1 (EPWM1B) GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // Configure GPIO0 as EPWM1A GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // Configure GPIO1 as EPWM1B GpioCtrlRegs.GPAPUD.bit.GPIO2 = 1; // Disable pull-up on GPIO2 (EPWM2A) GpioCtrlRegs.GPAPUD.bit.GPIO3 = 1; // Disable pull-up on GPIO3 (EPWM2B) GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1; // Configure GPIO2 as EPWM2A GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1; // Configure GPIO3 as EPWM2B GpioCtrlRegs.GPAPUD.bit.GPIO6 = 1; // Disable pull-up on GPIO6 (EPWM4A) GpioCtrlRegs.GPAPUD.bit.GPIO7 = 1; // Disable pull-up on GPIO7 (EPWM4B) GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 1; // Configure GPIO6 as EPWM4A GpioCtrlRegs.GPAMUX1.bit.GPIO7 = 1; // Configure GPIO7 as EPWM4B EDIS; } 

  • Étape 2
    Configurez la génération du signal PWM. Il faut obtenir une fréquence de 50 kHz et un déphasage de 120 o . Dans ce cas, j'utilise le PWM habituel, car dans ce contrôleur il y a aussi HRPWM, il est important de s'en souvenir. Le module PWM est cadencé à la fréquence de base, c'est-à-dire 60 MHz, j'ai montré comment régler la fréquence PLL dans le premier article sur TMS320, je ne le répéterai pas, mais à la fin de l'article il y aura une archive avec le code et il sera possible d'y jeter un œil.

  void InitPWM (void) { // EPWM Module 1 config EPwm1Regs.TBPRD = 600; // Set priod EPwm1Regs.TBPHS.half.TBPHS = 0; // Set phase EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetrical mode EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Master enable EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down-stream module EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; EPwm1Regs.AQCTLA.bit.CAD = AQ_CLEAR; EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable dead-time module EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; // Active Hi complementary EPwm1Regs.DBFED = 20; // dead-time on 20 tick EPwm1Regs.DBRED = 20; // dead-time off 20 tick // EPWM Module 2 config EPwm2Regs.TBPRD = 600; EPwm2Regs.TBPHS.half.TBPHS = 400; // Set phase = 400/1200 * 360 = 120 deg EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Slave enable EPwm2Regs.TBCTL.bit.PHSDIR = TB_DOWN; // Count DOWN on sync (=120 deg) EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW; EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // sync flow-through EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; EPwm2Regs.AQCTLA.bit.CAD = AQ_CLEAR; EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; EPwm2Regs.DBFED = 20; EPwm2Regs.DBRED = 20; // EPWM Module 4 config EPwm4Regs.TBPRD = 600; EPwm4Regs.TBPHS.half.TBPHS = 400; EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; EPwm4Regs.TBCTL.bit.PHSEN = TB_ENABLE; EPwm4Regs.TBCTL.bit.PHSDIR = TB_UP; EPwm4Regs.TBCTL.bit.PRDLD = TB_SHADOW; EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; EPwm4Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm4Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm4Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; EPwm4Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; EPwm4Regs.AQCTLA.bit.CAU = AQ_SET; EPwm4Regs.AQCTLA.bit.CAD = AQ_CLEAR; EPwm4Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; EPwm4Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; EPwm4Regs.DBFED = 20; EPwm4Regs.DBRED = 20; } 

Maintenant, un peu plus en détail ... dans le registre TBPRD , écrivez la période, ou plutôt "période / 2", car le temporisateur est compté dans les deux sens, il s'avère que la période 600 correspond à la fréquence du signal PWM de sortie de 50 kHz en mode paire complémentaire. Dans le registre TBPHS, nous écrivons la valeur de phase par laquelle nous devons décaler, dans ce cas 400 sur 600, ce qui correspond à 2π / 3. Il est à noter que nous ne déplaçons pas la 1ère phase, donc pour cela le décalage est de 0, pour la 2ème phase le décalage est respectivement de 400, mais pour la 3ème phase, il semblerait logique d'écrire 800, mais 800 sur 600 d'une manière ou d'une autre pas vraiment ... donc ils écrivent le décalage non pas par rapport à la 1ère phase, mais par rapport à la précédente, c'est-à-dire la 2e. En conséquence, nous obtenons que dans la 3e phase, nous écrivons 400 et cela correspond à 2π / 3 entre la phase 2 et 3, et puisque la 2e est déjà décalée, alors entre les phases 1 et 3 il y aura "2π / 3 + 2π / 3 = 4π / 3 "et du point de vue électronique, tout semble logique.


Pour que les phases comprennent qui se déplace par rapport à qui, un patron est nécessaire, donc EPWM1 ​​est défini en utilisant le bit PHSEN en mode maître et EPWM2 et EPWM4, respectivement, en tant qu'esclaves. En utilisant les bits SYNCOSEL , le «point» de synchronisation est également défini, c'est-à-dire où lire le décalage. EPWM1 ​​est synchronisé avec le début de la minuterie, c'est-à-dire avec une période nulle, et EPWM2 et EPWM4 sont déjà synchronisés par rapport au front de signal du canal précédent: le canal précédent pour EPWM2 est EPWM1, et pour EPWM4 c'est EPWM2.


Il reste maintenant à activer des paires complémentaires et à définir la durée du temps mort. En utilisant les bits POLSEL , nous définissons un PWM non inverse, c'est-à-dire qu'en atteignant la valeur définie du comparateur (référence), un journal est généré à la sortie. 1. Dans OUT_MODE, nous définissons la génération de temps mort à la fois sur le bord et sur la chute du signal. En conséquence, dans les registres DBFED et DBRED, écrivez la durée du temps mort en ticks.


  • Étape 3
    Il reste maintenant à écrire la valeur du facteur d'utilisation dans le registre CMPA correspondant à chaque canal et vous pouvez observer le résultat.

  EPwm1Regs.CMPA.half.CMPA = 300; // duty for output EPWM1A EPwm2Regs.CMPA.half.CMPA = 300; // duty for output EPWM2A EPwm4Regs.CMPA.half.CMPA = 300; // duty for output EPWM4A 

PWM triphasé


Voila! Les sondes de l'oscilloscope sont connectées à la sortie du pilote. Le canal jaune est notre EPWM1, c'est-à-dire le maître. Le canal bleu est EPWM2 et il est décalé de 2π / 3 (ou 400 échantillons) par rapport au canal jaune, et le canal vert est décalé de 400 autres échantillons. On obtient ainsi 3 phases, où chaque phase est décalée de 120 o .


Transférons maintenant les sondes de l'oscilloscope de la sortie du pont de puissance aux signaux de commande qui sortent du microcontrôleur et vérifions le temps mort à l'intérieur de la paire complémentaire:


Oscillogramme numéro 2


Comme vous pouvez le voir, le temps mort réglé correspond au temps réel. La durée d'un échantillon est de 1/60 000 000 Hz = 16,6 ns et nous obtenons 20 échantillons, ce qui équivaut au temps mort 20,6 16 ns = 332 ns *, ce qui correspond approximativement à ce qui est observé sur l'oscillogramme.


En fait, où cela peut être utile, sous la forme actuelle. L'option la plus évidente est les convertisseurs dc / dc multiphasés, pour ceux qui souhaitent google le convertisseur dc / dc entrelacé . Il s'agit d'une solution technique extrêmement intéressante qui peut réduire considérablement la taille des inductances de puissance, réduire la capacité de sortie des condensateurs et également augmenter l'efficacité. Sur un simple TMS320F28027, vous pouvez implémenter un convertisseur 4 phases et tout cela sera très simplement implémenté dans le code et uniquement dans le matériel.


Nous générons une tension alternative triphasée


Dans de nombreux problèmes, il ne suffira pas d'obtenir des valeurs discrètes de 0 ou VCC à la sortie; une onde sinusoïdale est nécessaire. J'ai un article qui parle de la formation d'une tension alternative monophasée et la méthode "tabulaire" y est utilisée, c'est-à-dire que les valeurs de l'onde sinusoïdale ont été initialement calculées. En principe, cela peut également être fait pour la phase triphasée, mais je veux montrer une option alternative, à savoir le calcul de la valeur en douane en temps réel ou à la volée.


Il y a une caractéristique. La fréquence PWM dans ce cas est également de 50 kHz et le déphasage est réglé entre les périodes de ce signal. En conséquence, lorsque nous modulons une sinusoïde avec une fréquence de 50 Hz, le déphasage matériel est "perdu", il sera toujours présent entre les PWM, mais pas à l'intérieur de la sinusoïde, il faudra donc le faire par logiciel. La trigonométrie est une chose lourde pour le TMS320F28027, mais ce n'est pas très occupé avec moi, alors laissez-le compter. Si vous avez une tâche qui nécessite beaucoup de calculs, vous avez besoin d'un contrôleur avec TMU et FPU, par exemple, TMS320F280049, qui peut tourner les calculs beaucoup plus rapidement.


Pour charger les valeurs de devoir dans le PWM, nous avons besoin d'une minuterie, dont la période définira la fréquence d'échantillonnage. J'ai besoin d'une période de 20 ms (1 / 50Hz = 20 ms) et je vais prendre le nombre de pas dans une sinusoïde, disons 20, par conséquent, une interruption doit être générée avec une fréquence de 0,02 s / 20 = 0,001 ms = 1 kHz et dans cette interruption, j'écrirai la valeur dans le PWM . Pour plus de simplicité, je vais prendre un minuteur CPU0 normal et le configurer:


 void InitTimer0ForGenerator (void) { EALLOW; PieVectTable.TINT0 = &cpu_timer0_isr; EDIS; InitCpuTimers(); ConfigCpuTimer(&CpuTimer0, 60, 1000); CpuTimer0Regs.TCR.bit.TIE = 1; CpuTimer0Regs.TCR.bit.TSS = 0; IER |= M_INT1; PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // Enable TINT0 in the PIE: Group 1 interrupt 7 EINT; // Enable Global interrupt INTM ERTM; // Enable Global real-time interrupt DBGM } __interrupt void cpu_timer0_isr (void) { CpuTimer0.InterruptCount++; /* *   -  . ... */ PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge this interrupt to receive more interrupts from group 1 } 

Les fonctions InitCpuTimers et ConfigCpuTimer sont standard, tous les réglages y sont, il suffit de transférer la fréquence centrale (60 MHz) et la période de comptage en microsecondes (1000 μs = 1 ms), ce qui équivaut à 1 kHz, et nous en avions besoin. Alors, où dans la fonction de configuration, nous activons les interruptions et passons l'adresse du gestionnaire de notre interruption, où tout se passera.


Il faut maintenant "inventer" à nouveau la formule sinusoïdale, pour cela il faut avoir des connaissances en trigonométrie scolaire et c'est tout. Et donc ... nous avons une fonction y = sin (x) traçons cette fonction:


y = sin (x)


Comme vous pouvez le voir sur le graphique, l'amplitude de y varie de -1 à 1, mais nous voulons de 0 à 1, car avec une amplitude minimale, nous avons 0V, et avec un maximum (équivalent à 1), nous avons + VCC. Pour "dessiner" -1 ... + 1, nous avons besoin d'une nutrition bipolaire, mais ce n'est pas le cas. Vous devez déplacer le graphique dans une direction positive. Si nous le soulevons, il passera de 0 à +2, et nous ne pourrons que jusqu'à +1. Vous devez donc diviser par 2 et juste quelque chose! Commençons par diviser et tracer simplement pour y = (sin (x) / 2):


y = (sin (x) / 2)


Ouais! Maintenant, le graphique a une plage de -0,5 à +0,5, c'est-à-dire que l'amplitude est 1. C'est déjà mieux, mais nous ne nous sommes pas encore débarrassés des valeurs négatives, nous allons donc simplement augmenter le graphique de 0,5, pour cela nous avons juste besoin d'ajouter cette valeur au résultat et d'obtenir la formule y = 0,5 + (sin (x) / 2) et tracez le graphique de cette fonction:


y = 0,5 + (sin (x) / 2)


Maintenant, tout est devenu absolument parfait: la sinusoïde a une amplitude de 0 à 1, les valeurs négatives sont absentes. La formule y = 0,5 + (sin (x) / 2) décrit la 1ère phase, il est maintenant nécessaire d'ajouter un déphasage pour obtenir les phases 2 et 3. Pour ce faire, soustrayez respectivement 2π / 3 et 4π / 3 de x et obtenez les formules pour le reste phases y = 0,5 + (sin (x-2π / 3) / 2) et y = 0,5 + (sin (x-4π / 3) / 2). Nous construisons 3 graphiques et voyons si cela ressemble à la vérité:


3 phases


Pas mal! L'image est similaire à ce qui est généralement peint dans les manuels de génie électrique lorsqu'ils parlent d'un réseau triphasé ou de moteurs asynchrones. Soit dit en passant, 2,0943 est 2π / 3 et 4,1866 est 4π / 3, respectivement, je viens de les compter tout de suite et ils apparaissent dans mon code. Au total, nous avons 3 équations:


  • Phase A - y = 0,5 + (sin (x) / 2)
  • Phase B - y = 0,5 + (sin (x-2π / 3) / 2)
  • Phase C - y = 0,5 + (sin (x-4π / 3) / 2)

Du côté des mathématiques, tout semble simple et clair, mais maintenant vous devez l'adapter aux réalités des microcontrôleurs. Notre onde sinusoïdale n'est pas analogique, mais a des "pas", c'est-à-dire qu'elle est discrète, car nous ne pouvons régler que la tension ou 0V ou + 15V (VCC) dans mon cas. Plus tôt, j'ai écrit que j'aurais 20 étapes, donc pour 1 période j'aurais 20 calculs.


Tout d'abord, décidons quoi remplacer x . La période de notre sinusoïde est de , ce qui signifie que le pas d'échantillonnage sera de 2π / 20 . Par conséquent, la sinusoïde sera constituée de 20 points, comme si nous construisions un graphique sur les points, et approximativement entre eux. Par conséquent, la valeur dans la première étape sera sin (2π * (1/20), dans la deuxième étape sin (2π * (2/20)), dans la troisième étape * sin (2π (3/20)) et ainsi de suite, lorsque nous S'il atteint 20/20 , cela signifiera la fin de la période et il faudra recommencer le comptage. Sur la base des données reçues, corrigeons les formules:


  • Phase A - y = 0,5 + (sin (2π * (n / N)) / 2)
  • Phase B - y = 0,5 + (sin (2π * (n / N) -2π / 3) / 2)
  • Phase C - y = 0,5 + (sin (2π * (n / N) -4π / 3) / 2)

Maintenant, nous considérons maintenant la valeur du sinus à chaque point spécifique du graphique. Par conséquent, n est l'étape actuelle, N est l'étape totale (20). Après ces formules, nous obtenons une valeur de 0 à 1, mais en réalité nous ne fonctionnons pas avec une amplitude abstraite. L'amplitude dans notre cas dépend du rapport cyclique, car le devoir varie de 0 à 600 (à partir des paramètres PWM), puis 0 est 0 et 1 équivaut à 600. Sur cette base, recalculons-le dans une formule réelle pour obtenir la valeur qui sera chargée dans le registre PWM CMPA:


  • Phase A - devoir1 = A (0,5 + (sin (2π (n / N)) / 2))
  • Phase B - devoir2 = A (0,5 + (sin (2π (n / N) -2π / 3) / 2))
  • Phase C - devoir4 = A (0,5 + (sin (2π (n / N) -4π / 3) / 2))

Par conséquent, A est la valeur maximale de l'amplitude, c'est-à-dire 600, n est le pas actuel, N est le nombre total de pas (20). Les valeurs de duty1, duty2, duty4 sont les valeurs réelles converties du facteur de devoir, qui est chargé dans l' ACPM. Écrivons maintenant le code du gestionnaire d'interruption mis à jour et déclarons toutes les variables nécessaires:


 float activeStep = 0.0; float amplitude = 600.0; float allStep = 20.0; const float pi = 3.1415; // π const float piTwo = 6.2831; // 2π const float phaseShifted120deg = 2.0943; // 2π/3 const float phaseShifted240deg = 4.1866; // 4π/3 __interrupt void cpu_timer0_isr (void) { if (activeStep >= allStep) {activeStep = 0;} activeStep++; EPwm1Regs.CMPA.half.CMPA = ((uint16_t)(amplitude * (0.5 + (sinf(piTwo * (activeStep / allStep)) / 2)))); EPwm2Regs.CMPA.half.CMPA = ((uint16_t)(amplitude * (0.5 + (sinf(piTwo * (activeStep / allStep) - phaseShifted120deg) / 2)))); EPwm4Regs.CMPA.half.CMPA = ((uint16_t)(amplitude * (0.5 + (sinf(piTwo * (activeStep / allStep) - phaseShifted240deg) / 2)))); PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge this interrupt to receive more interrupts from group 1 } 

Le code, comme vous le voyez, est le plus simple, si vous comprenez ce qu'il fallait faire et les mathématiques simples dans le problème à résoudre. Chaque fois que l'interruption est appelée, nous incrémentons la variable activeStep , qui contient le numéro d'étape, elle passe de 0 à 20 puis est réinitialisée. Il s'avère qu'en une période, nous effectuons 20 étapes et 20 calculs pour chaque phase. Afin de ne pas compter tout le temps 2π / 3 et 4π / 3 dans la formule, je les ai comptés tout de suite pour les utiliser comme constantes.


Les calculs se sont avérés minimum, pour ce MK ce n'est absolument rien. Si vous le souhaitez, le nombre de points peut être considérablement augmenté, par exemple jusqu'à 200. Tout dépend de la tâche. La modification de la fréquence PWM se produit en modifiant la fréquence d'appel d'interruption et le nombre d'étapes. Vous pouvez également modifier l' amplitude variable et modifier la tension à la sortie du convertisseur de puissance.


Après avoir téléchargé le code sur le microcontrôleur, vous obtiendrez l'image correspondante:


Oscillogramme numéro 1


Si vous étirez le graphique le long de Y , il devient préférable de voir les défauts du signal. Ceci est une conséquence du petit nombre d'étapes d'échantillonnage, une règle conditionnelle s'applique: plus il y a de points, plus le signal est beau.


Oscillogramme numéro 3


Conclusion


Aujourd'hui, j'ai parlé du processus de formation du déphasage dans les systèmes polyphasiques, en principe, il n'y a rien de compliqué, en particulier lors de l'utilisation du TMS320F28. Le reste dépend des algorithmes, en principe, sur Internet, il existe de nombreux articles où le contrôle de la mastication et les moteurs sans balais, et asynchrones et toutes sortes d'autres, vous ne pouvez que changer la logique.


J'espère que ce matériel sera utile et pas particulièrement ennuyeux à lire. Comme toujours, la source est jointe:


Archiver avec le projet pour Code Composer Studio

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


All Articles