motorcontroldemo_035/Vsrc/V_PWM_Module.c
KulikEgor bd31578422 Ряд правок:
V_PWM_Module.c - изменено чередование ШИМ каналов;
V_adc.c - добавлена обработка датчика температуры;
cood1.c - изменены дефолтные коэффициенты усиления для датчиков тока и датчика температуры.
2019-09-24 11:41:09 +03:00

653 lines
23 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; //ñèíõðîíèçàöèÿ òàéìåðîâ - ñáðîñ âíóòðåííèõ ñ÷åò÷èêîâ
// ------------------------------------------------------------------------
// Íàñòðàèâàåì ìîäóëü ePWM0
// ------------------------------------------------------------------------
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; //ïðåäûäóùàÿ ÷àñòîòà
PWM0->TBPHS_bit.TBPHS = 0x0000; // Phase is 0
PWM0->TBCTR = 0x0000; // Clear counter
// Setup counter mode
PWM0->TBCTL_bit.PRDLD = TB_SHADOW; // çàãðóçêà TBPRD ïðè TBCTR = 0
PWM0->TBCTL_bit.CTRMODE = TB_COUNT_UPDOWN; // Count up-down
PWM0->TBCTL_bit.PHSEN = TB_DISABLE; // Disable phase loading
PWM0->TBCTL_bit.PHSDIR = TB_UP; // Ñ÷èòàòü ââåðõ ïîñëå çàãðóçêè ôàçû
PWM0->TBCTL_bit.HSPCLKDIV = 0; // High Speed Time-base Clock Prescale
PWM0->TBCTL_bit.CLKDIV = 0; // Time-base Clock Prescale
PWM0->TBCTL_bit.SYNCOSEL = TB_CTR_ZERO; // âûäà¸ì ñèíõðî-ñèãíàë ïðè TBCTR = 0
// Setup shadowing
PWM0->CMPCTL_bit.SHDWAMODE = CC_SHADOW; //âêëþ÷èòü SHADOW äëÿ ñðàâíåíèÿ
PWM0->CMPCTL_bit.LOADAMODE = CC_CTR_ZERO; // Load on period and zero
PWM0->CMPCTL_bit.SHDWBMODE = CC_SHADOW; //âêëþ÷èòü SHADOW äëÿ ñðàâíåíèÿ
PWM0->CMPCTL_bit.LOADBMODE = CC_CTR_ZERO; // Load on period and zero
// Set Compare values
PWM0->CMPA_bit.CMPA = 0; // Set compare A value
// Set actions
PWM0->AQCTLA = AQ_EPWM_DISABLE; // äëÿ íà÷àëà ñîáûòèÿ äëÿ PWM1A çàïðåùåíû
PWM0->AQCTLA_bit.ZRO = 1; //îáíóëÿåì ïðè íóëå ñ÷åò÷èêà
PWM0->AQCTLA_bit.CAU = 2; //âêëþ÷àåì ïðè ñðàâíåíèè è èíêðåìåíòèîâàíèè
PWM0->AQCTLA_bit.CAD = 1; //îáíóëÿåì ïðè ñðàâíåíèè è äåêðåìåíòðîâàíèè
//Äëÿ PWMB òîæå ñàìîå, ÷òî äëÿ PWMÀ. Áåç èíâåðñèè. Èíâåðñèÿ äàëåå â ìîäóëå ÌÂ
PWM0->AQCTLB = PWM0->AQCTLA; // äëÿ íà÷àëà ñîáûòèÿ äëÿ PWM1B çàïðåùåíû
PWM0->AQCTLB_bit.ZRO = PWM0->AQCTLA_bit.ZRO; //îáíóëÿåì ïðè íóëå ñ÷åò÷èêà
PWM0->AQCTLB_bit.CAU = PWM0->AQCTLA_bit.CAU; //âêëþ÷àåì ïðè ñðàâíåíèè è èíêðåìåíòèîâàíèè
PWM0->AQCTLB_bit.CAD = PWM0->AQCTLA_bit.CAD; //îáíóëÿåì ïðè ñðàâíåíèè è äåêðåìåíòðîâàíèè
PWM0->AQSFRC_bit.RLDCSF = 0; //ïî ÒÎ íàäî ïèñàòü 0
// Setup Deadband
// 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->ETSEL_bit.INTSEL = ET_DISABLE; // Disable INT (øèìîâñêîå)
PWM0->ETSEL_bit.INTEN = 0; // Disable INT
//ðàçðåøàåì TZ áûòü èñòî÷íèêîì àïïàðàòíîé àâàðèè (one-shot)
// PWM0->TZSEL_bit.OSHT1 = TZ_ENABLE;
// PWM0->TZSEL_bit.OSHT2 = TZ_ENABLE;
// PWM0->TZSEL_bit.OSHT3 = TZ_ENABLE;
// Trip-Zone
PWM0->TZCTL_bit.TZA = TZ_STATE; // ïî ñîáûòèþ "One-Shot Trip" ïåðåâîäèì
PWM0->TZCTL_bit.TZB = TZ_STATE; // ØÈÌ âûõîäû â íóæíîå ñîñòîÿíèå
//Äëÿ VectorCARD îò ØÈÌà çàïóñêàåòñÿ ADC
//PWM0->ETSEL_bit.SOCAEN = 1; // Ðàçðåøèòü çàïóñê àöï
//PWM0->ETSEL_bit.SOCASEL = 1; // Çàïóñêàòü ïðè CTR == 0 (Underflow)
// ------------------------------------------------------------------------
// Íàñòðàèâàåì ìîäóëü ePWM1
// ------------------------------------------------------------------------
// Setup TBCLK
PWM1->TBPRD = PWM0->TBPRD; //ïåðèîä òàêîé æå
PWM1->TBPHS_bit.TBPHS = 0x0001; // Ôàçà ðàâíà 1 èç-çà çàäåðæêè â îäèí òàêò íà ñèíõðîíèçàöèþ
PWM1->TBCTR = 0x0000; // Clear counter
// Setup counter mode
PWM1->TBCTL_bit.PRDLD = TB_SHADOW; // çàãðóçêà TBPRD ïðè TBCTR = 0
PWM1->TBCTL_bit.CTRMODE = TB_COUNT_UPDOWN; // Count up-down
PWM1->TBCTL_bit.PHSEN = TB_ENABLE; // Enable phase loading
PWM1->TBCTL_bit.PHSDIR = TB_UP; // Ñ÷èòàòü ââåðõ ïîñëå çàãðóçêè ôàçû
PWM1->TBCTL_bit.HSPCLKDIV = 0; // High Speed Time-base Clock Prescale
PWM1->TBCTL_bit.CLKDIV = 0; // Time-base Clock Prescale
PWM1->TBCTL_bit.SYNCOSEL = TB_SYNC_IN; // ïðîïóñêàåì ñèíõðî-ñèãíàë "íàñêâîçü"
// Setup shadowing
PWM1->CMPCTL_bit.SHDWAMODE = CC_SHADOW; //âêëþ÷èòü SHADOW äëÿ ñðàâíåíèÿ
PWM1->CMPCTL_bit.LOADAMODE = CC_CTR_ZERO; // Load on period and zero
PWM1->CMPCTL_bit.SHDWBMODE = CC_SHADOW; //âêëþ÷èòü SHADOW äëÿ ñðàâíåíèÿ
PWM1->CMPCTL_bit.LOADBMODE = CC_CTR_ZERO; // Load on period and zero
// Set Compare values
PWM1->CMPA_bit.CMPA = 0; // Set compare A value
// Set actions
PWM1->AQCTLA = AQ_EPWM_DISABLE; // äëÿ íà÷àëà ñîáûòèÿ çàïðåùåíû
PWM1->AQCTLA_bit.ZRO = 1; //îáíóëÿåì ïðè íóëå ñ÷åò÷èêà
PWM1->AQCTLA_bit.CAU = 2; //âêëþ÷àåì ïðè ñðàâíåíèè è èíêðåìåíòèîâàíèè
PWM1->AQCTLA_bit.CAD = 1; //îáíóëÿåì ïðè ñðàâíåíèè è äåêðåìåíòðîâàíèè
//Äëÿ PWMB òîæå ñàìîå, ÷òî äëÿ PWMÀ. Áåç èíâåðñèè. Èíâåðñèÿ äàëåå â ìîäóëå ÌÂ
PWM1->AQCTLB = PWM0->AQCTLA; // äëÿ íà÷àëà ñîáûòèÿ äëÿ PWM1B çàïðåùåíû
PWM1->AQCTLB_bit.ZRO = PWM0->AQCTLA_bit.ZRO; //îáíóëÿåì ïðè íóëå ñ÷åò÷èêà
PWM1->AQCTLB_bit.CAU = PWM0->AQCTLA_bit.CAU; //âêëþ÷àåì ïðè ñðàâíåíèè è èíêðåìåíòèîâàíèè
PWM1->AQCTLB_bit.CAD = PWM0->AQCTLA_bit.CAD; //îáíóëÿåì ïðè ñðàâíåíèè è äåêðåìåíòðîâàíèè
PWM1->AQSFRC_bit.RLDCSF = 0; //ïî ÒÎ íàäî ïèñàòü 0
// Active high complementary PWMs - Setup Deadband
PWM1->DBRED = PWM0->DBRED;
PWM1->DBFED = PWM1->DBRED;
PWM1->DBCTL_bit.INMODE = PWM0->DBCTL_bit.INMODE;
PWM1->DBCTL_bit.OUTMODE = PWM0->DBCTL_bit.OUTMODE;
PWM1->DBCTL_bit.POLSEL = PWM0->DBCTL_bit.POLSEL;
// Interrupt where we will change the Compare Values
PWM1->ETSEL_bit.INTSEL = ET_DISABLE; // Disable INT
PWM1->ETSEL_bit.INTEN = 0; // Disable INT
// Trip-Zone
PWM1->TZCTL_bit.TZA = TZ_STATE; // ïî ñîáûòèþ "One-Shot Trip" ïåðåâîäèì
PWM1->TZCTL_bit.TZB = TZ_STATE; // ØÈÌ âûõîäû â íóæíîå ñîñòîÿíèå
// ------------------------------------------------------------------------
// Íàñòðàèâàåì ìîäóëü ePWM2
// ------------------------------------------------------------------------
// Setup TBCLK
PWM2->TBPRD = PWM0->TBPRD;
PWM2->TBPHS_bit.TBPHS = 0x0001; // Ôàçà ðàâíà 1 èç-çà çàäåðæêè â îäèí òàêò íà ñèíõðîíèçàöèþ
PWM2->TBCTR = 0x0000; // Clear counter
// Setup counter mode
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; // ðàçðåøàåì âûäà÷ó ñèíõðî-ñèãíàëà
// Setup shadowing
PWM2->CMPCTL_bit.SHDWAMODE = CC_SHADOW; //âêëþ÷èòü SHADOW äëÿ ñðàâíåíèÿ
PWM2->CMPCTL_bit.LOADAMODE = CC_CTR_ZERO; // Load on period and zero
PWM2->CMPCTL_bit.SHDWBMODE = CC_SHADOW; //âêëþ÷èòü SHADOW äëÿ ñðàâíåíèÿ
PWM2->CMPCTL_bit.LOADBMODE = CC_CTR_ZERO; // Load on period and zero
// Set Compare values
PWM2->CMPA_bit.CMPA = 0; // Set compare A value
// Set actions
PWM2->AQCTLA = AQ_EPWM_DISABLE; // äëÿ íà÷àëà ñîáûòèÿ çàïðåùåíû
PWM2->AQCTLA_bit.ZRO = 1; //îáíóëÿåì ïðè íóëå ñ÷åò÷èêà
PWM2->AQCTLA_bit.CAU = 2; //âêëþ÷àåì ïðè ñðàâíåíèè è èíêðåìåíòèîâàíèè
PWM2->AQCTLA_bit.CAD = 1; //îáíóëÿåì ïðè ñðàâíåíèè è äåêðåìåíòðîâàíèè
//Äëÿ PWMB òîæå ñàìîå, ÷òî äëÿ PWMÀ. Áåç èíâåðñèè. Èíâåðñèÿ äàëåå â ìîäóëå ÌÂ
PWM2->AQCTLB = PWM0->AQCTLA; // äëÿ íà÷àëà ñîáûòèÿ äëÿ PWM1B çàïðåùåíû
PWM2->AQCTLB_bit.ZRO = PWM0->AQCTLA_bit.ZRO; //îáíóëÿåì ïðè íóëå ñ÷åò÷èêà
PWM2->AQCTLB_bit.CAU = PWM0->AQCTLA_bit.CAU; //âêëþ÷àåì ïðè ñðàâíåíèè è èíêðåìåíòèîâàíèè
PWM2->AQCTLB_bit.CAD = PWM0->AQCTLA_bit.CAD; //îáíóëÿåì ïðè ñðàâíåíèè è äåêðåìåíòðîâàíèè
PWM2->AQSFRC_bit.RLDCSF = 0; //ïî ÒÎ íàäî ïèñàòü 0
// Active high complementary PWMs - Setup Deadband
PWM2->DBRED = PWM0->DBRED;
PWM2->DBFED = PWM2->DBRED;
PWM2->DBCTL_bit.INMODE = PWM0->DBCTL_bit.INMODE;
PWM2->DBCTL_bit.OUTMODE = PWM0->DBCTL_bit.OUTMODE;
PWM2->DBCTL_bit.POLSEL = PWM0->DBCTL_bit.POLSEL;
// Interrupt where we will change the Compare Values
PWM2->ETSEL_bit.INTSEL = ET_DISABLE; // Disable INT
PWM2->ETSEL_bit.INTEN = 0; // Disable INT
// Trip-Zone
PWM2->TZCTL_bit.TZA = TZ_STATE; // ïî ñîáûòèþ "One-Shot Trip" ïåðåâîäèì
PWM2->TZCTL_bit.TZB = TZ_STATE; // ØÈÌ âûõîäû â íóæíîå ñîñòîÿíèå
// Îòêëþ÷àåì êëþ÷è
PWM0->TZFRC_bit.OST = 1;
PWM1->TZFRC_bit.OST = 1;
PWM2->TZFRC_bit.OST = 1;
//PWM0->TBCTL_bit.FREESOFT = 0;
//ØÈÌ 6 âûâîäîâ
GPIOA->ALTFUNCSET = (1 << 8) + (1 << 9) + (1 << 10) + (1 << 11) + (1 << 12) + (1 << 13);
GPIOA->DENSET = (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;
}
case PWM_TYPE_SRD: {
PWM_Module_Separate_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;
//ïîñ÷èòàåì äëèíó âûáîðêè äëÿ óñðåäíåíèÿ òîêîâ, èñõîäÿ èç ÷àñòîòû ØÈÌ
adc.IASampleLength = (p->Frequency >> 10) / 10; //×àñòîòà ØÈÌ â ôîðìàòå 22.10, ïðèâîäèì ê èíòó è äåëèì íà 10 - ÷àñòîòó ðàñ÷åòà ñèñòåìû óïðàâëåíèÿ
if (adc.IASampleLength > 4) //íå áîëåå 4 òî÷åê
adc.IASampleLength = 4;
if (adc.IASampleLength < 1) //íå ìåíåå 1 òî÷êè
adc.IASampleLength = 1;
adc.IBSampleLength = adc.IASampleLength;
adc.ICSampleLength = adc.IASampleLength;
adc.UdcSampleLength = adc.IASampleLength;
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;
}
/*@}*/