Geração de sinal PWM multifásico no TMS320F28027

Era uma vez em uma galáxia distante e distante Escrevi um pequeno artigo sobre o controlador Piccolo especializado da Texas Instruments, projetado para controlar conversores de energia e acionamentos elétricos. Esses controladores são ferramentas de desenvolvimento muito poderosas em muitas tarefas e eu queria escrever algo mais sobre eles ... simples e útil.


Recentemente, fiquei intrigado ao desenvolver um controlador para controle de motor e, consequentemente, um tópico para o artigo foi formado - hoje vou falar sobre o processo de formação de um PWM trifásico para controle de motor, além de explicar as diferenças benéficas entre o TMS320F28 e outros controladores, como STM32F334, STM32G484, XMC4200 e outros.


Como suporte, usarei o controlador em desenvolvimento, infelizmente, não posso falar sobre a peça de ferro em detalhes. No entanto, se eu disser que o controlador é baseado no pacote TMS320F28027 + DRV8353RSRGZT, você pode olhar para os dados do driver e ver o conceito geral de circuitos + há depuração nessa pedra e o design de referência está aberto nela.


Driver BLDC


Em princípio, no mesmo tipo de circuito, é possível controlar motores BLDC que "consomem" níveis de tensão e trifásicos comuns, que já desejam uma saída sinusoidal. Vou mostrar as duas opções, como o caminho para o seno reside na formação de níveis de tensão.


Oscilograma número 1


Um pouco sobre ferro


A parte de potência do driver consiste ideologicamente em 3 conversores de meia ponte, provavelmente todos os chastotniks e controladores para controlar os motores BLDC em todos os helicópteros, de forma semelhante:


Ponte trifásica


Uma diferença - eu não tenho um retificador de entrada, porque o controlador é alimentado inicialmente por uma tensão constante. A fonte de energia no meu caso é um conjunto de baterias de íon de lítio na forma de células 18650. O driver DRV8353RSRGZT usado pode controlar apenas 3 meias-pontes de energia, também na versão usada da pedra também existem amplificadores operacionais integrados para trabalhar com derivações como sensores de corrente, embutidos dc / dc, que pode digerir até 70 ... 80V e tudo isso é configurado de maneira muito flexível via SPI. Por exemplo, é muito conveniente poder ajustar a corrente máxima de pulso do controle do transistor.


Também nesta série existem drivers com um conjunto diferente de funções, por exemplo, existem com controle analógico, não SPI ou sem dc / dc embutido e sem amplificador operacional. Pelo preço, eles não são muito diferentes e eu peguei o mais "ousado", como você provavelmente já entendeu. Essa coisa toda parece muito bonita, mas eu me aproximei frivolamente do design da ligação do driver e consegui dois problemas significativos. De fato, existe apenas um problema - esse é um superaquecimento forte:


Termovisor


Mas esse problema foi causado por 2 razões. Na verdade, a essência do problema é o superaquecimento do próprio driver. No termograma, o motorista é carregado com uma corrente de 5A (para ele está quase ociosa) e nada além do motorista e do próprio MK é aquecido um pouco. Os transistores nem são visíveis, eles têm uma temperatura de PCB, em 5A há escassas perdas de calor.


  • Erro nº 1
    Fui solicitado por um amigo meu, sinceramente, eu pensaria nisso como a última coisa - o driver possui um dc / dc interno, que recebe 15 ... 50V de entrada e produz 3,3V para alimentar o MK, lógica, comparadores e amplificadores operacionais. Parece que meus projetos têm microchips LM5008 e LM5017 na forma de microchips separados e eu reduzi calmamente 60V a 3,3V sem aquecimento perceptível a uma corrente de 100-150 mA, mas tudo ficou mais complicado - a eficiência geral do conversor acabou sendo de 65 a 70% a uma corrente 300 mA! O fato é que o próprio conversor pode fornecer 3,3V, mas a eficiência será escassa; é ideal definir a tensão de saída 10-12-15V. Quando a saída era de 12V a 100 mA, meu motorista parou de aquecer praticamente e a eficiência atingiu 88% agradáveis. A solução para o problema é abaixar a entrada de 15 ... 50V a 12V com a CC / CC incorporada e depois abaixar de 12V a 3,3V com uma CC / CC externa já barata.


  • Erro nº 2
    O segundo erro é mais óbvio e a primeira coisa que eu pequei nele quanto pude. O fato é que, para os chips do pacote QFN, o calor principal é removido através da "barriga", geralmente fica no GND e, por várias vias (via), se agarra ao chão e todo o calor vai para lá com calma. Inicialmente, não levei em conta a escassa eficiência do dc / dc embutido com uma grande diferença de tensão, por isso não me incomodou que a queda térmica ("ventre") se agarrasse a um polígono GND sólido na camada interna, na camada externa não havia cobre sob o ventre como polígono GND Como resultado, verificou-se que ~ 0,5 W de calor são liberados no chip e se dissipam na camada interna da placa, ou seja, a eficiência é muito baixa. A solução para o problema é que você precisa fazer um teste de aterramento na camada externa (camada inferior) e não fazer isso:

