a99491f9b8
- проект переведён на VectorIDE v1.3 В целях экономии памяти удалены: - модуль управления светодиодами - модуль ШИМ для двигателей SRD - модуль часов реального времени - режим привода для измерения задержки меджу сигналами ШИМ и измерениями токов Добавлены следующие модули: - проект переведён на VectorIDE v1.3 - модуль SPI для абсолютного ДПР - модуль управление реле для заряда ЗПТ - модуль дискретных вводов-выводов - модуль управления вентилятором Одноплатного Инвертора - модуль тормозного резистора Одноплатного Инвертора Прочие изменения: - оптимизирована инициализация регистров периферии - удалено множество неиспользуемых переменных - разрешение работы всех GPIO перенесено в функцию "PeripheralClockEnable" - добавлен счётчик индексной метки энкодера - исправлен сброс прерываний модуля захвата CAP - переработан режим задания постоянного тока статора - исправлены прочие мелкие ошибки в разных модулях
611 lines
21 KiB
C
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;
|
|
}
|
|
|
|
/*@}*/
|