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

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

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

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

301 lines
11 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 main.c
\brief Ãëàâíûé ôàéë ïðîåêòà. Ñîäåðæèò main(), à òàêæå îáðàáîò÷èêè ïðåðûâàíèé.
\author ÎÎÎ "ÍÏÔ Âåêòîð". http://motorcontrol.ru
\version v 2.0 25/03/2016
*/
/** \addtogroup MAIN */
/*@{*/
#include "main.h"
#include <string.h> //äëÿ memcpy
TClarke clarke = CLARKE_DEFAULTS; //!<Ôàçíûå ïðåîáðàçîâàíèÿ
TPark park = PARK_DEFAULTS; //!<Êîîðäèíàòíûå ïðåîáðàçîâàíèÿ
TIPark ipark = IPARK_DEFAULTS; //!<Îáðàòíûå êîîðäèíàòíûå ïðåîáðàçîâàíèÿ
TPidReg3 pid_id = PIDREG3_DEFAULTS; //!<Ðåã. òîêà ïî îñè d
TPidReg3 pid_iq = PIDREG3_DEFAULTS; //!<Ðåã. òîêà ïî îñè q
TPidReg3 pid_ia = PIDREG3_DEFAULTS; //!<Ðåã. òîêà ÿêîðÿ ÄÏÒ
TPidReg3 pid_spd = PIDREG3_DEFAULTS; //!<Ðåã. ñêîðîñòè
TPidReg3 pid_pos = PIDREG3_DEFAULTS; //!<Ðåã. ïîëîæåíèÿ
TVhzProf vhz = VHZPROF_DEFAULTS; //!< çàêîí U/f=const
TSM_Sys sm_sys = SM_Sys_DEFAULTS; //!< Ãëàâíàÿ îáîëî÷êà äëÿ âûçîâà âñåõ ìîäóëåé
Uint16 disp_group_number = 0; //!< Íåîáõîäèìî äëÿ äðàéâåðà CANOpen è Unicon
TDataLog dlog = DATALOG_DEFAULTS; //!< Ìîäóëü îñöèëëîãðàôèðîâàíèÿ ïåðåìåííûõ CANOpen
TSM_Protect sm_prot = SM_PROTECT_DEFAULTS; //!< Ìîäóëü çàùèò
TSM_Ctrl sm_ctrl = SM_CTRL_DEFAULTS; //!< Ãëàâíûé äèñêðåòíûé àâòîìàò, ðåàëèçóåò ñòðóêòóðó óïðàâëåíèÿ
TSM_CmdLogic sm_cmd_logic = SM_CMD_LOGIC_DEFAULTS; //!< Îáðàáîòêà ïîëüçîâàòåëüñêèõ êîìàíä óïðàâëåíèÿ
TSM_Net sm_net = SM_NET_DEFAULTS; //!< Îáîëî÷êà äëÿ âûçîâà ñåòåâûõ äðàéâåðîâ
TRMPCtrl rmp = V_RMP_CTRL_DEFAULTS; //!< Çàäàò÷èê èíòåíñèâíîñòè
TAdcDrv adc = ADC_DRV_DEFAULTS; //!< Ìîäóëü ÀÖÏ
TPWM_Module pwm = PWM_Module_DEFAULTS; //!< Ìîäóëü ØÈÌ
TDPReCAP DPReCAP = DPRECAP_DEFAULTS; //!< Ìîäóëü ÄÏÐ íà ýëåìåíòàõ Õîëëà
TposspeedEqep posspeedEqep = POSSPEED_DEFAULTS; //!< Ìîäóëü ÄÏÐ òèïà ýíêîäåð
TCurPar cur_par = TCUR_PAR_DEFAULTS; //!< Ìîäóëü ðàñ÷åòà è õðàíåíèÿ òåêóùèõ ïîêàçàòåëåé ïðèâîäà - ìîùíîñòü, ñêîðîñòü
TUserMemory UserMem = USERMEMORY_DEFAULTS; //!< Ìîäóëü ðàáîòû ñ ýíåðãîíåçàâèñèìîé ïàìÿòüþ.
TUdControl udControl = UD_CONTROL_DEFAULTS; //!<Ïëàâíàÿ çàðÿäêà ÇÏÒ ÷åðåç òåðìèñòîðû
TAutoOffset AutoOffset = AUTO_OFFSET_DEFAULTS; //!<Àâòîìàòè÷åñêàÿ ïîäñòðîéêà ñìåùåíèÿ òîêîâ ÀÖÏ
TSSI_Encoder SSI_Encoder = SSI_ENCODER_DEFAULTS; //!<Äðàéâåð îáðàáîòêè äàò÷èêà ïîëîæåíèÿ ñ SSI èíòåðôåéñîì
TRotorObserver RotorObserver = ROTOR_OBSERVER_DEFAULTS; //!<Äàò÷èêîâûé íàáëþäàòåëü ïîòîêîñöåïëåíèÿ ðîòîðà àñèíõðîííîãî äâèãàòåëÿ
TCANtoRS CANtoRS = CAN_TO_RS_DEFAULTS; //!<Ìîäóëü äëÿ ðàáîòû ñ äðàéâåðîì CANopen ÷åðåç UART (RS). Ïîñûëêè CAN çàïàêîâûâàþòñÿ â UART
TDrvInterface drv_interface = DRV_INTERFACE_DEFAULTS; //!<Èíòåðôåéñ äëß ðàáîòû ñ áàíêàìè àâàðèé, ñîáûòèé è ò.ï.
TLogger FaultLog = LOGGER_DEFAULTS; //!<Ïðîòîêîëèðîâàíèå àâàðèé
TGlobalTime global_time = GLOBAL_TIME_DEFAULTS; //!<Ðàáîòà ñ ÷àñàìè
TFanControl fanControl = FAN_CONTROL_DEFAULTS; //!< Óïðàâëåíèå âåíòèëÿòîðîì
TbrakeResistor brakeResistor = BRAKE_RESISTOR_DEFAULTS; //! Óïðàâëåíèå ñëèâíûì ðåçèñòîðîì
TBitsToEnumNums pult_faults_lister = BITS_TO_ENUM_NUMS_DEFAULTS; //!<Ëèñòàëêà àâàðèé äëÿ Unicon
TRefs refs; //!< Ñòðóêòóðà ñ çàäàíèÿìè (òîêè, ñêîðîñòè)
TCmd cmd = { 0 }; //!< Ñòðóêòóðà ñ êîìàíäàìè óïðàâëåíèÿ
TDrvStatus drv_status = { 0 }; //!< Òåêóùèé ñòàòóñ ïðèâîäà
TDrvParams drv_params; //!< Ïàðàìåòðû äâèãàòåëÿ
TSysSwitches sw; //!< Ðàçëè÷íûå äèñêðåòíûå íàñòðîéêè ñèñòåìû óïðàâëåíèÿ
Uint32 VendorToken=0x11111111; //!< Óíèêàëüíûé êëþ÷ ïðîèçâîäèòåëÿ, íóæíûé äëÿ ïðîãðàììû UniCON è COODEdit äëÿ ðàçëè÷íûõ íàáîðîâ òåêñòîâ ðàçíûõ ïðîèçõâîäèòåëåé
int drv_status_code; //!<Ñòàòóñ ñèñòåìû óïðàâëåíèÿ â âèäå êîíñòàíòû (ÃÎÒÎÂ, ÐÀÁÎÒÀ è ò.ï.)
//Ïåðåìåííûå äëÿ îòëàäêè - âûâåäåíû â ñëîâàðü CANOpen,
// íèõ ìîæíî ïðèñâàèâàòü ëþáóþ äðóãóþ ïåðåìåííóþ è íàáëþäàòü å¸
//â UniCon, à òàêæå èñïîëüçîâàòü èõ íàïðÿìóþ â ÏÎ äëÿ îòëàäêè è ìåíÿòü íà õîäó.
volatile long Debug1 = 0;
volatile long Debug2 = 0;
volatile Uint16 Debug3 = 0;
volatile Uint16 Debug4 = 0;
volatile long DebugW1 = 0;
volatile long DebugW2 = 0;
volatile long DebugW3 = 0;
volatile long DebugW4 = 0;
volatile float DebugF1 = 0;
volatile float DebugF2 = 0;
volatile float DebugF3 = 0;
volatile float DebugF4 = 0;
//Ñ÷åò÷èêè ïðåðûâàíèé ìîäóëÿ çàõâàòà
Uint16 CounterCAP_isr = 0;
Uint16 cap0_counter = 0;
Uint16 cap1_counter = 0;
Uint16 cap2_counter = 0;
Uint16 LoopCounter = 0; //!< Ñ÷åò÷èê èòåðàöèé ôîíîâîãî öèêëà
//!Ñ ýòîé ôóíêöèè íà÷èíàåòñÿ çàïóñê ïðîãðàììû
//! \memberof MAIN_C
int main(void) {
co1_vars.co_productCode = 51;
co1_vars.co_revisionNumber = 1;
/* Íàñòðîéêà òàêòèðîâàíèÿ, âêëþ÷åíèå ïåðèôåðèè */
SystemInit(); // Íàñòðîéêà êëîêîâ
SystemCoreClockUpdate(); // Àïäåéòè ñèñòåìíûõ ïåðåìåííûõ íàñòðîåííûìè êëîêàìè (õç çà÷åì, íåîáÿçàòåëüíî)
pwm.Off(&pwm); //âûêëþ÷èòü ØÈÌ (íà âñÿêèé ñëó÷àé)
DINT;
//Èíèöèàëèçàöèÿ, ñîáñòâåííî, âñåãî.
sm_sys.init(&sm_sys);
EINT;//ðàçðåøåíèå ïðåðûâàíèé
//òèï è âåðñèÿ óñòðîéñòâà äëÿ äðàéâåðà CANOpen
while (1) { //Ôîíîâûé öèêë
LoopCounter++;
sm_sys.slow_calc(&sm_sys); //Ôîíîâûé ðàñ÷åò
}
}
unsigned long CpuTimerIsr1 = 0;
Uint16 TIsr1 = 0;
Uint16 msCounter = 0;
//! Ïðåðâûíèå, âûçûâàåìîå ïî òàéìåðó ñ ÷àñòîòîé 1êÃö
//! \memberof MAIN_C
void TMR1_IRQHandler(void) {
CpuTimerIsr1 = TMR2->VALUE; //Çàñåêàåòñÿ âðåìÿ âûïîëíåíèÿ ôóíêöèè
sm_sys.ms_calc(&sm_sys); //ìèëëèñåêóíäíûé ðàñ÷åò âñåãî
msCounter++;
TIsr1 = (CpuTimerIsr1 - TMR2->VALUE) & 0xFFFFFF; //âðåìÿ âûïîëíåíèÿ ôóíêöèè
if (TIsr1 > 97000) {
sm_prot.bit_fault1 |= F_PROGRAM_1K; //åñëè ðàñ÷åò ñëèøêîì äîëãèé, îøèáêà
}
TMR1->INTSTATUS_bit.INT = 1; //ñáðîñ ïðåðûâàíèÿ
}
Uint16 FastCounter = 0;
unsigned long CpuTimerIsr10 = 0;
Uint16 TIsr10 = 0;
//! Ïðåðâûíèå, âûçûâàåìîå ïî òàéìåðó ñ ÷àñòîòîé 10êÃö
//! \memberof MAIN_C
void TMR0_IRQHandler(void) {
CpuTimerIsr10 = TMR2->VALUE; //Çàñåêàåòñÿ âðåìÿ âûïîëíåíèÿ ôóíêöèè
sm_sys.fast_calc(&sm_sys); //ðàñ÷åò 10êÃö âñåãî
FastCounter++;
TIsr10 = (CpuTimerIsr10 - TMR2->VALUE) & 0xFFFFFF; //âðåìÿ âûïîëíåíèÿ ôóíêöèè
if (TIsr10 > 9700) {
sm_prot.bit_fault1 |= F_PROGRAM_10K; //åñëè ðàñ÷åò ñëèøêîì äîëãèé, îøèáêà
}
TMR0->INTSTATUS_bit.INT = 1; //ñáðîñ ïðåðûâàíèÿ
}
Uint16 ePWM0_TZ_isr_counter = 0;
//!Ïðåðûâàíèå, âîçíèêàþùåå ïðè àïïàðàòíîé àâàðèè
//! \memberof MAIN_C
#if defined (__GNUC__)
void PWM0_TZ_IRQHandler(void)
#elif defined (__CMCPPARM__)
void PWM0_TZ_IRQHandler(void)
#endif
{
//Òàê êàê àïïàðàòíàÿ àâàðèÿ âîçíèêàåò ïðè âêëþ÷åíèè ØÈÌ
//è óäåðæèâàåòñÿ ïîêà çàðÿæàþòñÿ áóäñòðåïíûå êîíäåíñàòîðû,
//â ïðåðûâàíèè íà íåå íå ðåàãèðóåì
//Õîòÿ â "íàñòîÿùåì" èíâåðòîðå íà âûñîêîå íàïðÿæåíèå ýòî, êîíå÷íî, íàäî äåëàòü
//Çäåñü ìèêðîñõåìà äðàéâåðîâ çàùèòèò âñ¸ ñàìà, òàêîãî âûõîäà ó íå¸ íåò
ePWM0_TZ_isr_counter++;
/*
pwm12.Off(&pwm12);
if (sm_ctrl.state!=CTRL_STOP)
{
sm_prot.bit_fault1|= F_PDPINT;
}
sm_ctrl.state=CTRL_STOP;
//ñáðàñûâàåì ôëàãè ïðåðûâàíèé ïî ýòîé íîæêå
*/
}
//!Ïðåðûâàíèå, âîçíèêàþùåå ïî ñîáûòèÿì çàõâàòà ìîäóëÿ CAP0
//! \memberof MAIN_C
#if defined (__GNUC__)
void ECAP0_IRQHandler(void)
#elif defined (__CMCPPARM__)
void CAP0_IRQHandler(void)
#endif
{
//Ïîäòâåðæäàåì ýòî ïðåðûâàíèå äëÿ NVIC - èíà÷å ïðè âûõîäå èç ôóíêöèè îíî âîçíèêíåò îïÿòü
ECAP0->PEINT = 1;
if (DPReCAP.CAPCalcEna1 == 0) { //åñëè ôóíêöèÿ âûçâàëàñü ïîâòîðíî
DPReCAP.CAP_WrongEdgeCnt = (++DPReCAP.CAP_WrongEdgeCnt) & 0xFF;
DPReCAP.CAP_WrongEdgeCnt1++;
return;
}
DPReCAP.CAPCalcEna1 = 0;//ðàñ÷åò áóäåò ðàçðåøåí, êîãäà òèêíåò ïðåðûâàíèå 10êÃö. ×àùå ñ÷èòàòü íåò ñìûñëà, ýòî ïîìåõè
CounterCAP_isr++;//îáùèé ñ÷¸ò÷èê âñåõ ïðåðûâàíèé ìîäóëÿ çàõâàòà
CounterCAP_isr = CounterCAP_isr & 0xF;
cap0_counter++;//ñ÷¸ò÷èê ïðåðûâàíèé èìåííî ýòîãî êàíàëà
//èñõîäÿ èç ñîñòîÿíèÿ íîã òðåõ äàò÷èêîâ Õîëëà âûñ÷èòûâàåò òåêóùèé óãîë ñ òî÷íîñòüþ 60 ãðàäóñîâ.
//âûõîäîì ôóíêöèè ÿâëÿåòñÿ DPReCAP.Angle6 - óãîë ñ òî÷íîñòüþ 60 ãðàäóñîâ.
DPReCAP.Angle6Calc(&DPReCAP);
//îáðàáîò÷èê ìîäóëÿ çàõâàòà êàíàëà1 (0, åñëè ñ÷èòàòü ñ íóëÿ, íî íå ïåðåèìåíîâûâàòü æå êàêæäûé ðàç ôóíêöèè, â çàâèñèìîñòè îò âåðñèè çàãîëîâî÷íûõ ôàéëîâ...).
//Çàñåêàåò âðåìÿ ìåæäó ýòèì èìïóëüñîì è ïðåäûäóùèìè äëÿ ðàñ÷åòà èíòåðïîëÿòîðà óãëà è ÷àñòîòû âðàùåíèÿ (ñêîðîñòè)
DPReCAP.CAP1Calc(&DPReCAP);
//Ïîäòâåðæäåíèå ïðåðûâàíèé ïðîèçâîäèòñÿ â 10 êÃö ïðåðûâàíèè
}
//!Ïðåðûâàíèå, âîçíèêàþùåå ïî ñîáûòèÿì çàõâàòà ìîäóëÿ CAP1
//! \memberof MAIN_C
#if defined (__GNUC__)
void ECAP1_IRQHandler(void)
#elif defined (__CMCPPARM__)
void CAP1_IRQHandler(void)
#endif
{
//Ïîäòâåðæäàåì ýòî ïðåðûâàíèå äëÿ NVIC - èíà÷å ïðè âûõîäå èç ôóíêöèè îíî âîçíèêíåò îïÿòü
ECAP1->PEINT = 1;
if (DPReCAP.CAPCalcEna2 == 0) { //åñëè ôóíêöèÿ âûçâàëàñü ïîâòîðíî
DPReCAP.CAP_WrongEdgeCnt = (++DPReCAP.CAP_WrongEdgeCnt) & 0xFF;
DPReCAP.CAP_WrongEdgeCnt2++;
return;
}
DPReCAP.CAPCalcEna2 = 0;
CounterCAP_isr++;
CounterCAP_isr = CounterCAP_isr & 0xF;
cap1_counter++;
DPReCAP.Angle6Calc(&DPReCAP);
DPReCAP.CAP2Calc(&DPReCAP);
//Ïîäòâåðæäåíèå ïðåðûâàíèé ïðîèçâîäèòñÿ â 10 êÃö ïðåðûâàíèè
}
//!Ïðåðûâàíèå, âîçíèêàþùåå ïî ñîáûòèÿì çàõâàòà ìîäóëÿ CAP2
//! \memberof MAIN_C
#if defined (__GNUC__)
void ECAP2_IRQHandler(void)
#elif defined (__CMCPPARM__)
void CAP2_IRQHandler(void)
#endif
{
//Ïîäòâåðæäàåì ýòî ïðåðûâàíèå äëÿ NVIC - èíà÷å ïðè âûõîäå èç ôóíêöèè îíî âîçíèêíåò îïÿòü
ECAP2->PEINT = 1;
if (DPReCAP.CAPCalcEna3 == 0) { //åñëè ôóíêöèÿ âûçâàëàñü ïîâòîðíî
DPReCAP.CAP_WrongEdgeCnt = (++DPReCAP.CAP_WrongEdgeCnt) & 0xFF;
DPReCAP.CAP_WrongEdgeCnt3++;
return;
}
DPReCAP.CAPCalcEna3 = 0;
CounterCAP_isr++;
CounterCAP_isr = CounterCAP_isr & 0xF;
cap2_counter++;
DPReCAP.Angle6Calc(&DPReCAP); //åñëè óáðàòü, òî â ìîìåíò ïðèõîäà ìåòêè íà îäèí ïåðèîä ØÈÌ êîñÿê, òàê êàê ïðåðûâàíèå ïîñ÷èòàëîñü, à Angle6Calc íåò
DPReCAP.CAP3Calc(&DPReCAP);
//Ïîäòâåðæäåíèå ïðåðûâàíèé ïðîèçâîäèòñÿ â 10 êÃö ïðåðûâàíèè
}
//!Ïðåðûâàíèå, âîçíèêàþùåå ïî ñîáûòèþ ðåïåðíîé ìåòêè(èíäåêñà) ìîäóëÿ QEP
//! \memberof MAIN_C
//! Íî - íà äâèãàòåëå ACM601V36-1000 íåò èíäåêñíîé ìåòêè.
//Òàê ÷òî ýòîãî ïðåðûâàíèÿ c òàêèì äâèãàòåëåì íå áóäåò (èëè áóäåò îò ïîìåõ, êàê ïîâåçåò)
#if defined (__GNUC__)
void QEP_IRQHandler(void)
#elif defined (__CMCPPARM__)
void QEP1_IRQHandler(void)
#endif
{
//Îáðàáîòêà ðåïåðà
posspeedEqep.index(&posspeedEqep);
//Ïîäòâåðæäàåì ýòî ïðåðûâàíèå äëÿ NVIC
QEP->INTCLR = 1;
QEP->QCLR_bit.IEL = 1;
QEP->QCLR_bit.INT = 1;
}
//Ïðåðûâàíèå âûçûâàåòñÿ îäèí ðàç íà ïåðèîäå ØÈÌ è çàáèðàåò 4 ðåçóëüòàòà çà ïåðèîä
void ADC_SEQ0_IRQHandler (void) {
adc.fast_calc(&adc);
dlog.update(&dlog); //Îñöèëëîãðàôèðîâàíèå äàííûõ
ADC->IC_bit.SEQIC0 = 1;
}
/*@}*/