Placa de circuito


Como resultado, na segunda revisão do ferro, esses erros foram corrigidos: um conversor externo dc / dc 12-3.3V foi adicionado e o polígono GND foi adicionalmente preenchido na camada inferior e o chip pad foi plantado nele + o polígono interno sólido foi preservado. Após essas melhorias, a temperatura em operação contínua diminuiu de +82 para +43 o C:


Termograma


Como você pode ver, devido à redução de perdas, a temperatura diminuiu significativamente nas mesmas condições, assim como o calor agora é distribuído de maneira mais uniforme na área da placa e não superaquece localmente o driver ou o microcontrolador. Em princípio, tudo era de ferro, nada mais interessante aconteceu e funcionou de forma estável. Como resultado, eles podem recomendar o uso do driver DRV8353 .


Implementação de uma mudança de fase de hardware de 120 o


Uma característica da rede trifásica é que a corrente nas fases não é síncrona, mas é deslocada em 120 o em relação à rede vizinha. O que é essa mudança de fase de 120º em geral? Em termos simples, essa é uma mudança do ponto inicial da geração em 1/3 do período. Do ponto de vista matemático, o período do sinal é , o que significa que o segundo sinal deve ser movido por 2π / 3 e o terceiro por 4π / 3. Do ponto de vista eletrônico, o período é definido pelo período de contagem regressiva do nosso timer. Por exemplo, ao cronometrar em 60 MHz, queremos obter um PWM com uma frequência de 50 kHz, o que significa que o período de contagem regressiva do temporizador será de 0 a 1200 (60 000 000 Hz / 50 000 Hz = 1200). Agora, para obter 3 fases com um deslocamento de 120 o, não precisamos tocar na 1ª fase, adicionar +400 ao valor atual da 2ª fase, adicionar +800 à fase atual.


Se usarmos microcontroladores no núcleo do córtex, podemos implementar a mudança escrevendo uma fórmula matemática ou usando a sincronização de eventos. Sempre foi incrível para mim por que ST, NXP e outros não apenas registravam onde o valor do turno seria gravado. Felizmente, a TI fez isso no seu TMS320F28xxx, para definir a mudança, basta escrever um registro! Não vou explicar por que a solução de software não é ótima, apenas direi que considera as fórmulas MK não muito rapidamente. O profissional com sincronização de eventos já é mais adequado e, no stm, eu faria exatamente isso, mas essa opção não permite alterar o valor da fase em tempo real, ou seja, para alguma ponte de fase deslocada novamente, apenas a versão do software permanece. A vantagem da capacidade de controlar o hardware da fase? Cabe a você decidir, minha tarefa é dizer que é possível. Para mim, essa é uma vantagem óbvia quando falamos em controlar um acionamento elétrico ou inversor de tensão com uma saída trifásica.


