motorcontroldemo_035/Vsrc/V_PWM_Module.c
Dmitry Shpak a99491f9b8 Основные обновления в данном коммите:
- проект переведён на VectorIDE v1.3

В целях экономии памяти удалены:
 - модуль управления светодиодами
 - модуль ШИМ для двигателей SRD
 - модуль часов реального времени
 - режим привода для измерения задержки меджу сигналами ШИМ и измерениями токов

Добавлены следующие модули:
 - проект переведён на VectorIDE v1.3
 - модуль SPI для абсолютного ДПР
 - модуль управление реле для заряда ЗПТ
 - модуль дискретных вводов-выводов
 - модуль управления вентилятором Одноплатного Инвертора
 - модуль тормозного резистора Одноплатного Инвертора

Прочие изменения:
 - оптимизирована инициализация регистров периферии
 - удалено множество неиспользуемых переменных
 - разрешение работы всех GPIO перенесено в функцию "PeripheralClockEnable"
 - добавлен счётчик индексной метки энкодера
 - исправлен сброс прерываний модуля захвата CAP
 - переработан режим задания постоянного тока статора
- исправлены прочие мелкие ошибки в разных модулях
2021-12-01 13:54:14 +03:00

611 lines
21 KiB
C

/*!
Copyright 2017 ÀÎ "ÍÈÈÝÒ" è ÎÎÎ "ÍÏÔ ÂÅÊÒÎÐ"
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
\file V_PWM_Module.c
\brief Ìîäóëü ðåàëèçàöèè âåêòîðíîé ØÈÌ (ñì. TPWM_Module)
\author ÎÎÎ "ÍÏÔ Âåêòîð". http://motorcontrol.ru
\version v 2.0 25/03/2016
\addtogroup V_PWM_Module
@{*/
#include "V_IQmath.h"
#include "V_PWM_Module.h"
#include "main.h"
//! Èíèöèàëèçàöèÿ
//! \memberof TPWM_Module
void PWM_Module_Init(TPWM_Module *p) {
SIU->PWMSYNC_bit.PRESCRST = 0; //ñèíõðîíèçàöèÿ òàéìåðîâ - ñáðîñ âíóòðåííèõ ñ÷åò÷èêîâ
// Íàñòðîéêà ïåðèîäà
if (p->Frequency < PWM_FREQ_MIN)
p->Frequency = PWM_FREQ_MIN;
if (p->Frequency > PWM_FREQ_MAX)
p->Frequency = PWM_FREQ_MAX;
PWM0->TBPRD = _IQ10div(_IQ10(SystemCoreClock/1000.0), p->Frequency << 1) >> 10; //ïåðèîä
p->k_pwm = PWM0->TBPRD;
p->FreqPrev = p->Frequency; //ïðåäûäóùàÿ ÷àñòîòà
// ------------------------------------------------------------------------
// Íàñòðàèâàåì ìîäóëü ePWM0
// ------------------------------------------------------------------------
PWM0->TBPHS_bit.TBPHS = 0x0000; // Phase is 0
PWM0->TBCTR = 0x0000; // Clear counter
// Íàñòðîéêà ñ÷¸ò÷èêà. â êîììåíòàðèè ðàñïèñàíî ïî ïîëÿì, íî äëÿ óñêîðåíèÿ âñ¸ ãðóçèòñÿ çà îäèí ðàç
//PWM0->TBCTL_bit.PRDLD = TB_SHADOW; // Çàãðóçêà TBPRD ïðè TBCTR = 0
//PWM0->TBCTL_bit.CTRMODE = TB_COUNT_UPDOWN; // Ñ÷¸ò ââåðõ-âíèç
//PWM0->TBCTL_bit.PHSEN = TB_DISABLE; // Íå ñèíõðîíèçèðîâàòü ýòîò òàéìåð íè ñ ÷åì
//PWM0->TBCTL_bit.HSPCLKDIV = 0; // Ïåðâûé äåëèòåëü ÷àñòîòû (íåò äåëåíèÿ)
//PWM0->TBCTL_bit.CLKDIV = 0; // Âòîðîé äåëèòåëü ÷àñòîòû (íåò äåëåíèÿ)
//PWM0->TBCTL_bit.SYNCOSEL = TB_CTR_ZERO; // Âûäà¸ì ñèíõðî-ñèãíàë ïðè TBCTR = 0
//PWM0->TBCTL_bit.FREESOFT = 2; // Ïðîäîëæàòü ñ÷¸ò ïðè äåáàæíîì îñòàíîâå ïðîöåññîðà
//PWM0->TBCTL_bit.SHADOWGLOB = 1; // Ðàçðåøèòü íîðìàëüíóþ ðàáîòó òåíåâûõ ðåãèñòðîâ
PWM0->TBCTL = (TB_SHADOW << PWM_TBCTL_PRDLD_Pos) |
(TB_COUNT_UPDOWN << PWM_TBCTL_CTRMODE_Pos) |
(TB_DISABLE << PWM_TBCTL_PHSEN_Pos) |
(0 << PWM_TBCTL_HSPCLKDIV_Pos) |
(0 << PWM_TBCTL_CLKDIV_Pos) |
(TB_CTR_ZERO << PWM_TBCTL_SYNCOSEL_Pos) |
(2 << PWM_TBCTL_FREESOFT_Pos) |
(1 << PWM_TBCTL_SHDWGLOB_Pos);
// Íàñòðîéêà òåíåâûõ çàãðóçîê ðåãèñòðîâ
//PWM0->CMPCTL_bit.SHDWAMODE = CC_SHADOW; // Èñïîëüçîâàòü òåíåâîé ðåãèñòð äëÿ CMPA
//PWM0->CMPCTL_bit.LOADAMODE = CC_CTR_ZERO; // Çàãðóæàòü â àêòèâíûé èç òåíåâîãî ïî íóëþ ñ÷¸ò÷èêà
//PWM0->CMPCTL_bit.SHDWBMODE = CC_SHADOW; // Èñïîëüçîâàòü òåíåâîé ðåãèñòð äëÿ CMPB
//PWM0->CMPCTL_bit.LOADBMODE = CC_CTR_ZERO; // Çàãðóæàòü â àêòèâíûé èç òåíåâîãî ïî íóëþ ñ÷¸ò÷èêà
PWM0->CMPCTL = (CC_SHADOW << PWM_CMPCTL_SHDWAMODE_Pos) |
(CC_CTR_ZERO << PWM_CMPCTL_LOADAMODE_Pos) |
(CC_SHADOW << PWM_CMPCTL_SHDWBMODE_Pos) |
(CC_CTR_ZERO << PWM_CMPCTL_LOADBMODE_Pos);
// Îáíóëåíèå óñòàâêè ñðàâíåíèÿ
PWM0->CMPA_bit.CMPA = 0; // Set compare A value
// Íàñòðîéêà äåéñòâèé ïðè ñðàâíåíèè ñ÷¸ò÷èêà ñ óñòàâêàìè
//PWM0->AQCTLA_bit.ZRO = AQ_CLEAR; //îáíóëÿåì ïðè íóëå ñ÷åò÷èêà
//PWM0->AQCTLA_bit.CAU = AQ_SET; //âêëþ÷àåì ïðè ñðàâíåíèè è èíêðåìåíòèîâàíèè
//PWM0->AQCTLA_bit.CAD = AQ_CLEAR; //îáíóëÿåì ïðè ñðàâíåíèè è äåêðåìåíòðîâàíèè
PWM0->AQCTLA = (AQ_CLEAR << PWM_AQCTLA_ZRO_Pos) |
(AQ_SET << PWM_AQCTLA_CAU_Pos) |
(AQ_CLEAR << PWM_AQCTLA_CAD_Pos);
//Äëÿ PWMB íàñòðîéêà íå íóæíà, òàê êàê îí ïðè ïîìîùè áëîêà ì¸ðòâîãî âðåìåíè áóäåò èíâåðñèåé îò êàíàëà A
PWM0->AQSFRC_bit.RLDCSF = 0; //ïî ÒÎ íàäî ïèñàòü 0
// Íàñòðîéêà áëîêà ì¸ðòâîãî âðåìåíè
// DBRED = DBFED = 150 * Tì_ìêñ / 4
PWM0->DBRED = _IQ4mpy(_IQ4(150 / 4), p->DeadBand >> 20) >> 4;
PWM0->DBFED = PWM0->DBRED;
// Íàñòðîéêà ìîäóëÿ ì¸ðòâîãî âðåìåíè:
// INMODE: S5=0 S4=0 - ñèãíàë ñ çàäåðæàííûì ïåðåäíèì ôðîíòîì è ñèãíàë ñ çàäåðæàííûì çàäíèì ôðîíòîì
// ôîðìèðóþòñÿ èç ñèãíàëà PWMA
// POLSEL: S3 = 1 S2 = 1 - ñèãíàë ñ çàäåðæàííûì ïåðåäíèì ôðîíòîì èä¸ò êàê åñòü, à ñèãíàë
// ñ çàäåðæàííûì çàäíèì ôðîíòîì èíâåðòèðóåòñÿ
// OUTMODE:S0 = 1 S1 = 1 íà êàíàë PWMA âûõîäèò èñõîäíûé ñèãíàë PWMA, íî ñ çàäåðæàííûì ïåðåäíèì ôðîíòîì
// Íà êàíàë PWMB âûõîäèò ñèãíàë PWMA ñ çàäåðæàííûì çàäíèì ôðîíòîì äà åù¸ è ñ èíâåðñèåé
//PWM0->DBCTL_bit.INMODE = DBA_ALL;
//PWM0->DBCTL_bit.POLSEL = DB_ACTV_HIC;
//PWM0->DBCTL_bit.OUTMODE = DB_FULL_ENABLE;
PWM0->DBCTL = (DBA_ALL << PWM_DBCTL_INMODE_Pos) |
(DB_ACTV_HIC << PWM_DBCTL_POLSEL_Pos) |
(DB_FULL_ENABLE << PWM_DBCTL_OUTMODE_Pos);
// Íàñòðîéêà Trip-Zone
//PWM0->TZCTL_bit.TZA = TZ_STATE; // ïî ñîáûòèþ "One-Shot Trip" ïåðåâîäèì
//PWM0->TZCTL_bit.TZB = TZ_STATE; // ØÈÌ âûõîäû â íóæíîå ñîñòîÿíèå (òðåòüå)
PWM0->TZCTL = (TZ_STATE << PWM_TZCTL_TZA_Pos) |
(TZ_STATE << PWM_TZCTL_TZB_Pos);
// ------------------------------------------------------------------------
// Íàñòðàèâàåì ìîäóëü ePWM1
// ------------------------------------------------------------------------
// Setup TBCLK
PWM1->TBPRD = PWM0->TBPRD; //ïåðèîä òàêîé æå
PWM1->TBPHS_bit.TBPHS = 0x0001; // Ôàçà ðàâíà 1 èç-çà çàäåðæêè â îäèí òàêò íà ñèíõðîíèçàöèþ
PWM1->TBCTR = 0x0000; // Clear counter
// Íàñòðîéêà ñ÷¸ò÷èêà
//PWM1->TBCTL_bit.PRDLD = TB_SHADOW; // Çàãðóçêà TBPRD ïðè TBCTR = 0
//PWM1->TBCTL_bit.CTRMODE = TB_COUNT_UPDOWN; // Ñ÷¸ò ââåðõ-âíèç
//PWM1->TBCTL_bit.PHSEN = TB_ENABLE; // Ðàçðåøèòü ñèíõðîíèçàöèþ
//PWM1->TBCTL_bit.PHSDIR = TB_UP; // Ñ÷èòàòü ââåðõ ïîñëå çàãðóçêè ôàçû
//PWM1->TBCTL_bit.HSPCLKDIV = 0; // Ïåðâûé äåëèòåëü ÷àñòîòû (íåò äåëåíèÿ)
//PWM1->TBCTL_bit.CLKDIV = 0; // Âòîðîé äåëèòåëü ÷àñòîòû (íåò äåëåíèÿ)
//PWM1->TBCTL_bit.SYNCOSEL = TB_SYNC_IN; // Ïðîïóñêàåì ñèíõðî-ñèãíàë "íàñêâîçü"
//PWM1->TBCTL_bit.FREESOFT = 2; // Ïðîäîëæàòü ñ÷¸ò ïðè äåáàæíîì îñòàíîâå ïðîöåññîðà
//PWM1->TBCTL_bit.SHADOWGLOB = 1; // Ðàçðåøèòü íîðìàëüíóþ ðàáîòó òåíåâûõ ðåãèñòðîâ
PWM1->TBCTL = (TB_SHADOW << PWM_TBCTL_PRDLD_Pos) |
(TB_COUNT_UPDOWN << PWM_TBCTL_CTRMODE_Pos) |
(TB_ENABLE << PWM_TBCTL_PHSEN_Pos) |
(TB_UP << PWM_TBCTL_PHSDIR_Pos) |
(0 << PWM_TBCTL_HSPCLKDIV_Pos) |
(0 << PWM_TBCTL_CLKDIV_Pos) |
(TB_SYNC_IN << PWM_TBCTL_SYNCOSEL_Pos) |
(2 << PWM_TBCTL_FREESOFT_Pos) |
(1 << PWM_TBCTL_SHDWGLOB_Pos);
// Òåíåâûå ðåãèñòðû, èçìåíåíèÿ âûõîäíûõ ñèãíàëîâ, ì¸ðòâîå âðåìÿ
// TZ è ïðåðûâàíèÿ íàñòðàèâàþòñÿ òàê æå, êàê ó PWM0
PWM1->CMPCTL = PWM0->CMPCTL;
PWM1->AQCTLA = PWM0->AQCTLA;
PWM1->DBRED = PWM0->DBRED;
PWM1->DBFED = PWM0->DBFED;
PWM1->DBCTL = PWM0->DBCTL;
PWM1->TZCTL = PWM0->TZCTL;
PWM1->ETSEL = PWM0->ETSEL;
// Îáíóëåíèå óñòàâîê
PWM1->CMPA_bit.CMPA = 0;
PWM1->AQSFRC_bit.RLDCSF = 0;
// ------------------------------------------------------------------------
// Íàñòðàèâàåì ìîäóëü ePWM2
// ------------------------------------------------------------------------
// Setup TBCLK
PWM2->TBPRD = PWM0->TBPRD;
PWM2->TBPHS_bit.TBPHS = 0x0001; // Ôàçà ðàâíà 1 èç-çà çàäåðæêè â îäèí òàêò íà ñèíõðîíèçàöèþ
PWM2->TBCTR = 0x0000; // Clear counter
// Íàñòðîéêà ñ÷¸ò÷èêà òàêàÿ æå, êàê ó PWM1
//PWM2->TBCTL_bit.PRDLD = TB_SHADOW; // çàãðóçêà TBPRD ïðè TBCTR = 0
//PWM2->TBCTL_bit.CTRMODE = TB_COUNT_UPDOWN; // Count up-down
//PWM2->TBCTL_bit.PHSEN = TB_ENABLE; // Enable phase loading
//PWM2->TBCTL_bit.PHSDIR = TB_UP; // Ñ÷èòàòü ââåðõ ïîñëå çàãðóçêè ôàçû
//PWM2->TBCTL_bit.HSPCLKDIV = 0; // High Speed Time-base Clock Prescale
//PWM2->TBCTL_bit.CLKDIV = 0; // Time-base Clock Prescale
//PWM2->TBCTL_bit.SYNCOSEL = TB_SYNC_IN; // ðàçðåøàåì âûäà÷ó ñèíõðî-ñèãíàëà
//PWM2->TBCTL_bit.FREESOFT = 2; // Ïðîäîëæàòü ñ÷¸ò ïðè äåáàæíîì îñòàíîâå ïðîöåññîðà
//PWM2->TBCTL_bit.SHADOWGLOB = 1; // Ðàçðåøèòü íîðìàëüíóþ ðàáîòó òåíåâûõ ðåãèñòðîâ
PWM2->TBCTL = PWM1->TBCTL;
// Òåíåâûå ðåãèñòðû, èçìåíåíèÿ âûõîäíûõ ñèãíàëîâ, ì¸ðòâîå âðåìÿ
// TZ è ïðåðûâàíèÿ íàñòðàèâàþòñÿ òàê æå, êàê ó PWM0 è PWM1
PWM2->CMPCTL = PWM0->CMPCTL;
PWM2->AQCTLA = PWM0->AQCTLA;
PWM2->DBRED = PWM0->DBRED;
PWM2->DBFED = PWM0->DBFED;
PWM2->DBCTL = PWM0->DBCTL;
PWM2->TZCTL = PWM0->TZCTL;
PWM2->ETSEL = PWM0->ETSEL;
// Îáíóëåíèå óñòàâîê
PWM2->CMPA_bit.CMPA = 0;
PWM2->AQSFRC_bit.RLDCSF = 0;
// Îòêëþ÷àåì êëþ÷è
PWM0->TZFRC_bit.OST = 1;
PWM1->TZFRC_bit.OST = 1;
PWM2->TZFRC_bit.OST = 1;
//ØÈÌ 6 âûâîäîâ
GPIOA->ALTFUNCSET = (1 << 8) + (1 << 9) + (1 << 10) + (1 << 11) + (1 << 12) + (1 << 13);
//Ñèíõðîííûé çàïóñê ØÈÌ
SIU->PWMSYNC_bit.PRESCRST= 0b111;
}
//! Íîðìèðîâàíèå âõîäíûõ âåëè÷èí.
//!Ó÷èòûâàåò êîìïåíñàöèþ íàïðÿæåíèÿ ïðè èçìåíåíèè Ud,
//!âûïîëíÿåò âïèñûâàíèå âåêòîðà â îêðóæíîñòü, åñëè òðåáóåòñÿ, è
//!âûïîëíÿåò ñìåíó áàçèñà, îòíîñèòåëüíî êîòîðîãî èäåò íîðìèðîâêà.
//! \memberof TPWM_Module
void PWM_Module_NormInput(TPWM_Module* p) {
_iq knorm;
p->UalphaNorm=p->UalphaRef;
p->UbetaNorm=p->UbetaRef;
//íàõîäèì àìïëèòóäó (áåç ó÷åòà îãðàíè÷åíèÿ)
p->U_mag=_IQmag(p->UalphaNorm,p->UbetaNorm);
p->UdCorTmp=_IQdiv(_IQ(1.0),(_IQ(1.0)+_IQmpy((adc.Udc_meas-_IQ(1.0)),p->UdCompK)));
//ó÷åò ïóëüñàöèé íàïðÿæåíèÿ íà Ud
if (p->UdCompEnable&1) { //îí âêëþ÷åí?
p->UalphaNorm=_IQmpy(p->UalphaNorm, p->UdCorTmp);//èçìåíèì ïðîïîðöèîíàëüíî êîýôô-òó êîððåêöèè
p->UbetaNorm=_IQmpy(p->UbetaNorm, p->UdCorTmp);//è ýòî òîæå
}
//âïèñûâàíèå çàäàííîé àìïëèòóäû íàïðÿæåíèÿ â îêðóæíîñòü, âïèñûâàåìóþ â øåñòèóãîëüíèê áàçûâûõ âåêòîðîâ
//êîãäà U_lim=1.0, ýòî è åñòü òàêàÿ îêðóæíîñòü. Áûâàåò, ÷òî ìû õîòèì âïèñûâàòü â øåñòèóãîëüíèê. Òîãäà ïðîñòî çàäèðàåì ââåðõ îãðèàíè÷åíèå U_lim
if (p->U_lim>_IQ(1.0/0.866)) //íî íåò ñìûñëà çàäèðàòü âûøå ìàêñèìàëüíî-ðåàëèç. íàïðÿæåíèÿ (áîëüøå áàçîâîãî âåêòîðà)
p->U_lim=_IQ(1.0/0.866);
/* ðàññ÷èòûâàåì àìïëèòóäó âåêòîðà, êîòîðûé õîòèì îòðàáîòàòü*/
knorm=_IQmag(p->UalphaNorm,p->UbetaNorm);//ïëþñ íîðìèðóåì îò 540 ê 311
if (knorm>=p->U_lim) { //îí áîëüøå, ÷åì íàøå îãðàíè÷åíèå?
knorm=_IQdiv(p->U_lim,knorm);//â ýòó æå ïåðåìåííóþ, äëÿ ýêîíîìèè, ðàññ÷èòûâàåì íîðìèðîâêó
p->UalphaNorm=_IQmpy(knorm,p->UalphaNorm);//óìåíüøàåì ïðîïîðöèîíàëüíî íîðìèðîâêå
p->UbetaNorm=_IQmpy(knorm,p->UbetaNorm);//è ýòî
p->ULimitation=1;//ôëàã î òîì, ÷òî èäåò îãðàíè÷åíèå íàïðÿæåíèÿ
} else
p->ULimitation=0;
/* ðàññ÷èòûâàåì ïðèâåäåííûå âåêòîðà*/
/* Äî ýòîãî ìîìåíòà íàïðÿæåíèå íîðìèðîâàëîñü îòíîñèòåëüíî
áàçèñà ôàçíîãî àìïëèòóäíîãî çíà÷åíèÿ, íàïðèìåð, 220*sqrt(2)
Òåïåðü ïðîèçâîäèòñÿ ïåðåõîä, ãäå çà åäèíèöó ïðèíèìàåòñÿ ìàêñèìàëüíî
ðåàëèçóåìîå íàïðÿæåíèå (äëèíà áàçîâîãî âåêòîðà)
*/
p->UalphaNorm=_IQmpy(p->UalphaNorm,_IQ(0.866));
p->UbetaNorm=_IQmpy(p->UbetaNorm,_IQ(0.866));
}
//! Ôóíêöèÿ 6òè ñåêòîðíîé âåêòîðíîé ØÈÌ
//! \memberof TPWM_Module
void PWM_Module_No_SV_Update(TPWM_Module *p) {
_iq lambda1;
_iq lambda2;
_iq lambda3;
int16 gamma;
int16 gamma1;
long tmp_pwm;
//Ïðèñâîåíèå òðåõ óñòàâîê ñðàâíåíèÿ òîëüêî åñëè ñ÷åò÷èê òàéìåðà äàëåê îò íóëÿ, ÷òîáû
//ïðåäîòâðàòèòü ÷àñòè÷íîå ïðèìåíåíèå ñêâàæíîñòåé, ÷òî â âåêòîðíîé ØÈÌ ìîæåò áûòü êðèòè÷íî è èñïîðòèòü ïåðèîä ØÈÌ.
DINT;
if (PWM0->TBCTR>30) {
PWM0->CMPA_bit.CMPA=(Uint16)p->GammaA;
PWM1->CMPA_bit.CMPA=(Uint16)p->GammaB;
PWM2->CMPA_bit.CMPA=(Uint16)p->GammaC;
}
EINT;
PWM_Module_NormInput(p);
//Ðàñ÷åò ñêâàæíîñòåé ïî ìåòîäó Èçîñèìîâà.
//Ïîäðîáíåå ñì. äèññåðòàöèþ ×óåâà Ï.Â. http://motorcontrol.ru/wp-content/uploads/2015/11/Chuev_vector_control.pdf
tmp_pwm = _IQmpy(_1_SQRT3,p->UbetaNorm); /*äåëèì íà êîðåíü èç 3*/
lambda1 = _IQmpy(p->k_pwm,(p->UalphaNorm - tmp_pwm));
lambda2 = _IQmpy(p->k_pwm,2*tmp_pwm);
lambda3 = _IQmpy(p->k_pwm,p->UalphaNorm + tmp_pwm);
if (lambda1<=0)
if (lambda3>0) {
gamma=lambda3;
gamma1=-lambda1;
p->sector=1; /*110 íà÷àëî */
p->GammaA=p->k_pwm-gamma;
p->GammaB=p->k_pwm-(gamma+gamma1+1);
p->GammaC=p->k_pwm-0;
} else if (lambda2>0) {
gamma=lambda2;
gamma1=-lambda3;
p->sector=2; /*011 íà÷àëî */
p->GammaA=p->k_pwm-0;
p->GammaB=p->k_pwm-(gamma+gamma1+1);
p->GammaC=p->k_pwm-gamma1;
/*011 íà÷àëî */
} else if (lambda1!=0) {
gamma=-lambda1;
gamma1=-lambda2;
p->sector=3; /*011 íà÷àëî */
p->GammaA=p->k_pwm-0;
p->GammaB=p->k_pwm-gamma;
p->GammaC=p->k_pwm-(gamma+gamma1+1);
/*011 íà÷àëî */
} else {
gamma=-lambda3;
gamma1 = lambda1;
p->sector= 4; /*101 íà÷àëî */
p->GammaA=p->k_pwm-gamma1;
p->GammaB=p->k_pwm-0;
p->GammaC=p->k_pwm-(gamma+gamma1+1);
/*101 íà÷àëî */
}
else if (lambda2>0) {
gamma=lambda1;
gamma1=lambda2;
p->sector= 0; /*110 íà÷àëî */
p->GammaA=p->k_pwm-(gamma+gamma1+1);
p->GammaB=p->k_pwm-gamma1;
p->GammaC=p->k_pwm-0;
/*110 íà÷àëî */
} else if (lambda3<0) {
gamma=-lambda3;
gamma1 = lambda1;
p->sector= 4; /*101 íà÷àëî */
p->GammaA=p->k_pwm-gamma1;
p->GammaB=p->k_pwm-0;
p->GammaC=p->k_pwm-(gamma+gamma1+1);
/*101 íà÷àëî */
} else {
gamma=-lambda2;
gamma1=lambda3;
p->sector=5; /*101 íà÷àëî */
p->GammaA=p->k_pwm-(gamma+gamma1+1);
p->GammaB=p->k_pwm-0;
p->GammaC=p->k_pwm-gamma;
/*101 íà÷àëî */
}
/*íàñûùåíèÿ */
if (p->GammaA<0) p->GammaA=0;
if (p->GammaB<0) p->GammaB=0;
if (p->GammaC<0) p->GammaC=0;
if (p->GammaA>p->k_pwm) p->GammaA=p->k_pwm+1;
if (p->GammaB>p->k_pwm) p->GammaB=p->k_pwm+1;
if (p->GammaC>p->k_pwm) p->GammaC=p->k_pwm+1;
//Ïðèñâîåíèå òðåõ óñòàâîê ñðàâíåíèÿ òîëüêî åñëè ñ÷åò÷èê òàéìåðà äàëåê îò íóëÿ, ÷òîáû
//ïðåäîòâðàòèòü ÷àñòè÷íîå ïðèìåíåíèå ñêâàæíîñòåé, ÷òî â âåêòîðíîé ØÈÌ ìîæåò áûòü êðèòè÷íî è èñïîðòèòü ïåðèîä ØÈÌ.
//Âòîðîé ðàç - ÷òîáû ïðåäîòâðàòèòü ñèòóàöèþ ñ ïîñòîÿííîé "íåçàãðóçêîé" ïðè ðàâåíñòâå ÷àñòîò ðàñ÷åòà è ØÈÌ
DINT;
if (PWM0->TBCTR>30) {
PWM0->CMPA_bit.CMPA=(Uint16)p->GammaB;
PWM1->CMPA_bit.CMPA=(Uint16)p->GammaC;
PWM2->CMPA_bit.CMPA=(Uint16)p->GammaA;
}
EINT;
}
//! Ôóíêöèÿ ñèíóñîèäàëüíîé ØÈÌ
//! \memberof TPWM_Module
void PWM_Module_Sin_Update(TPWM_Module *p) {
_iq PhasePtsA;
_iq PhasePtsB;
_iq PhasePtsC;
_iq knorm;
p->UalphaNorm = p->UalphaRef;
p->UbetaNorm = p->UbetaRef;
//íàõîäèì àìïëèòóäó (áåç ó÷åòà îãðàíè÷åíèÿ)
p->U_mag = _IQmag(p->UalphaNorm, p->UbetaNorm);
/* ðàññ÷èòûâàåì àìïëèòóäó âåêòîðà, êîòîðûé õîòèì îòðàáîòàòü*/
knorm = _IQmag(p->UalphaNorm, p->UbetaNorm);
if (knorm >= p->U_lim) { //îí áîëüøå, ÷åì íàøå îãðàíè÷åíèå?
knorm = _IQdiv(p->U_lim, knorm); //â ýòó æå ïåðåìåííóþ, äëÿ ýêîíîìèè, ðàññ÷èòûâàåì íîðìèðîâêó
p->UalphaNorm = _IQmpy(knorm, p->UalphaNorm); //óìåíüøàåì ïðîïîðöèîíàëüíî íîðìèðîâêå
p->UbetaNorm = _IQmpy(knorm, p->UbetaNorm); //è ýòî
p->ULimitation = 1; //ôëàã î òîì, ÷òî èäåò îãðàíè÷åíèå íàïðÿæåíèÿ
} else
p->ULimitation = 0;
//Íîðìèðîâàíèå âõîäíîãî íàïðÿæåíèÿ. Òàê êàê ñèíóñîèäàëüíàÿ ØÈÌ ôîðìèðóåò íà 0.866 ìåíüøåå íàïðÿæåíèå,
//÷åì âåêòîðíàÿ ØÈÌ (270 àìïëèòóäíîãî ôàçíîãî íàïðÿæåíèÿ âìåñòî 311Â), òî äëÿ òîãî, ÷òîáû ïðè òîì æå çàäàíèè â ïåðåìåííûõ
//p->UalphaNorm, p->UbetaNorm ïîëó÷èëîñü òî æå ñàìîå íàïðÿæåíèå íà âûõîäå, ÷òî è â âåêòîðíîé ØÈÌ, íóæíî çàäàíèÿ óâåëè÷èòü â 1/0.866 ðàç.
//Äåëåíèå íà äâà íóæíî äëÿ ïîñëåäóþùèõ ôîðìóë, ÷òîáû ïåðåìåíûå ìåíÿëèñü â ïîëîâèííîì îò ìàêñèìàëüíîãî äèàïàçîíå.
p->UalphaNorm = _IQmpy(p->UalphaNorm, _IQ(1/0.866/2));
p->UbetaNorm = _IQmpy(p->UbetaNorm, _IQ(1/0.866/2));
/*ôàçíîå ïðåîáðàçîâàíèå èç ñèñòåìû àëüôà, áåòòà â a,b,c */
PhasePtsA = _IQ(0.5) - (p->UalphaNorm);
PhasePtsB = _IQ(0.5) - (_IQmpy(p->UbetaNorm,_IQ(0.8660254)) - (p->UalphaNorm >> 1));
PhasePtsC = _IQ(0.5) - (-_IQmpy(p->UbetaNorm, _IQ(0.8660254)) - (p->UalphaNorm >> 1));
p->GammaA = _IQmpy(p->k_pwm, PhasePtsA);
p->GammaB = _IQmpy(p->k_pwm, PhasePtsB);
p->GammaC = _IQmpy(p->k_pwm, PhasePtsC);
/*íàñûùåíèÿ */
if (p->GammaA < 0)
p->GammaA = 0;
if (p->GammaB < 0)
p->GammaB = 0;
if (p->GammaC < 0)
p->GammaC = 0;
if (p->GammaA > p->k_pwm)
p->GammaA = p->k_pwm + 1;
if (p->GammaB > p->k_pwm)
p->GammaB = p->k_pwm + 1;
if (p->GammaC > p->k_pwm)
p->GammaC = p->k_pwm + 1;
PWM0->CMPA_bit.CMPA = (Uint16) p->GammaB;
PWM1->CMPA_bit.CMPA = (Uint16) p->GammaC;
PWM2->CMPA_bit.CMPA = (Uint16) p->GammaA;
}
//! Ôóíêöèÿ ØÈÌ ñ ðàçäåëüíûìè ôàçàìè (äëÿ ìîäåëè SRM)
//! \memberof TPWM_Module
void PWM_Module_Separate_Update(TPWM_Module *p) {
// Çàêîììåíòèðîâàíî äëÿ ýêîíîìèè ìåñòà
/* _iq PhasePtsA;
_iq PhasePtsB;
_iq PhasePtsC;
_iq knorm;
p->UPhARef = _IQmpy(p->UPhARef, _IQ(0.5));
p->UPhBRef = _IQmpy(p->UPhBRef, _IQ(0.5));
p->UPhCRef = _IQmpy(p->UPhCRef, _IQ(0.5));
PhasePtsA = _IQ(0.5) - p->UPhARef;
PhasePtsB = _IQ(0.5) - p->UPhBRef;
PhasePtsC = _IQ(0.5) - p->UPhCRef;
p->GammaA = _IQmpy(p->k_pwm, PhasePtsA);
p->GammaB = _IQmpy(p->k_pwm, PhasePtsB);
p->GammaC = _IQmpy(p->k_pwm, PhasePtsC);
//íàñûùåíèÿ
if (p->GammaA < 0)
p->GammaA = 0;
if (p->GammaB < 0)
p->GammaB = 0;
if (p->GammaC < 0)
p->GammaC = 0;
if (p->GammaA > p->k_pwm)
p->GammaA = p->k_pwm + 1;
if (p->GammaB > p->k_pwm)
p->GammaB = p->k_pwm + 1;
if (p->GammaC > p->k_pwm)
p->GammaC = p->k_pwm + 1;
PWM0->CMPA_bit.CMPA = (Uint16) p->GammaB;
PWM1->CMPA_bit.CMPA = (Uint16) p->GammaC;
PWM2->CMPA_bit.CMPA = (Uint16) p->GammaA;
*/
}
//! Ôóíêöèÿ ØÈÌ äëÿ íà÷àëüíîé çàðÿäêè áóäñòðåïíûõ êîíäåíñàòîðîâ èíâåðòîðà
//! \memberof TPWM_Module
void PWM_Module_ChargingMode(TPWM_Module *p) {
p->GammaA = p->k_pwm;
p->GammaB = p->k_pwm;
p->GammaC = p->k_pwm;
DINT;
if (PWM0->TBCTR > 30) {
PWM0->CMPA_bit.CMPA = (Uint16) p->GammaA;
PWM1->CMPA_bit.CMPA = (Uint16) p->GammaB;
PWM2->CMPA_bit.CMPA = (Uint16) p->GammaC;
}
EINT;
}
//! Îáùàÿ ôóíêöèÿ-îáåðòêà äëÿ ðàñ÷åòà ØÈÌ
//Âûçûâàþùàåò òó âåðñèþ ØÈÌ (òó ôóíêöèþ), ÷òî âûáðàíà â íàñòðîéêàõ.
//! \memberof TPWM_Module
void PWM_Module_Update(TPWM_Module *p) {
if (p->ChargingMode)
PWM_Module_ChargingMode(p);
else {
switch (p->PWM_type) {
case PWM_TYPE_6SECT_NO_SV: {
PWM_Module_No_SV_Update(p);
break;
}
case PWM_TYPE_SIN_PWM: {
PWM_Module_Sin_Update(p);
break;
}
default: {
// Çàùèòà îò íåïðàâèëüíûõ òèïîâ ØÈÌ
p->PWM_type = PWM_TYPE_6SECT_NO_SV;
PWM_Module_No_SV_Update(p);
break;
}
}
}
}
//! Ìåäëåííûé ðàñ÷åò
//! Ïåðåñ÷èòûâàþòñÿ ââåäåííûå ïîëüçîâàòåëåì âåëè÷èíû
//! Âåëè÷èíà ìåðòâîãî âðåìåíè, ÷àñòîòà ØÈÌ è ò.ï.
//! \memberof TPWM_Module
void PWM_Module_SlowCalc(TPWM_Module *p) {
Uint16 tmp;
//ïðîâåðêà îãðàíè÷åíèé âåëè÷èíû ìåðòâîãî âðåìåíè
if (p->DeadBand < DEAD_BAND_MIN)
p->DeadBand = DEAD_BAND_MIN;
if (p->DeadBand > DEAD_BAND_MAX)
p->DeadBand = DEAD_BAND_MAX;
//ïåðåñ÷åò Ì èç ôîðìàòà IQ â ìêñ â òàêòû òàéìåðà íà 100ìÃö
PWM0->DBRED = _IQ4mpy(_IQ4(100), p->DeadBand >> 20) >> 4;
//âî âñå êëþ÷è òî æå ñàìîå
PWM0->DBFED = PWM0->DBRED;
PWM1->DBFED = PWM0->DBRED;
PWM1->DBRED = PWM0->DBRED;
PWM2->DBFED = PWM0->DBRED;
PWM2->DBRED = PWM0->DBRED;
if (p->MinGammaLimit < DEAD_BAND_MIN)
p->MinGammaLimit = GAMMA_LIMIT_MIN;
if (p->MinGammaLimit > DEAD_BAND_MAX)
p->MinGammaLimit = GAMMA_LIMIT_MAX;
PWM0->FWDTH = _IQ4mpy(_IQ4(100), p->MinGammaLimit >> 20) >> 4;
PWM1->FWDTH = PWM0->FWDTH;
PWM2->FWDTH = PWM0->FWDTH;
//÷àñòîòà ØÈÌ. Ñìåíà "íà ëåòó".
if (p->FreqPrev != p->Frequency) { //ñìåíèëè ÷àñòîòó
DINT; //çàïðåùåíèå ïðåðûâàíèé
//ïðîâåðêà ìàêñèìóìà/ìèíèìóìà
if (p->Frequency < PWM_FREQ_MIN)
p->Frequency = PWM_FREQ_MIN;
if (p->Frequency > PWM_FREQ_MAX)
p->Frequency = PWM_FREQ_MAX;
//èçìåíÿåì ïåðèîä
p->k_pwm = _IQ10div(_IQ10(SystemCoreClock/1000.0), p->Frequency << 1) >> 10; //ïåðèîä
PWM0->TBPRD = p->k_pwm;
//äëÿ âñåõ ñòîåê òî æå ñàìîå
PWM1->TBPRD = p->k_pwm;
PWM2->TBPRD = p->k_pwm;
p->FreqPrev = p->Frequency; //ïðåäûäóùàÿ ÷àñòîòà
EINT;
}
}
//! Ôóíêöèÿ âêëþ÷åíèÿ ØÈÌ (âêëþ÷åíèå èíâåðòîðà)
//! \memberof TPWM_Module
void PWM_Module_On(TPWM_Module *p) {
p->Enabled = 1; //ôëàã "âêëþ÷åíî"
// Ñíèìàåì ïðèíóäèòåëüíóþ óñòàíîâêó âûõîäîâ
PWM0->TZCLR_bit.OST = 1;
PWM1->TZCLR_bit.OST = 1;
PWM2->TZCLR_bit.OST = 1;
}
//! Ôóíêöèÿ âûêëþ÷åíèÿ ØÈÌ (âûêëþ÷åíèå èíâåðòîðà)
//! \memberof TPWM_Module
void PWM_Module_Off(TPWM_Module *p) {
p->Enabled = 0; //ôëàã "âûêëþ÷åíî"
// Ïðèíóäèòåëüíî îáíóëèì âñå íîæêè
PWM0->TZFRC_bit.OST = 1;
PWM1->TZFRC_bit.OST = 1;
PWM2->TZFRC_bit.OST = 1;
}
/*@}*/