Agora vamos configurar a geração de sinais PWM na forma de 3 pares complementares com tempo morto e mudança de fase. Até agora sem um seno. Utilizarei os seguintes pares: EPWM1A + EPWM1B, EPWM2A + EPWM2B e EPWM4A + EPWM4B. Estes são os sinais que vão do microcontrolador para o driver.


  • Etapa 1
    É necessário configurar o multiplexador GPIO usando o registro GPAMUX para trabalhar com o PWM e desativar os pull-ups da saída da fonte de alimentação, para que, quando você a ligue, não exista um log.1 em todas as pernas e as teclas não sejam abertas. A proteção atual certamente salvará, mas é melhor não fazer isso. Também é importante lembrar que, para acessar os registros de instalação, é necessário obtê-lo com o comando EALLOW e, em seguida, reativar a proteção contra substituição com o comando 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; } 

  • Etapa 2
    Configure a geração do sinal PWM. É necessário obter uma frequência de 50 kHz e uma mudança de fase de 120 o . Nesse caso, eu uso o PWM usual, porque neste controlador também há HRPWM, é importante lembrar disso. O módulo PWM é com freqüência na freqüência central, ou seja, 60 MHz, mostrei como definir a frequência PLL no primeiro artigo no TMS320, não repetirei, mas no final do artigo haverá um arquivo com o código e será possível espiar lá.

  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; } 

Agora, um pouco mais detalhadamente ... no registro TBPRD, escrevemos o período, ou melhor, "período / 2", porque Se considerarmos o temporizador em ambas as direções, verifica-se que o período 600 corresponde à frequência do sinal PWM de saída de 50 kHz no modo de par complementar. No registro TBPHS, escrevemos o valor da fase pelo qual precisamos mudar, neste caso 400 de 600, o que corresponde a 2π / 3. Vale a pena notar que não estamos movendo a 1ª fase, portanto, para o turno é 0, para o 2º estágio o turno é de 400, respectivamente, mas para o 3º estágio pareceria lógico escrever 800, mas 800 de 600 de alguma forma não realmente ... portanto, eles escrevem a mudança não em relação à 1ª fase, mas em relação à anterior, ou seja, a 2ª. Como resultado, obtemos que na 3ª fase escrevemos 400 e isso corresponde a 2π / 3 entre as fases 2 e 3, e como a 2ª já está deslocada, entre as fases 1 e 3 haverá "2π / 3 + 2π / 3 = 4π / 3 "e do ponto de vista da eletrônica tudo parece lógico.


Para que as fases entendam quem está se movendo em relação a quem, é necessário um chefe, portanto, o EPWM1 ​​é configurado usando o bit PHSEN no modo mestre, e EPWM2 e EPWM4, respectivamente, como escravos. Usando os bits SYNCOSEL , o “ponto” de sincronização também é definido, ou seja, de onde ler a mudança. O EPWM1 ​​é sincronizado com o início do temporizador, ou seja, com período zero, e o EPWM2 e o EPWM4 já estão sincronizados em relação à borda do sinal do canal anterior: o canal anterior para o EPWM2 é o EPWM1 ​​e para o EPWM4 é o EPWM2.


Agora resta ativar pares complementares e definir a duração do tempo morto. Utilizando os bits POLSEL , definimos um PWM não inverso, ou seja, ao atingir o valor definido do comparador (referência), um log é gerado na saída. 1. Em OUT_MODE, configuramos a geração de tempo morto na borda e na queda do sinal. Assim, nos registros DBFED e DBRED, escreva a duração do tempo morto em ticks.


  • Etapa 3
    Agora resta escrever o valor do fator de serviço no registro CMPA correspondente a cada canal e você pode observar o resultado.

  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 trifásico


Voila! As pontas de prova do osciloscópio estão conectadas à saída do driver. O canal amarelo é o nosso EPWM1, ou seja, o mestre. O canal azul é EPWM2 e é deslocado 2π / 3 (ou 400 amostras) em relação ao canal amarelo, e o canal verde é deslocado outras 400 amostras. Assim, temos 3 fases, onde cada fase é deslocada em 120 o .


Agora vamos transferir as pontas de prova do osciloscópio da saída da ponte de energia para os sinais de controle que saem do microcontrolador e verificar se há tempo morto dentro do par complementar:


Oscilograma número 2


Como você pode ver, o tempo morto definido corresponde ao tempo real. A duração de uma amostra é de 1 / 60.000.000 Hz = 16,6 ns e obtemos 20 amostras, o que equivale ao tempo morto 20,6 16 ns = 332 ns *, que é aproximadamente o que é observado no oscilograma.


Na verdade, onde isso pode ser útil, da forma que é agora. A opção mais óbvia são os conversores multifásicos dc / dc, para aqueles interessados ​​em pesquisar no conversor intercalado dc / dc . Esta é uma solução técnica extremamente interessante que pode reduzir significativamente o tamanho das indutâncias de potência, reduzir a capacitância de saída dos capacitores e também aumentar a eficiência. Em um simples TMS320F28027, você pode implementar um conversor de 4 fases e tudo isso será implementado com muita simplicidade no código e apenas no hardware.


Geramos uma tensão alternada trifásica


Em muitos problemas, não será suficiente obter valores discretos de 0 ou VCC na saída; é necessária uma onda senoidal. Eu tenho um artigo que fala sobre a formação de uma tensão alternada monofásica e o método "tabular" é usado lá, ou seja, os valores para a onda senoidal foram inicialmente calculados. Em princípio, isso também pode ser feito para a fase trifásica, mas quero mostrar uma opção alternativa, a saber, o cálculo do valor do imposto em tempo real ou em tempo real.


Há um recurso. A frequência PWM neste caso também é de 50 kHz e a mudança de fase é definida entre os períodos desse sinal. Assim, quando modulamos um sinusóide com uma frequência de 50 Hz, a mudança de fase do hardware será "perdida", ela ainda estará presente entre os PWMs, mas não dentro do sinusóide, portanto, será necessário realizar um software. A trigonometria é uma coisa pesada para o TMS320F28027, mas não está muito ocupada comigo, então conte. Se você possui uma tarefa que exige muitos cálculos, precisa de um controlador com TMU e FPU, por exemplo, TMS320F280049, que pode tornar a matemática muito mais rápida.


Para carregar os valores de serviço no PWM, precisamos de um temporizador, cujo período definirá a frequência de amostragem. Preciso de um período de 20 ms (1 / 50Hz = 20 ms) e tomo o número de etapas em um sinusóide, digamos 20, como resultado, uma interrupção deve ser gerada com uma frequência de 0,02 s / 20 = 0,001 ms = 1 kHz e nessa interrupção vou escrever o valor no PWM . Para simplificar, vou pegar um cronômetro CPU0 regular e configurá-lo:


 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 } 

As funções InitCpuTimers e ConfigCpuTimer são padrão, todas as configurações estão nelas, basta transferir a frequência do núcleo (60 MHz) e o período de contagem em microssegundos (1000 μs = 1 ms), equivalente a 1 kHz, e precisávamos disso. Então, onde na função de configuração habilitamos interrupções e passamos o endereço do manipulador da nossa interrupção, onde tudo vai acontecer.


Agora é necessário "inventar" a fórmula senoidal novamente, para isso você precisa ter conhecimento de trigonometria escolar e isso é tudo. E então ... nós temos uma função y = sin (x), vamos traçar esta função:


y = pecado (x)


Como você pode ver no gráfico, a amplitude de y varia de -1 a 1, mas queremos de 0 a 1, porque com uma amplitude mínima, temos 0V e, com um máximo (equivalente a 1), temos + VCC. Para "desenhar" -1 ... + 1, precisamos de nutrição bipolar, mas não é. Você precisa mudar o gráfico em uma direção positiva. Se apenas levantarmos, ele passará de 0 a +2 e só podemos receber +1. Então você precisa dividir por 2 e apenas algo! Vamos começar simplesmente dividindo e plotando para y = (sin (x) / 2):


y = (sen (x) / 2)


Sim! Agora, o gráfico tem um intervalo de -0,5 a +0,5, ou seja, a amplitude é 1. Já é melhor, mas ainda não nos livramos dos valores negativos, então vamos mudar o gráfico para 0,5, para isso, basta adicionar esse valor ao resultado e obter a fórmula y = 0,5 + (sin (x) / 2) e plote o gráfico para esta função:


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


Agora tudo se tornou absolutamente perfeito: o senoide tem uma amplitude de 0 a 1, valores negativos estão ausentes. A fórmula y = 0,5 + (sin (x) / 2) descreve a 1ª fase, agora é necessário adicionar uma mudança de fase para obter as fases 2 e 3. Para fazer isso, subtraia 2π / 3 e 4π / 3 de x, respectivamente, e obtenha as fórmulas para as demais fases y = 0,5 + (sin (x-2π / 3) / 2) e y = 0,5 + (sin (x-4π / 3) / 2). Construímos 3 gráficos e verificamos se parece com a verdade:


3 fases


Nada mal! A imagem é semelhante à que geralmente é pintada nos livros didáticos de engenharia elétrica quando eles falam sobre uma rede trifásica ou motores assíncronos. A propósito, 2.0943 é 2π / 3 e 4.1866 é 4π / 3, respectivamente, apenas contei-os imediatamente e eles aparecem no meu código. Total, temos 3 equações:


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

Por parte da matemática, tudo parece ser simples e claro, mas agora precisa ser adaptado às realidades do microcontrolador. Nossa onda senoidal não é analógica, mas possui "etapas", ou seja, é discreta, pois podemos definir apenas tensão ou 0V ou + 15V (VCC) no meu caso. Escrevi anteriormente que terei 20 etapas, então por 1 período terei 20 cálculos.


Primeiro, vamos decidir o que substituir por x . O período do nosso sinusóide é , o que significa que a etapa de amostragem será 2π / 20 . Consequentemente, o sinusóide consistirá em 20 pontos, como se estivéssemos construindo um gráfico sobre os pontos, e aproximados entre eles. Como resultado, o valor no primeiro passo será sin (2π * (1/20), no segundo passo sin (2π * (2/20)), no terceiro passo * sin (2π (3/20)) e assim por diante, quando Se atingir 20/20 , isso significa o final do período e será necessário começar a contar novamente.Com base nos dados recebidos, vamos corrigir as fórmulas:


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

Agora, agora consideramos o valor do seno em cada ponto específico do gráfico. Consequentemente, n é o passo atual, N é o passo total (20). Após essas fórmulas, obtemos um valor de 0 a 1, mas, na realidade, não estamos operando com uma amplitude abstrata. A amplitude no nosso caso depende do ciclo de trabalho, porque o dever muda de 0 a 600 (nas configurações do PWM), então 0 é 0 e 1 é equivalente a 600. Com base nisso, vamos recalculá-lo em uma fórmula real para obter o valor que será carregado no registro do CMPA PWM :


  • Fase A - dever1 = A (0,5 + (sin (2π (n / N)) / 2))
  • Fase B - dever2 = A (0,5 + (sin (2π (n / N) -2π / 3) / 2))
  • Fase C - dever4 = A (0,5 + (sin (2π (n / N) -4π / 3) / 2))

Por conseguinte, A é o valor máximo da amplitude, ou seja, 600, n é o passo atual, N é o número total de passos (20). Os valores de dever1, dever2, dever4 são os valores reais convertidos do fator de dever, carregados no CMPA. Agora vamos escrever o código para o manipulador de interrupções atualizado e declarar todas as variáveis ​​necessárias:


 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 } 

O código, como você vê, é o mais simples, se você entender o que era necessário fazer e a matemática simples no problema que está sendo resolvido. Cada vez que a interrupção é chamada, incrementamos a variável activeStep , que contém o número da etapa, ela muda de 0 a 20 e depois é redefinida. Acontece que em um período realizamos 20 etapas e 20 cálculos para cada fase. Para não contar 2π / 3 e 4π / 3 na fórmula o tempo todo, contei-os imediatamente para serem usados ​​como constantes.


Os cálculos foram mínimos, para este MK não é absolutamente nada. Se desejado, o número de pontos pode ser aumentado significativamente, por exemplo, até 200. Tudo depende da tarefa. A alteração da frequência PWM ocorre alterando a frequência da chamada de interrupção e o número de etapas. Você também pode alterar a amplitude variável e a tensão na saída do conversor de potência.


Depois de baixar o código para o microcontrolador, você obterá a imagem correspondente:


Oscilograma número 1


Se você esticar o gráfico ao longo de Y , será melhor ver os defeitos do sinal. Isso é uma conseqüência do pequeno número de etapas de amostragem; uma regra condicional se aplica: quanto mais pontos, mais bonito o sinal.


Oscilograma número 3


Conclusão


Hoje falei sobre o processo de formação de mudança de fase em sistemas multifásicos, em princípio, não há nada complicado, principalmente quando se usa o TMS320F28. O resto depende dos algoritmos, em princípio, na Internet, existem muitos artigos em que controle de mastigação e motores sem escova, além de assíncrono e de todos os tipos, você só pode mudar a lógica.


Espero que este material seja útil e não particularmente chato de ler. Como sempre, a fonte está anexada:


Arquivar com o projeto para o Code Composer Studio

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


All Articles