Основные обновления в данном коммите:

- проект переведён на VectorIDE v1.3

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

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

Прочие изменения:
 - оптимизирована инициализация регистров периферии
 - удалено множество неиспользуемых переменных
 - разрешение работы всех GPIO перенесено в функцию "PeripheralClockEnable"
 - добавлен счётчик индексной метки энкодера
 - исправлен сброс прерываний модуля захвата CAP
 - переработан режим задания постоянного тока статора
- исправлены прочие мелкие ошибки в разных модулях
This commit is contained in:
Dmitry Shpak 2021-12-01 13:54:14 +03:00
parent d580349f63
commit a99491f9b8
50 changed files with 2657 additions and 2752 deletions

View File

@ -5,7 +5,7 @@
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-1690824301468933220" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT ARM Cross GCC Built-in Compiler Settings " parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="311310324716293368" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT ARM Cross GCC Built-in Compiler Settings " parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
@ -16,7 +16,7 @@
<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="-1711836428449608695" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT ARM Cross GCC Built-in Compiler Settings " parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="224227462986715429" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT ARM Cross GCC Built-in Compiler Settings " parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>

View File

@ -59,8 +59,8 @@ extern int __isr_vector_ram_end;
#define IRQ_PRIORITY_TZ 1
#define IRQ_PRIORITY_ADC 2
#define IRQ_PRIORITY_10K 3
#define IRQ_PRIORITY_CAP 4
#define IRQ_PRIORITY_CAP 3
#define IRQ_PRIORITY_10K 4
#define IRQ_PRIORITY_CAN 5
#define IRQ_PRIORITY_1K 6
#define IRQ_PRIORITY_EQEP 6

View File

@ -114,7 +114,9 @@ extern "C"
{
RELATIVE_TIME relative_time1;//!îòíîñèòåëüíîå âðåìß 1
RELATIVE_TIME relative_time2;//!îòíîñèòåëüíîå âðåìß 2
#ifdef USE_ABSOLUTE_TIME_CLOCK
ABSOLUTE_TIME absolute_time;//!àáñîëþòíîå âðåìß
#endif
int16 time_type;//!÷àñû ðåàëüíîãî âðåìåíè (1 - åñòü)
int32 PowerOn_time; //!<Îáùåå âðåìß íàðàáîòêè
int32 PowerOn_time_min; //!<Îáùåå âðåìß íàðàáîòêè â ìèíóòàõ
@ -146,18 +148,15 @@ extern "C"
#define ABSOLUTE_TIME_DEFAULTS {0,0,0,0,0}
//!Èíèöèàëèçàòîð TGlobalTime.
#define GLOBAL_TIME_DEFAULTS { RELATIVE_TIME_DEFAULTS,\
RELATIVE_TIME_DEFAULTS,\
ABSOLUTE_TIME_DEFAULTS,\
1,0,0,0,0,0,0,\
GlobalTime_init,\
GlobalTime_calc,\
GlobalTime_ms_calc,\
GlobalTime_slow_calc,\
GlobalTime_read_PowerOn_time, \
GlobalTime_write_PowerOn_time, \
GlobalTime_read_oper_time, \
GlobalTime_write_oper_time,\
#define GLOBAL_TIME_DEFAULTS { .time_type = 1,\
.init = GlobalTime_init,\
.calc = GlobalTime_calc,\
.ms_calc = GlobalTime_ms_calc,\
.slow_calc = GlobalTime_slow_calc,\
.read_PowerOn_time = GlobalTime_read_PowerOn_time, \
.write_PowerOn_time = GlobalTime_write_PowerOn_time, \
.read_oper_time = GlobalTime_read_oper_time, \
.write_oper_time = GlobalTime_write_oper_time,\
}
//! \memberof TGlobalTime

View File

@ -51,15 +51,11 @@ extern "C"
//! ñì. TSM_CmdLogic
struct SSM_CmdLogic
{
int state;//!<Cîñòîÿíèå
int state_prev;//!<Ïðåäûäóùåå ñîñòîÿíèå
int E;//!<Ôëàã ïåðâîãî âõîæäåíèÿ
int16 state;//!<Cостояние
int16 state_prev;//!<Предыдущее состояние
int16 E;//!<Флаг первого вхождения
TCmd cmd_by_level_prev;//!<Ïðåäûäóùåå ñîñòîÿíèå êîìàíäíîãî ñëîâà
int ReRunCounter;//!< Ñ÷åò÷èê âðåìåíè ñ ìîìåíòà ïðåäûäóùåãî çàïóñêà ñèñòåìû
int StartButtonPrev;
int StartButton;
int StopButtonPrev;
int StopButton;
void (*init)(volatile struct SSM_CmdLogic*);//!< Pointer to the init funcion
void (*slow_calc)(volatile struct SSM_CmdLogic*);//!< Pointer to the calc funtion
void (*ms_calc)(volatile struct SSM_CmdLogic*); //!< Pointer to the calc funtion
@ -68,10 +64,9 @@ extern "C"
typedef volatile struct SSM_CmdLogic TSM_CmdLogic;
//! Èíèöèàëèçàòð ïî óìîë÷àíèþ
#define SM_CMD_LOGIC_DEFAULTS {0,0,0,{0},0,0,0,0,0,\
SM_CmdLogicInit,\
SM_CmdLogicSlow_Calc,\
SM_CmdLogicms_Calc}
#define SM_CMD_LOGIC_DEFAULTS {.init = SM_CmdLogicInit,\
.slow_calc = SM_CmdLogicSlow_Calc,\
.ms_calc = SM_CmdLogicms_Calc}
//! \memberof TSM_CmdLogic
void SM_CmdLogicInit(TSM_CmdLogic*);

View File

@ -49,6 +49,7 @@ extern "C"
//! см. TSM_Sys
struct SSM_Sys
{
Uint16 ledPeriod, ledTimer; // Äëÿ ñâåòîäèîäà
int state;//!< Состояние
int state_prev;//!< Состояние предыдущее
int E;//!<Флаг первого вхождения
@ -61,11 +62,10 @@ extern "C"
typedef struct SSM_Sys TSM_Sys;
//!Инициализатор по умолчанию
#define SM_Sys_DEFAULTS {0,0,0,\
SM_Sys_Init,\
SM_Sys_Slow_Calc,\
SM_Sys_Fast_Calc,\
SM_Sys_ms_Calc,\
#define SM_Sys_DEFAULTS {.init = SM_Sys_Init,\
.slow_calc = SM_Sys_Slow_Calc,\
.fast_calc = SM_Sys_Fast_Calc,\
.ms_calc = SM_Sys_ms_Calc,\
}
//! \memberof TSM_Sys

View File

@ -43,7 +43,6 @@ extern "C"
_iq FilterK;//!< Êîýôôèöèåíò ôèëüòðà (òåìï èçìåíåíèÿ ñìåùåíèÿ)
int32 IA_int; //!< Èíòåãðàòîð äëÿ òîêà ôàçû A
int32 IB_int; //!< Èíòåãðàòîð äëÿ òîêà ôàçû B
int32 IC_int; //!< Číňĺăđŕňîđ äë˙ ňîęŕ ôŕçű C
int Enabled; //!< Âêëþ÷åíî/âûêëþ÷åíî
void (*init)(volatile struct SAutoOffset *);
void (*ms_calc)(volatile struct SAutoOffset *);
@ -56,7 +55,6 @@ extern "C"
#define AUTO_OFFSET_DEFAULTS {\
_IQ(0.0001),\
0,0,0,\
0,\
AutoOffset_init,\
AutoOffset_calc,\
AutoOffset_slow_calc}

View File

@ -0,0 +1,35 @@
/*
* V_BrakeResistor.h
*
* Created on: 11 sept. 2018 ã.
* Author: Lashkevich
*/
#ifndef VINCLUDE_V_BRAKE_RESISTOR_H_
#define VINCLUDE_V_BRAKE_RESISTOR_H_
#define BRAKE_R_STATE_ON 1
#define BRAKE_R_STATE_OFF 0
struct SbrakeResistor;
typedef volatile struct SbrakeResistor TbrakeResistor;
struct SbrakeResistor {
_iq upperLevel; // Íàïðÿæåíèå äëÿ âêëþ÷åíèÿ ðåçèñòîðà
_iq bottomLevel; // Íàïðÿæåíèå äëÿ âûêëþ÷åíèÿ ðåçèñòîðà
Uint16 state;
Uint16 enabled;
void (*init)(TbrakeResistor*);
void (*fastCalc)(TbrakeResistor*);
};
void BrakeResistor_Init (TbrakeResistor*);
void BrakeResistor_fastCalc (TbrakeResistor*);
#define BRAKE_RESISTOR_DEFAULTS {.init = BrakeResistor_Init,\
.fastCalc = BrakeResistor_fastCalc}
extern TbrakeResistor brakeResistor;
#endif /* VINCLUDE_V_BRAKE_RESISTOR_H_ */

View File

@ -42,19 +42,13 @@ extern "C" {
#include "CANOpen_drv.h"
struct SCANtoRS {
Uint16 lastActiveConnection; // Îïðåäåëÿåò, êàêîé èíòåðôåéñ áûë àêòèâåí â ïîñëåäíèé ðàç - USB èëè RS
Uint8 tempBuf[13]; // Âðåìåííûé áóôåð äëÿ äàííûõ
Uint16 test_dbg; //äëÿ îòëàäêè
Uint16 APIpacketMode;
int16 HeartBeatGo;//ïðîïóñòèòå ñåðäöåáèåíèå!
Uint16 callback_go; //ôëàã äëÿ âûçîâà callback
Uint16 TransmBusy; //ôëàã çàíÿòîñòè ïåðåäàò÷èêà
Uint16 PacketInWait; //ôëàã åñëè åñòü ÷òî-òî â áóôåðå îòïðàâêè
Uint16 HeartCounter; //ñ÷åò÷èê äëÿ îòïðàâêè HeartBeat
Uint16 TransmBusyTimeCount; //ñ÷åò÷èê òàéìàóòà çàíÿòîñòè ïåðåäàò÷èêà
Uint16 ReadPackDataCounter; //ñ÷åò÷èê äàííûõ â ïàêåòå
Uint16 ReadCRCCounter; //ñ÷åò÷èê äàííûõ â ïàêåòå
Uint16 SendTimeoutCounter;
Uint16 all_len; //transmit buf len
Uint16 tr_counter; //transmit counter
Uint16 MessDrop1;
@ -69,7 +63,6 @@ struct SCANtoRS {
Uint16 (*write)(TZCanMsg* MSG,volatile struct SCANtoRS *);
void (*callback)(TCo_OdVars* ppc, TZCanMsg* p);
unsigned char buf_out[CANTORS_BUFSIZE];
Uint16 temp_buf[CANTORS_BUFSIZE];
TZCanMsg MSG;
TZCanMsg bufMSG;
Uint16 ReadPackData[CANTORS_BUFSIZE]; //áóôåð äëÿ API ïîñûëêè

96
Vinclude/V_DIO.h Normal file
View File

@ -0,0 +1,96 @@
/*!
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_DIO.h
\brief Ìîäóëü äèñêðåòíûõ âõîäîâ/âûõîäîâ
\author ÎÎÎ "ÍÏÔ Âåêòîð". http://motorcontrol.ru
\version v 1.0 25/08/2017
\addtogroup
@{*/
#ifndef V_DIO_H
#define V_DIO_H
#ifdef __cplusplus
extern "C" {
#endif
// Ìàêðîñ óñòàíîâêè â '1' çàäàííîãî áèòà
// var - öåëåâàß ïåðåìåííàß
// index - èíäåêñ (ñìåùåíèå) óñòàíàâëèâàåìîãî áèòà
#define SET_BIT(var, index) var |= (1 << index);
// Ìàêðîñ ñáðîñà â '0' çàäàííîãî áèòà
// var - öåëåâàß ïåðåìåííàß
// index - èíäåêñ (ñìåùåíèå) î÷èùàåìîãî áèòà
#define CLEAR_BIT(var, index) var &= (~(1 << index));
// Ìàêðîñ ïðîâåðêè íåíóëåâîãî ñîñòîßíèÿ çàäàííîãî áèòà
// var - öåëåâàß ïåðåìåííàß
// index - èíäåêñ (ñìåùåíèå) ïðîâåðßåìîãî áèòà
#define BIT_IS_SET(var, index) ((var & (1 << index)) != 0)
// Ìàêðîñ ïðîâåðêè íóëåâîãî ñîñòîßíèÿ çàäàííîãî áèòà
// var - öåëåâàß ïåðåìåííàß
// index - èíäåêñ (ñìåùåíèå) ïðîâåðßåìîãî áèòà
#define BIT_IS_CLEAR(var, index) ((var & (1 << index)) == 0)
// Äåôàéíèì äèñêðåòíûå âõîäû
#ifdef HW_MOTORCONTROLBOARD
#define D_IN1 ((GPIOA->DATA & (1 << 14)) == 0) // Âõîä 1
#else
#define D_IN1 0
#endif
// Äåôàéíèì äèñêðåòíûå âûõîäû
#ifdef HW_MOTORCONTROLBOARD
#define D_OUT1_ON GPIOA->DATAOUTSET = (1 << 15)
#define D_OUT1_OFF GPIOA->DATAOUTCLR = (1 << 15)
#else
#define D_OUT1_ON
#define D_OUT1_OFF
#endif
// Âåêòîð ñîñòîßíèß äèñêðåòíûõ âûõîäîâ
extern volatile Uint8 output_vect;
// Âåêòîð ñîñòîßíèß äèñêðåòíûõ âõîäîâ
extern volatile Uint8 input_vect;
void DIO_Init();
void DIO_slow_calc(); // âûçûâàòü â ôîíîâîé ïðîãðàììå
void DIO_fast_calc(); // âûçûâàòü ñ ÷àñòîòîé 1êÃö èëè 10 êÃö
#ifdef __cplusplus
}
#endif
#endif
/*@}*/

View File

@ -85,11 +85,9 @@ Uint16 rsvd:
Uint32 PrevTspeed; // Предыдущая величина периода для расчёта скорости
Uint32 PrevTspeed1; // Предыдущая величина периода для расчёта скорости по датчику А.
Uint32 PrevTspeed11;
Uint32 PrevTspeed2; // Предыдущая величина периода для расчёта скорости по датчику B.
Uint32 PrevTspeed22;
Uint32 PrevTspeed3; // Предыдущая величина периода для расчёта скорости по датчику C.
Uint32 PrevTspeed33;
int16 CAPCalcEna1;
int16 CAPCalcEna2;
@ -136,29 +134,19 @@ Uint16 rsvd:
/******************************************************************************
Инициализация структуры по умолчанию
******************************************************************************/
#define DPRECAP_DEFAULTS \
{\
0,0,0,0,0,0,0,0,0, \
0,0,0,0,0, \
0,0,0,0,0,0, \
0,0,0,0,0,0,0,\
0,0,0,\
0,0,0,0,0,\
0,0,0,0,\
0,0,0,0,0,0,\
0,0,\
&DPReCAP_Init, \
&DPReCAP_AngleCalc, \
&DPReCAP_Angle6Calc, \
&DPReCAP_AngleErrorCalc, \
&DPReCAP_SpeedCalc, \
&DPReCAP_CAP1Calc, \
&DPReCAP_CAP2Calc, \
&DPReCAP_CAP3Calc, \
&DPReCAP_HelpCalc, \
&DPReCAP_SlowCalc, \
&DPReCAP_msCalc, \
&DPReCAP_calc_10k\
#define DPRECAP_DEFAULTS {\
.Init = DPReCAP_Init, \
.AngleCalc = DPReCAP_AngleCalc, \
.Angle6Calc = DPReCAP_Angle6Calc, \
.AngleErrorCalc = DPReCAP_AngleErrorCalc, \
.SpeedCalc = DPReCAP_SpeedCalc, \
.CAP1Calc = DPReCAP_CAP1Calc, \
.CAP2Calc = DPReCAP_CAP2Calc, \
.CAP3Calc = DPReCAP_CAP3Calc, \
.HelpCalc = DPReCAP_HelpCalc, \
.slow_calc = DPReCAP_SlowCalc, \
.ms_calc = DPReCAP_msCalc, \
.calc_10k = DPReCAP_calc_10k\
}
/******************************************************************************

87
Vinclude/V_Fan.h Normal file
View File

@ -0,0 +1,87 @@
/*!
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_Fan.h
\brief Ìîäóëü ðàáîòû âåíòèëÿòîðà
\author ÎÎÎ "ÍÏÔ Âåêòîð". http://motorcontrol.ru
\version v 1.0 25/08/2017
\addtogroup
@{*/
#ifndef V_FAN_H
#define V_FAN_H
//! âåíòèëÿòîð âûêëþ÷åí
#define FAN_CONTROL_STATE_OFF 0
//! âåíòèëÿòîð âêëþ÷åí
#define FAN_CONTROL_STATE_ON 1
//! ñîñòîÿíèå ïåðåãðåâà
#define FAN_CONTROL_STATE_OVERHEAT 2
/* Âêëþ÷åíèå è âûêëþ÷åíèå âåíòèëÿòîðà */
#if defined (HW_MOTORCONTROLBOARD)
#define FAN_ON GPIOB->MASKLB[16].MASKLB = 16 //NT_GPIOA->DATA |= (1 << 13)
#define FAN_OFF GPIOB->MASKLB[16].MASKLB = 0 //NT_GPIOA->DATA &= ~(1 << 13)
#endif
#if !defined (HW_MOTORCONTROLBOARD)
/* Äåôàéíû äëÿ äðóãèõ êîíòðîëëåðîâ */
#define FAN_ON
#define FAN_OFF
#endif
struct SFanControl{
Uint16 Enabled;
Uint16 manualOn; // Ïðèíóäèòåëüíîå âëêþ÷åíèå
int state; //!<ñîñòîÿíèå
int state_shadow;//!< ñîñòîÿíèå òåíåâîå
int state_prev;//!<ñîñòîÿíèå ïðåäûäóùåå
int StateOn;//!<äâîè÷íîå ñîñòîÿíèå: âêëþ÷åí/íå âêëþ÷åí
long T_on;//!<òåìïåðàòóðà âêëþ÷åíèÿ
long T_off;//!<òåìïåðàòóðà âûêëþ÷åíèÿ
long T_alarm;//!òåìïåðàòóðà âûâîäà ïðåäóïðåæäåíèÿ
long temperature; //! Òåìïåðàòóðà, ïî êîòîðîé îñóùåñòâëÿåòñÿ êîíòðîëü
void (*init)(volatile struct SFanControl*);
void (*slow_calc)(volatile struct SFanControl*);
};
typedef volatile struct SFanControl TFanControl;
//! \memberof TFanControl
void FanControl_init(TFanControl*);
//! \memberof TFanControl
void FanControl_slow_calc(TFanControl*); //ðàñ÷åò â ôîíîâîì ðåæèìå
#define FAN_CONTROL_DEFAULTS {0,0,\
FAN_CONTROL_STATE_OFF,FAN_CONTROL_STATE_OFF,FAN_CONTROL_STATE_OFF,0,\
_IQ(2.5),_IQ(2), _IQ(4), _IQ(0),\
FanControl_init,\
FanControl_slow_calc}
#endif
/*@}*/

View File

@ -1,90 +0,0 @@
/*!
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_MBVarsConv.h
\brief Ìîäóëü ïðåîáðàçîâàíèÿ äàííûõ Modbus
\author ÎÎÎ "ÍÏÔ ÂÅÊÒÎÐ"
\version v.1.1. 02/03/2017
\addtogroup v_ModBus
@{
*/
#ifndef V_MBVARSCONV_H
#define V_MBVARSCONV_H
#ifdef __cplusplus
extern "C" {
#endif
#include "DSP.h"
/*! \class TMBVarsConv
\brief Ìîäóëü ïðåîáðàçîâàíèÿ äàííûõ Modbus
Êëàññ \a TMBVarsConv, îñíîâàííûé íà ñòðóêòóðå SMBVarsConv, ïðåäíàçíà÷åí
äëÿ ïðåîáðàçîâàíèÿ äàííûõ èç ôîðìàòà 16 ðàçðÿäîâ Modbus â ôîðìàò ñèñòåìû óïðàâëåíèÿ (IQ 24).
*/
struct SMBVars{
int Command;
int CommandPrev;
int speed_ref;
int CurIs;
int CurSpeed;
int Main_ErrorCode;
int Umax_protect;
};
//!ñì. TMBVarsConv MBVars
#define SMBVARS_DEFAULTS {0,0,0,0,0,0}
struct SMBVarsConv{
struct SMBVars Vars;
Uint16 NeedForSave;
void (*init)(volatile struct SMBVarsConv*);
void (*calc)(volatile struct SMBVarsConv*);
void (*slow_calc)(volatile struct SMBVarsConv*);
};
typedef volatile struct SMBVarsConv TMBVarsConv;
//!Èíèöèàëèçàòîð ïî óìîë÷àíèþ
#define MBVARSCONV_DEFAULTS { SMBVARS_DEFAULTS,\
0,\
MBVarsConv_init,\
MBVarsConv_calc,\
MBVarsConv_slow_calc\
}
//! \memberof TMBVarsConv
void MBVarsConv_init(TMBVarsConv *p);
//! \memberof TMBVarsConv
void MBVarsConv_calc(TMBVarsConv *p);
//! \memberof TMBVarsConv
void MBVarsConv_slow_calc(TMBVarsConv *p);
#ifdef __cplusplus
}
#endif
#endif
/*@}*/

View File

@ -1,126 +0,0 @@
/*!
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_ModBus.h
\brief Äðàéâåð ModBus (ñì. TModBus)
\author Alecksey Anuchin
\version v 1.1 24/03/2017
\defgroup V_ModBus Äðàéâåð ModBus (ñì. TModBus)
@{
*/
#ifndef V_MODBUS_H
#define V_MODBUS_H
#ifdef __cplusplus
extern "C" {
#endif
#include "mbod.h"
#define MODBUS_MAX_RX_COUNT 10
/*! \class TModBus
\brief Äðàéâåð ModBus
Êëàññ \a TModBus, îñíîâàííûé íà ñòðóêòóðå SModBus, îáðàáàòûâàåò
âõîäÿùèå ïîñûëêè ïî RS-485 êàê ïîñûëêè ModBus (RTU). */
//! ñì. TModBus
//! Ñòðóêòóðà modbus äëÿ õðàíåíèÿ âíóòðåííèõ äàííûõ
typedef struct {volatile Uint16 In[MODBUS_MAX_RX_COUNT];//!<Ìàññèâ äëÿ ïðèíÿòèÿ äàííûõ
volatile Uint16 InCount;//!<Ñ÷åò÷èê äëÿ ìàññèâà ïðèíÿòûõ äàííûõ
volatile MB_Record /*const*/ *Addr;//!<Óêàçàòåëü íà ñëîâàðü
volatile Uint16 TimeOut;//!<Òåêóùèé òàéìàóò, êîòîðûé íàäî âûäåðæèâàòü
volatile Uint16 TimeOut1_5;//!<Ðàññ÷èòàííûé òàéìàóò 1,5 äëèíû ïåðåäàííîãî áàéòà
volatile Uint16 TimeOut2_5;//!<Ðàññ÷èòàííûé òàéìàóò 2,5 äëèíû ïåðåäàííîãî áàéòà
volatile Uint16 ToSend;//!<Äàííûå äëÿ îòïðàâêè
volatile Uint16 NumOfHRs;//!<Êîëè÷åñòâî Holding Registers
volatile Uint16 MiddleOfHRs;//!<Ñåðåäèíà Holding Registers
volatile Uint16 InitialStepOfHRs;//!<Øàã Holding Registers
volatile Uint16 NumOfIRs;//!<Êîëè÷åñòâî Input Registers
volatile Uint16 MiddleOfIRs;//!<Ñåðåäèíà Input Registers
volatile Uint16 InitialStepOfIRs;//!<Øàã Input Registers
volatile Uint16 NumOfCs;//!<Êîëè÷åñòâî Coils
volatile Uint16 MiddleOfCs;//!<Ñåðåäèíà Coils
volatile Uint16 InitialStepOfCs;//!<Øàã Coils
volatile Uint16 NumOfDIs;//!<Êîëè÷åñòâî Discrete Inputs
volatile Uint16 MiddleOfDIs;//!<Ñåðåäèíà Discrete Inputs
volatile Uint16 InitialStepOfDIs;//!<Øàã Discrete Inputs
volatile Uint16 RxCRC;//!<Ïðèíèìàåìàÿ êîíòðîëüíàÿ ñóììà
volatile Uint16 TxCRC;//!<Ïåðåäàâàåìàÿ êîíòðîëüíàÿ ñóììà
volatile Uint16 MagicNumber;//!<Ýì...
volatile int16 TxState;//!<Ñîñòîÿíèå ïåðåäà÷è
volatile Uint16 temp;//!<
volatile int16 RecievedCounter;//!<Ñ÷åò÷èê äëÿ îòñ÷èûâàíèÿ òàéìàóòà ïî ïðèåìó
UART_TypeDef *UART;//!Óêàçàòåëü íà èñïîëüçóåìûé ìîäóëü UART
} MODBUS_INT;
#define MODBUS_INT_DEFAULTS {{0},0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0xFFFF,0xFFFF, 0xA001,-1, 0,0, \
}
struct SModBus{Uint32 BaudRate;//!<Ñêîðîñòü ðàáîòû ïî RS
Uint16 ExecutionFreq;//!< ×àñòîòà òàêòèðîâàíèÿ ìîäóëÿ
Uint16 RSNodeID; //!< Íîìåð óçëà â ñåòè
Uint16 Enabled; //!< Ðàçðåøåíèå èçìåíåíèÿ ïàðàìåòðîâ ïðèâîäà ÷åðåç ModBus
Uint16 Refresh; //!< Ôëàã èçìåíåíèÿ ïàðàìåòðîâ ïî Modbus
int16 error;
int16 errorCode;
int16 AutoRestart;
int16 clear_error;
Uint16 received_data;
Uint16 GPIOsValue;
Uint16 isOnline;//!< Â ñåòè ìû èëè íåò (èäóò ëè ïàêåòû)
Uint32 OfflineCounter;//!< Ñ÷åò÷èê èíêðåìåíòèðóåòñÿ ñ ÷àñòîòîé âûçîâà ïðîöåäóðû ModBus_Execute è îáíóëÿåòñÿ, åñëè â ñåòè åñòü ïàêåòû
Uint32 OfflineCounterMax;//!< Òàéìàóò îòñóòñòâèÿ ïàêåòîâ â ñåòè (â åäèíèöàõ ñ÷¸òà OfflineCounter)
Uint16 ReceiveByteCounter;//!< Ñ÷åò÷èê ïðèíÿòûõ áàéò
Uint16 ReceivePacketCounter;//!< Ñ÷åò÷èê ïðèíÿòûõ ïîñûëîê
MODBUS_INT MBInternals;//!< Ñëóæåáíûå ïåðåìåííûå äëÿ ðàáîòû äðàéâåðà (íå äëÿ ïîëüçîâàòåëÿ)
void (*Init)(volatile struct SModBus*);
void (*Execute)(volatile struct SModBus*);
};
typedef volatile struct SModBus TModBus;
#define MODBUS_DEFAULTS {9600,10000, 0x01, 1, 0,\
0,0,0,0,0,0,0,0,0,0,0,\
MODBUS_INT_DEFAULTS,\
ModBus_Init, \
ModBus_Execute,\
}
//! \memberof TModBus
void ModBus_Init(TModBus *p);
//! \memberof TModBus
void ModBus_Execute(TModBus *p);
//! \memberof TModBus
int16 ModBus_FindVocAddr(TModBus *p,volatile MB_Record Table[], Uint16 TableSize, int16 Type, Uint16 Index, int16 NumOfIndexs, int16 Mid, int16 Step);
#ifdef __cplusplus
}
#endif
#endif
/*@}*/

View File

@ -184,7 +184,7 @@ Uint16 rsvd:
union SPOSSPEED_FLG1 Posspeed_FLG1;
union SPOSSPEED_FLG2 Posspeed_FLG2;
Uint16 GPIOsValue;//!< Òåêóùåå çíà÷åíèå íîæåê GPIO ìîäóëÿ QEP
Uint16 Index_eventFlag;
Uint16 Index_eventCounter;
Uint16 UPPS_forWatch;//!< Òåêóùåå çíà÷åíèå UPPS
_iq AngleOffset;//!< Ñìåùåíèå ýëåêòðè÷åñêîãî óãëà â ãðàäóñàõ
int16 RevolutionCounter; // Êîëè÷åñòâî ìåõàíè÷åñêèõ îáîðîòîâ;
@ -211,13 +211,11 @@ Uint16 rsvd:
typedef volatile struct SposspeedEqep TposspeedEqep;
//! Èíèöèàëèçàòîð ïî-óìîë÷àíèþ.
#define POSSPEED_DEFAULTS {0,0,0,0,0, 0,0,0,0,0,0,0, 0,0,0,0, 0,{0},{0},0,0,FILTER_DEFAULTS,0,\
0,0x0790,0,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,\
TposspeedEqep_init,\
TposspeedEqep_Calc,\
TposspeedEqep_SlowCalc,\
TposspeedEqep_IndexEvent,\
#define POSSPEED_DEFAULTS {.speed_filter = FILTER_DEFAULTS,\
.init = TposspeedEqep_init,\
.calc = TposspeedEqep_Calc,\
.slow_calc = TposspeedEqep_SlowCalc,\
.index = TposspeedEqep_IndexEvent,\
}
//! \memberof TposspeedEqep

View File

@ -1,83 +0,0 @@
/*!
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_RTC_Clock.h
\brief Ìîäóëü ðàáîòû ñ ÷àñàìè ðåàëüíîãî âðåìåíè
\author ÎÎÎ "ÍÏÔ Âåêòîð". Âñå ïðàâà çàùèùåíû. http://motorcontrol.ru
\version v 2.0 25/03/2016
\defgroup V_rmp_ctrl Çàäàò÷èê èíòåíñèâíîñòè (ñì. TRMPCtrl)
@{
*/
#ifndef V_RTC_CLOCK_H_
#define V_RTC_CLOCK_H_
#define RTC_SLAVE_ADDRESS 0x68 // Äëÿ RTC DS1340 àäðåñ 1101 000b = 0x68 (õîòÿ â ðóêîâîäñòâå îíè åãî êàê áû äîïîëíÿþò íóë¸ì
// è ïîëó÷àþò 1101 0000b = 0xD0)
#define RTC_WRITE_ERROR 1
#define RTC_READ_ERROR 2
#define RTC_TIMEOUT_ERROR 3
#define RTC_TIMEOUT 1000 // Êîëè÷åñòâî îæèäàíèÿ øèíû
#define RTC_SECOND_WAITING_TIMEOUT 10000 // Âðåìÿ, â òå÷åíèå êîòîðîãî äîëæíà ñìåíèòüñÿ ñåêóíäà (çàäàåòñÿ â ìñ). Åñëè íå ìåíÿåòñÿ, çíà÷èò ÷àñû íå ðàáîòàþò.
struct SRTCClock{
Uint16 ms; // Íà âñÿêèé
Uint16 msInDay; // Ìèëèïèñþëè ñ íà÷àëà ñóòîê
Uint16 error; // Êîä îøèáêè
Uint16 tryCounter; // Ñ÷åò÷èê îæèäàíèé øèíû
Uint16 second;
Uint16 minute;
Uint16 hour;
Uint16 DOW; // DayOfWeek - äåíü íåäåëè (ïóñòü áóäåò, ÷òî, æàëêî ÷òî ëè?)
Uint16 day; // Date - ýòî ÷èñëî ìåñÿöà
Uint16 month;
Uint16 year;
Uint32 packed_time; // Âðåìÿ, óïàêîâàííîå â ñëîâî
Uint32 timeToSet; // Âðåìÿ, êîòîðîå íóæíî óñòàíîâèòü íà ÷àñàõ, óïàêîâàííîå â ñëîâî
Uint16 setTimeFlag;
Uint16 readTimeFlag;
Uint16 secondPrev;
Uint16 stoppedCounter;
Uint16 ClockOk;
void (*init)(volatile struct SRTCClock*); // Èíèöèàëèçàöèÿ
void (*read)(volatile struct SRTCClock*); // Ïðî÷èòàòü âðåìÿ èç ÷àñèêîâ
void (*set)(volatile struct SRTCClock*); // Ïèñüíóòü âðåìÿ â ÷àñèêè
void (*msCalc)(volatile struct SRTCClock*);
void (*slowCalc)(volatile struct SRTCClock*);
};
typedef volatile struct SRTCClock TRTCClock;
#define RTC_CLOCK_DEFAULTS {0,0,0,0, 0,0,0, 0,0,0,0, 0,0, 0,0, 0,0,0,\
RTC_Clock_Init,\
RTC_Clock_Read_Time,\
RTC_Clock_Set_Time,\
RTC_Clock_Ms_Calc,\
RTC_Clock_Slow_Calc}
void RTC_Clock_Init (TRTCClock *);
void RTC_Clock_Read_Time (TRTCClock *);
void RTC_Clock_Set_Time (TRTCClock *);
void RTC_Clock_Ms_Calc (TRTCClock *);
void RTC_Clock_Slow_Calc (TRTCClock *);
#endif /* V_I2CCLOCK_H_ */

View File

@ -29,6 +29,13 @@
#ifndef V_SSI_ENCODER_H
#define V_SSI_ENCODER_H
// Ðàçðåøåíèå ýíêîäåðà
#define SSI_ENC_RESOLUTION 12
// Èç-çà îñîáåííîñòåé ñõåìû, áóäåò ïðèíèìàòüñÿ íà 1 áèò áîëüøå, ÷åì íàäî,
// ïîýòîìó ñòàðøèé áóäåì îáíóëÿòü ýòîé ìàñêîé
#define SSI_ENC_DATA_MASK ((1 << SSI_ENC_RESOLUTION) - 1)
#ifdef __cplusplus
extern "C" {
#endif
@ -83,10 +90,9 @@ extern "C" {
typedef volatile struct S_SSI_Encoder TSSI_Encoder;
//! Èíèöèàëèçàòîð ïî-óìîë÷àíèþ.
#define SSI_ENCODER_DEFAULTS {0,0,0,0, 0,0,0,0, 0,0,0,0,0,0, 0,0, 0,0,0,0,0,\
SSI_Encoder_init,\
SSI_Encoder_Calc,\
SSI_Encoder_Read,\
#define SSI_ENCODER_DEFAULTS {.init = SSI_Encoder_init,\
.calc = SSI_Encoder_Calc,\
.read = SSI_Encoder_Read,\
}
//! \memberof TSSI_Encoder
@ -96,7 +102,7 @@ extern "C" {
//! \memberof TSSI_Encoder
void SSI_Encoder_Read(TSSI_Encoder*);
#ifdef __cplusplus
#ifdef __cplusplus
}
#endif

104
Vinclude/V_UdControl.h Normal file
View File

@ -0,0 +1,104 @@
/*!
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_UdControl.h
\brief Ìîäóëü ïëàâíîãî çàðÿäà ÇÏÒ
\author ÎÎÎ "ÍÏÔ Âåêòîð". http://motorcontrol.ru
\version v 1.0 25/08/2017
\addtogroup
@{*/
#ifndef V_UD_CONTROL_H
#define V_UD_CONTROL_H
#include "build.h"
#ifdef __cplusplus
extern "C" {
#endif
//! ñîñòîÿíèå âûêëþ÷åíî
#define UD_CONTROL_STATE_OFF 0
//! ñîñòîÿíèå îæèäàíèÿ âêëþ÷åíèÿ
#define UD_CONTROL_STATE_WAIT 1
//! ñîñòîÿíèå âêëþ÷åíî
#define UD_CONTROL_STATE_ON 2
/*! \class TUdControl
\brief Óïðàâëåíèå öåïüþ çàðÿäà çâåíà ïîñòîÿííîãî òîêà
Êëàññ \a TUdControl, îñíîâàííûé íà ñòðóêòóðå SUdControl, ñëóæèò
äëÿ óïðàâëåíèÿ äèñêðåòíûì âûõîäîì, êîòîðûé çàìûêàåò öåïü çàðÿäà
çâåíà ïîñòîÿííîãî òîêà. Ïåðåä âêëþ÷åíèåì ñëåäóþò òðè ïðîâåðêè:
âûäåðæêà òàéìàóòà, ïðåâûøåíèå íàïðÿæåíèÿ âûøå çàäàííîé óñòàâêè è
âûïîëàæèâàíèå êðèâîé íàïðÿæåíèÿ (ïðîèçâîäíàÿ ñòðåìèòñÿ ê íóëþ).
*/
//!ñì. TUdControl
struct SUdControl{
Uint16 Enabled;
int fault_start; //!<ïîïûòêà ïóñêà ïðè íåçàøóíòèðîâàííîì ðåëå
int state; //!<ñîñòîÿíèå
int state_prev;//!<ñîñòîÿíèå ïðåäûäóùåå
int E;//!<ôëàã ïåðâîãî âõîæäåíèÿ
int StateCounter;//!<ñ÷åò÷èê âðåìåíè íàõîæäåíèÿ â ñîñòîÿíèè
long fUdc_output_prev;//!<çíà÷åíèÿ íàïðÿæåíèÿ ïðåäûäóùåå
long U_on;//!<íàïðÿæåíèå âêëþ÷åíèÿ
long U_off;//!<íàïðÿæåíèå âûêëþ÷åíèÿ
long Timeout_on;//!<òàéìàóò âêëþ÷åíèÿ â ìñ.
long deriv_time_ZPT; //!<ïðîèçâîäíàÿ ïî íàïðÿæåíèþ íà ìèëëèñåêóíäå
long deriv_const; //!<êîíñòàíòà óñòàâêè ñðàâíåíèÿ ïðîèçâîäíîé
int StateOn;//!<äâîè÷íîå ñîñòîÿíèå: âêëþ÷åí/íå âêëþ÷åí
TFilter fUdc;//!<ôèëüòð íàïðÿæåíèÿ íà ÇÏÒ
void (*init)(volatile struct SUdControl*);
void (*calc)(volatile struct SUdControl*);
};
typedef volatile struct SUdControl TUdControl;
//! \memberof TUdControl
void UdControl_init(TUdControl*);
//! \memberof TUdControl
void UdControl_calc(TUdControl*);
#define UD_CONTROL_DEFAULTS {0,0,UD_CONTROL_STATE_OFF,UD_CONTROL_STATE_OFF,\
0,0,0,\
_IQ(0.8),_IQ(0.5),3000,0,\
0,0, FILTER_DEFAULTS,\
UdControl_init,\
UdControl_calc}
#ifdef __cplusplus
}
#endif
#endif
/*@}*/

View File

@ -53,30 +53,13 @@ extern "C"
int32 IaGainNom; //!< Âñïîìîãàòåëüíûé êîýôô. óñèëåíèÿ.
int32 IA_temp; //!<Âðåìåííàÿ ïåðåìåííàÿ
int16 IASampleLength; //длина выборки (кол-во точек на периоде ШИМ)
int16 IAPointer; //номер последней выборки
int16 IABuf[4]; //массив точек для усреднения
int16 Imeas_b_gain;
int16 Imeas_b_offset;
int32 Imeas_b;
int32 IbGainNom;
int32 IB_temp;
int16 IBSampleLength; //длина выборки (кол-во точек на периоде ШИМ)
int16 IBPointer; //номер последней выборки
int16 IBBuf[4]; //массив точек для усреднения
int16 Imeas_c_gain;
int16 Imeas_c_offset;
int32 Imeas_c;
int32 IcGainNom;
int16 IC_temp;
int16 ICSampleLength; //длина выборки (кол-во точек на периоде ШИМ)
int16 ICPointer; //номер последней выборки
int16 ICBuf[4]; //массив точек для усреднения
int16 Udc_meas_gain;
int16 Udc_meas_offset;
@ -84,14 +67,10 @@ extern "C"
int32 UdcGainNom;
int16 Udc_temp;
int16 UdcSampleLength; //длина выборки (кол-во точек на периоде ШИМ)
int16 UdcPointer; //номер последней выборки
int16 UdcBuf[4]; //массив точек для усреднения
int16 T_meas_gain; //!< Коэффициент усиления.
int32 T_meas; //!< Измеренное значение усредненное.
int32 TGainNom; //!< Вспомогательный коэфф. усиления.
int16 T_temp; //!<Временная переменная
int16 AI_meas_gain; //!< Коэффициент усиления аналогового входа
int32 AI_meas; //!< Измеренное значение усредненное.
int32 AIGainNom; //!< Вспомогательный коэфф. усиления.
int16 AI_temp; //!< Временная переменная
void (*init)(struct SAdcDrv *);
void (*fast_calc)(struct SAdcDrv*);
@ -105,13 +84,9 @@ extern "C"
//!Èíèöèàëèçàòîð ïî óìîë÷àíèþ.
#define ADC_DRV_DEFAULTS {\
54,0,0,0,0, \
4,0,{0}, \
54,0,0,0,0, \
4,0,{0}, \
54,0,0,0,0, \
4,0,{0}, \
0,\
800,0,0,0,0, \
4,0,{0}, \
100,0,0,0, \
AdcDrv_init,\
AdcDrv_fast_calc,\

View File

@ -1,25 +1,25 @@
/*!
Copyright 2017 ÀÎ "ÍÈÈÝÒ" è ÎÎÎ "ÍÏÔ ÂÅÊÒÎÐ"
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
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
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.
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_common.h
\brief Îáúÿâëåíèå ñòðóêòóð äàííûõ ðàçëè÷íîãî íàçíà÷åíèÿ, êîòîðûå åùå ñëèøêîì ìàëû äëÿ òîãî, ÷òîáû
îðãàíèçîâûâàòü èõ â îòäåëüíûé ìîäóëü
\author ÎÎÎ "ÍÏÔ Âåêòîð". Âñå ïðàâà çàùèùåíû. http://motorcontrol.ru
\version v 2.0 25/03/2016
\file v_common.h
\brief Îáúÿâëåíèå ñòðóêòóð äàííûõ ðàçëè÷íîãî íàçíà÷åíèÿ, êîòîðûå åùå ñëèøêîì ìàëû äëÿ òîãî, ÷òîáû
îðãàíèçîâûâàòü èõ â îòäåëüíûé ìîäóëü
\author ÎÎÎ "ÍÏÔ Âåêòîð". Âñå ïðàâà çàùèùåíû. http://motorcontrol.ru
\version v 2.0 25/03/2016
\defgroup v_common Îáúÿâëåíèå ñòðóêòóð äàííûõ ðàçëè÷íîãî íàçíà÷åíèÿ
\defgroup v_common Îáúÿâëåíèå ñòðóêòóð äàííûõ ðàçëè÷íîãî íàçíà÷åíèÿ
@{*/
@ -33,90 +33,85 @@ extern "C"
//!Битовое поле для битового статуса системы управления
typedef struct
{
unsigned int ready:
1;
unsigned int running:
1;
unsigned int fault:
1;
unsigned int alarm:
1;
unsigned int testing:
1;
unsigned int overheat:
1;
} DRV_STATUS_BIT;
typedef struct
{
unsigned int ready :1;
unsigned int running :1;
unsigned int fault :1;
unsigned int alarm :1;
unsigned int testing :1;
unsigned int overheat :1;
} DRV_STATUS_BIT;
//!Структура для статуса системы управления (содержит DRV_STATUS_BIT)
typedef union
{
int all;
DRV_STATUS_BIT bit;
}TDrvStatus;
typedef union
{
int all;
DRV_STATUS_BIT bit;
}TDrvStatus;
//!Битовое поле слова управления
typedef struct
{
unsigned int start:
1;
unsigned int stop:
1;
unsigned int trip_reset:
1;
unsigned int reserved:
5;
} CMD_BIT;
typedef struct
{
unsigned int start :1;
unsigned int stop :1;
unsigned int trip_reset :1;
unsigned int reserved :5;
} CMD_BIT;
//!Структура слова управления (содержит DRV_STATUS_BIT)
typedef union
{
unsigned int all;
CMD_BIT bit;
}TCmd;
typedef union
{
unsigned int all;
CMD_BIT bit;
}TCmd;
//! Структура, содержащия основные задания для привода
typedef volatile struct
{
long speed_ref;//!< Çàäàíèå ñêîðîñòè
long Iq_ref;//!< Çàäàíèå òîêîîãðàíè÷åíèÿ äëÿ âåêòîðíîé ñèñòåìû óïðàâëåíèÿ
long i_flux_ref;//!< Çàäàíèå òîêà äëÿ çàìêíóòîé ïî òîêó ñèñòåìû óïðàâëåíèÿ (íå âåêòîðíîé)
long theta_elec;//!< Çàäàíèå óãëîâîãî ïîëîæåíèÿ âåêòîðà òîêà/íàïðÿæåíèÿ
typedef volatile struct
{
long speed_ref;//!< Çàäàíèå ñêîðîñòè
long Iq_ref;//!< Çàäàíèå òîêîîãðàíè÷åíèÿ äëÿ âåêòîðíîé ñèñòåìû óïðàâëåíèÿ
long i_flux_ref;//!< Çàäàíèå òîêà äëÿ çàìêíóòîé ïî òîêó ñèñòåìû óïðàâëåíèÿ (íå âåêòîðíîé)
long theta_elec;//!< Çàäàíèå óãëîâîãî ïîëîæåíèÿ âåêòîðà òîêà/íàïðÿæåíèÿ
long ua_ref, uf_ref; // Задания тока якоря и тока ОВ для ДПТ
long DCMspeed_ref;//!< Задание скорости
} TRefs;
} TRefs;
//! Структура для хранения параметров привода, двигателя, базовых величин системы управления
typedef struct
{
long Rs;//!< Ñîïðîòèâëåíèå ôàçû ñòàòîðà
long Ls;//!< Èíäóêòèâíîñòü ôàçû ñòàòîðà
int p;//!< Êîëè÷åñòâî ïàð ïîëþñîâ
int I_nom;//!< Íîìèíàëüíûé (áàçîâûé) ôàçíûé òîê â ôîðìàòå 16.0
long _1_I_nom;//!< 1/I_nom
int U_nom;//!< Íîìèíàëüíîå (áàçîâîå) ôàçíîå íàïðÿæåíèå â ôîðìàòå 16.0
long _1_U_nom;//!< 1/U_nom
int Udc_nom;//!< Íîìèíàëüíîå (áàçîâîå) íàïðÿæåíèå ÇÏÒ â ôîðìàòå 16.0
long _1_Udc_nom;//!< 1/Udc_nom
int speed_nom;//!< Íîìèíàëüíàÿ (áàçîâàÿ) ñêîðîñòü â ôîðìàòå 16.0
int freq_nom;//!< Íîìèíàëüíàÿ (áàçîâàÿ) ÷àñòîòà â ôîðìàòå 16.0
int power;//!< Íîìèíàëüíàÿ (áàçîâàÿ) ìîùíîñòü â ôîðìàòå 16.0
int sens_type;//!< Òèï äàò÷èêà ïîëîæåíèÿ
} TDrvParams;
typedef struct
{
long Rs;//!< Ñîïðîòèâëåíèå ôàçû ñòàòîðà
long Ls;//!< Èíäóêòèâíîñòü ôàçû ñòàòîðà
int p;//!< Êîëè÷åñòâî ïàð ïîëþñîâ
int I_nom;//!< Íîìèíàëüíûé (áàçîâûé) ôàçíûé òîê â ôîðìàòå 16.0
long _1_I_nom;//!< 1/I_nom
int U_nom;//!< Íîìèíàëüíîå (áàçîâîå) ôàçíîå íàïðÿæåíèå â ôîðìàòå 16.0
long _1_U_nom;//!< 1/U_nom
int Udc_nom;//!< Íîìèíàëüíîå (áàçîâîå) íàïðÿæåíèå ÇÏÒ â ôîðìàòå 16.0
long _1_Udc_nom;//!< 1/Udc_nom
int speed_nom;//!< Íîìèíàëüíàÿ (áàçîâàÿ) ñêîðîñòü â ôîðìàòå 16.0
int freq_nom;//!< Íîìèíàëüíàÿ (áàçîâàÿ) ÷àñòîòà â ôîðìàòå 16.0
int power;//!< Íîìèíàëüíàÿ (áàçîâàÿ) ìîùíîñòü â ôîðìàòå 16.0
int sens_type;//!< Òèï äàò÷èêà ïîëîæåíèÿ
} TDrvParams;
//! Ñòðóêòóðà äëÿ áèòîâûõ "ïåðåêëþ÷àòåëåé", òàêèõ êàê íàïðàâëåíèå âðàùåíèÿ, ðàçðåøåíèå ðåêóïåðàöèè è ò.ï.
typedef struct {
Uint16 recuperation_ena;//!< Ðàçðåøåíèå ðåêóïåðàöèè ýíåðãèè ïðè òîðìîæåíèè
Uint16 rotation_dir;//!< Íàïðàâëåíèå âðàùåíèÿ
Uint16 Reboot;//!< Ïðîãðàììíàÿ ïåðåçàãðóçêà
Uint16 AutoOffset;//!< àâòîñìåùåíèå ÀÖÏ
Uint16 HardwareType;//!< Òèï æåëåçà, ïîä êîòîðûé ñîáðàí ïðîåêò
Uint16 excitation_ena;//!< Ðàçðåøåíèå âîçáóäèòåëÿ
} TSysSwitches;
struct SsysSwitches {
Uint16 recuperation_ena :1; //!< 0 Ðàçðåøåíèå ðåêóïåðàöèè ýíåðãèè ïðè òîðìîæåíèè
Uint16 Reboot :1; //!< 1 Ïðîãðàììíàÿ ïåðåçàãðóçêà
Uint16 AutoOffset :1; //!< 2 àâòîñìåùåíèå ÀÖÏ
Uint16 use_led :1; //!< 3 Èñïîëüçîâàòü ñâåòîäèîä âìåñòî JTAG
Uint16 use_led_prev :1; //!< 4 Èñïîëüçîâàòü ñâåòîäèîä âìåñòî JTAG
Uint16 :11;
};
typedef union {
struct SsysSwitches bit;
Uint16 all;
} TSysSwitches;
#ifdef __cplusplus
}

View File

@ -104,7 +104,7 @@ typedef volatile struct SLogger TLogger;
//т.к. часов реального времени нет (МК 30.1), в качестве временнОго маркера аварий используется время включенного состояния
#define LOGGER_DEFAULTS {0,0,0,1,0,\
(Uint32*)&RTCclock.packed_time,\
(Uint32*)&global_time.PowerOn_time,\
{0,0,0,0},0,0,0,0,0,\
EVENT_FIFO_DEFAULTS,\
Logger_Init,\

View File

@ -1,68 +0,0 @@
/*!
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 Vled.h
\brief Óïðàâëåíèå ñâåòîäèîäàìè
\author ÎÎÎ "ÍÏÔ Âåêòîð". http://motorcontrol.ru
\version v 2.0 25/03/2016
*/
#ifndef VINCLUDE_V_LED_H_
#define VINCLUDE_V_LED_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include "DSP.h"
#define LED1 0
#define LED2 1
#define LED3 2
#define LED4 3
#define LED5 4
#define LED6 5
#define LED_ALL 6
struct Sled;
typedef volatile struct Sled Tled;
struct Sled{
Uint16 timer1, timer2, timer3, timer4, timer5, timer6;
Uint16 mode, prevMode;
Uint16 mode3counter;
void (*init)(Tled*);
void (*toggle)(Tled*, Uint16);
void (*on)(Tled*, Uint16);
void (*off)(Tled*, Uint16);
void (*msCalc)(Tled*);
};
#define LED_DEFAULTS {0,0,0,0,0,0,0,0,0, LED_init, LED_toggle, LED_on, LED_off, LED_msCalc}
void LED_init (Tled*);
void LED_toggle (Tled*, Uint16);
void LED_on (Tled*, Uint16);
void LED_off (Tled*, Uint16);
void LED_msCalc (Tled*);
#ifdef __cplusplus
}
#endif
#endif /* VINCLUDE_V_LED_H_ */

View File

@ -1,108 +0,0 @@
/*!
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_pid_reg3.h
\brief ÏÈÄ-ðåãóëÿòîð (ñì. TPidReg3)
\author ÎÎÎ "ÍÏÔ Âåêòîð". http://motorcontrol.ru
\version v 2.0 25/03/2016
\defgroup V_pid_reg3 ÏÈÄ-ðåãóëÿòîð
@{*/
#ifndef PID_REG3_POS_H
#define PID_REG3_POS_H
#ifdef __cplusplus
extern "C" {
#endif
/*! \class TPidReg3
\brief Ìîäóëü ÏÈÄ-ðåãóëÿòîðà
Êëàññ \a TPidReg3, îñíîâàííûé íà ñòðóêòóðå SPidReg3, ïðåäñòàâëÿåò
ñîáîé ïðîïîðöèîíàëüíî - èíòåãðàëüíî - äèôôåðåíöèàëüíûé ðåãóëÿòîð.
Âñå êîýôôèöèåíòû íàñòðàèâàåìûå, äèôôåðåíöèàëüíàÿ ÷àñòü èìååò íàñòðàèâàåìûé ôèëüòð.
*/
//! ñì. TPidReg3
typedef struct SPidReg3_pos{ long pid_ref_reg3; //!< Input: Reference input
long pid_fdb_reg3;//!< Input: Feedback input
long e_reg3;//!<Variable: Error
long e_reg3Dz;//!<Variable: Error after dead zone
long Kp_reg3;//!< Parameter: Proportional gain
long up_reg3;//!< Variable: Proportional output
long ui_reg3;//!< Variable: Integral output
long ud_reg3;//!< Variable: Derivative output
long uprsat_reg3;//!< Variable: Pre-saturated output
long saterr_reg3Add;//!< Variable: Äîïîëíèòåëüíàÿ îøèáêà íàñûùåíèÿ îò "âåðõíåãî óðîâíÿ"
long pid_out_max;//!< Parameter: Maximum output
long pid_out_min;//!< Parameter: Minimum output
long pid_out_reg3;//!< Output: PID output */
long saterr_reg3;//!< Variable: Saturated difference
long Ki_reg3;//!< Parameter: Integral gain
long Kc_reg3;//!< Parameter: Integral correction gain
long Kd_reg3;//!< Parameter: Derivative gain
long up1_reg3;//!< History: Previous proportional output
long pid_out_test;//!< Output: PID output for test
long DeadZone;//!< Ìåðòâàÿ çîíà
long Kf_d;//!<Ôèëüòð äèôôåðåíöèàëüíîé ÷àñòè
long e_reg3_filterOut;//!<Âûõîä ôèëüòðà äèôôåðåíöèàëüíîé ÷àñòè
long DiffDelim;//!<Äåëèòåëü äëÿ òàêòèðîâàíèÿ ðàñ÷åòà ïðîèçâîäíîé
long DiffCounter;//!<Ñ÷åò÷èê äëÿ äåëèòåëÿ
int KdFilterInitFlag;//!<Ôëàã ïåðâîãî çàïóñêà äëÿ èíèöèàëèçàöèè ôèëüòðà äèôô. ÷àñòè
void (*calc)(struct SPidReg3_pos*);//!< Pointer to calculation function
void (*reset)(struct SPidReg3_pos*);//!< Pointer to reset function
}TPidReg3_pos;
//! Èíèöèàëèçàòîð ïî-óìîë÷àíèþ
#define PIDREG3_DEFAULTS_POS { 0,0, \
0, \
0, \
0, \
0, \
0, \
0, \
0,0, \
_IQ(1), \
_IQ(-1), \
0, \
0, \
_IQ(0.05), \
_IQ(0.5), \
_IQ(0), \
0,0,0,0,0,0,0,0,\
pid_reg3_calc_pos,\
pid_reg3_reset_pos}
//! \memberof TPidReg3
void pid_reg3_calc_pos(TPidReg3_pos*);
void pid_reg3_reset_pos(TPidReg3_pos*);
#ifdef __cplusplus
}
#endif
#endif
/*@}*/

View File

@ -1,67 +0,0 @@
/*!
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_relay_reg.h
\brief Ðåëåéíûé ðåãóëÿòîð
\author ÎÎÎ "ÍÏÔ Âåêòîð". http://motorcontrol.ru
\version v 1.0 23/01/2016
\defgroup V_realy_reg
@{*/
#ifndef V_RELAY_REG_H
#define V_RELAY_REG_H
#ifdef __cplusplus
extern "C" {
#endif
/*! \class TRelayReg
\brief Ìîäóëü ðåëåéíîãî ðåãóëÿòîðà
Êëàññ \a TRelayReg, îñíîâàííûé íà ñòðóêòóðå SRelayReg, ïðåäñòàâëÿåò
ñîáîé ðåëåéíûé ðåãóëÿòîð.
*/
//! ñì. TRelayReg
typedef struct SRelayReg{ long ref; //!< Çàäàíèå
long fdb;//!< Îáðàòíàÿ ñâÿçü
long out;//!< Âûõîä
void (*calc)(struct SRelayReg*);//!< Pointer to calculation function
}TRelayReg;
//! Èíèöèàëèçàòîð ïî-óìîë÷àíèþ
#define RELAY_REG_DEFAULTS { 0,0,0, \
relay_reg_calc}
//! \memberof TRelayReg
void relay_reg_calc(TRelayReg*);
#ifdef __cplusplus
}
#endif
#endif
/*@}*/

View File

@ -25,6 +25,7 @@
// Ðàçðåøèòü ñòîðîæåâîé òàéìåð
//#define WATCHDOG_ON
//Âûáîð òèïà àïïàðàòíîé ÷àñòè
#define HW_MOTORCONTROLBOARD
//Äëÿ UART, âûáèðàåòñÿ ÷åì åãî çàíÿòü - MODBUS èëè CANtoRS äðàéâåðîì
//#define MODBUS_ENA
@ -58,8 +59,6 @@
//! Ðåæèì àâòîêîììóòàöèè äëÿ SRM
#define CTRL_RUN_SRM_AUTOCOMMUTATION 101
//! Ðåæèì èçìåðåíèÿ çàäåðæêè ìåæäó ØÈÌ è äàò÷èêàìè òîêà
#define CTRL_RUN_LATENCY_TEST 31
@ -80,7 +79,7 @@
#define F_PROGRAM_40K 0x400
//#define F_RESERVED 0x800
#define F_PDPINT 0x1000
//#define F_RESERVED 0x2000
#define F_RELAY_START 0x2000
//#define F_RESERVED 0x4000
//#define F_RESERVED 0x8000

View File

@ -48,12 +48,10 @@ extern "C" {
#include "V_bits_to_enum_numbers.h"
#include "SM_Ctrl.h"
#include "SM_CmdLogic.h"
#include "V_RTC_Clock.h"
#include "clarke.h"
#include "park.h"
#include "ipark.h"
#include "V_pid_reg3.h"
#include "V_pid_reg3_pos.h"
#include "V_rmp_ctrl.h"
#include "V_adc.h"
#include "V_PWM_Module.h"
@ -61,20 +59,23 @@ extern "C" {
#include "V_hzprof.h"
#include "V_DPR_eCAP.h"
#include "V_QEP.h"
#include "V_led.h"
#include "V_AutoOffset.h"
#include "V_CANtoRS.h"
#include "V_SSI_Encoder.h"
#include "V_UserMemory.h"
#include "V_rotor_observer.h"
#include "V_relay_reg.h"
#include "DRV_INTERFACE.h"
#include "V_event_log.h"
#include "Global_time.h"
#include "V_fifo.h"
#include "V_usblib.h"
#include "V_watchdog.h"
#include "V_UdControl.h"
#include "V_DIO.h"
#include "V_Fan.h"
#include "V_BrakeResistor.h"
extern TFanControl fanControl;
extern TClarke clarke;
extern TPark park;
extern TIPark ipark;
@ -82,7 +83,7 @@ extern TPidReg3 pid_id;
extern TPidReg3 pid_iq;
extern TPidReg3 pid_ia;
extern TPidReg3 pid_spd;
extern TPidReg3_pos pid_pos;
extern TPidReg3 pid_pos;
extern TSM_Sys sm_sys;
extern Uint16 disp_group_number;
extern TDataLog dlog;
@ -102,7 +103,6 @@ extern TCurPar cur_par;
extern TVhzProf vhz;
extern TDPReCAP DPReCAP;
extern TposspeedEqep posspeedEqep;
extern TRTCClock RTCclock;
extern TAutoOffset AutoOffset;
extern TSSI_Encoder SSI_Encoder;
extern TRotorObserver RotorObserver;
@ -110,6 +110,8 @@ extern TCANtoRS CANtoRS;
extern TDrvInterface drv_interface;
extern TLogger FaultLog;
extern TGlobalTime global_time;
extern TUdControl udControl;
extern TbrakeResistor brakeResistor;
extern Uint16 msCounter;
extern Uint16 FastCounter;
@ -142,7 +144,7 @@ extern unsigned long CpuTimerIsr1;
extern TSysSwitches sw;
extern TUserMemory UserMem;
extern Tled leds;
//extern TCanBTInterface Can1BTInterface;
//extern TCanBTInterface Can2BTInterface;
extern TCANSpeedTableOptions canSpeedTable;

View File

@ -68,7 +68,6 @@ void co_CAN1GpioInit()
{
//переводим ГПИО на выполнение функции CAN
GPIOB->ALTFUNCSET = (1 << 14) + (1 << 15); //CAN_TX[0], CAN_RX[0]
GPIOB->DENSET = (1 << 14) + (1 << 15);
}
#endif //CAN_1_ENABLE
@ -268,12 +267,12 @@ void co_RPDO8_Callback(Uint16 nodeID, Uint16 tag_CANnum)
//!Если происходит запись в параметр [5139h.01h] Текущ. знач.Часы реального времени,
//то вызывается callback_RTC - там устанавливается запрос на коррекцию часов.
void callback_RTC(Uint16 par, Uint16 tag_CANnum) {
if (par == 1) {
RTCclock.setTimeFlag = 1; //ïðîèçîøëà çàïèñü â ÷àñû
}
}
//void callback_RTC(Uint16 par, Uint16 tag_CANnum) {
// if (par == 1) {
// RTCclock.setTimeFlag = 1; //ïðîèçîøëà çàïèñü â ÷àñû
//
// }
//}
//!Обращение к переменной dlog.next_value_var с данными цифрового осциллографа.

View File

@ -70,7 +70,14 @@ void SM_CmdLogicms_Calc(TSM_CmdLogic *p) {
if (sm_prot.state == PROT_ON_OK) {//если ДА защит включился, обрабатываем команды включения
if ((cmd.bit.start == 1) && (sm_sys.state == SYS_READY))//есть битовая команда старта
p->state = CMD_LOGIC_TURNED_ON; //ïîåõàëè
if (udControl.Enabled == 0) { //Если цепь плавного заряда ЗПТ отключена, то переходим к пуску
p->state = CMD_LOGIC_TURNED_ON; //поехали
} else {
if (udControl.StateOn == 1) //Если цепь плавного заряда ЗПТ включена, ждем срабатывания реле, а потом запускаем
p->state = CMD_LOGIC_TURNED_ON; //поехали
else
udControl.fault_start = 1; //если пытаемся пустится при незашунтированном реле, попадаем в аварию
}
}
//дискретный автомат со структурами управления в СТОПе всегда тоже принудительно переводим в стоп

View File

@ -144,7 +144,7 @@ void SM_Ctrl_Fast_Calc(TSM_Ctrl *p) {
p->state = CTRL_RUN_U2F;
}
if (p->run_mode == CTRL_FLUXING) {//режим удержания (постоянный ток)
p->state = CTRL_FLUXING;
p->state = CTRL_RUN_I2F;
}
if (p->run_mode == CTRL_RUN_I2F) {//частотно-токовый режим (вращение вектора тока)
p->state = CTRL_RUN_I2F;
@ -162,68 +162,13 @@ void SM_Ctrl_Fast_Calc(TSM_Ctrl *p) {
p->state = CTRL_AUTO_SENSOR_TUNING;
}
if (p->run_mode == CTRL_RUN_LATENCY_TEST) { // Режим измерения задержки между ШИМ и датчиками тока
p->state = CTRL_RUN_LATENCY_TEST;
}
/*DO END*/
break;
}
case CTRL_FLUXING: { //Режим постоянный ток
if (p->E == 1) {
/*ENTRY START*/
pwm.On(&pwm);
pid_id.ui_reg3 = 0; //сбрасывем интегральные каналы
pid_iq.ui_reg3 = 0; //чтобы не накапливались
pid_spd.ui_reg3 = 0;
refs.theta_elec = 0;//заданный угол - 0. Но он есть в группе Задания, его можно менять на ходу!
if (dlog.StartBits & (1 << 1))
dlog.set_mode(1, &dlog);
/*ENTRY END*/
}
/*DO START*/
//два тока фаз из АЦП в модуль фазных преобразований
clarke.as = adc.Imeas_a;
clarke.bs = adc.Imeas_b;
clarke.calc(&clarke);//расчет
//из фазных преобразований в координатные преобразования.
//Поворачиваем вектор на заданный угол refs.theta_elec
park.ds = clarke.ds;
park.qs = clarke.qs;
park.ang = refs.theta_elec;
park.calc(&park);
//регулятор тока "как бы" оси d (на самом деле эта ось к двигателю к оси d не привязана, это свободная ось)
pid_id.pid_ref_reg3 = refs.i_flux_ref; //задание на ток намагничивания
pid_id.pid_fdb_reg3 = park.de;//обратная связь - то что пришло с фазных преобразований
pid_id.calc(&pid_id);
//регулятор тока "как бы" оси q (на самом деле эта ось к двигателю к оси q не привязана, это свободная ось)
pid_iq.pid_ref_reg3 = 0;//задание - ноль
pid_iq.pid_fdb_reg3 = park.qe;park.de;//обратная связь - то что пришло с фазных преобразований
pid_iq.calc(&pid_iq);
//обратные фазные преобразования.
//Крутим вектор напряжения, который выдают регуляторы токов обратно на угол refs.theta_elec
ipark.de = pid_id.pid_out_reg3;
ipark.qe = pid_iq.pid_out_reg3;
ipark.ang = refs.theta_elec;
ipark.calc(&ipark);
//получившиеся задания напряжения по осям альфа и бета отправляем на модуль ШИМ
pwm.UalphaRef = ipark.ds;
pwm.UbetaRef = ipark.qs;
pwm.update(&pwm);
//в наблюдаемые переменные - текущий амплитудный ток в статоре (обратная связь регулятора d)
cur_par.Is = pid_id.pid_fdb_reg3;
break;
}
case CTRL_RUN_U2F: { //Режим скалярное управление U(f)
if (p->E == 1) {
@ -295,18 +240,21 @@ void SM_Ctrl_Fast_Calc(TSM_Ctrl *p) {
cur_par.Ialpha = clarke.ds;
cur_par.Ibeta = clarke.qs;
//задание скорости на вход задатчика интенсивности
rmp.input = refs.speed_ref;
rmp.calc(&rmp);//расчет задатчика
//угол refs.theta_elec - интеграл от скорости rmp.output.
//Константа FAST_CALC_TS - период дискретизации
//drv_params.freq_nom номинальная частота (базовый параметр частоты для относительных единиц измерения)
refs.theta_elec += _IQmpy(
_IQmpyI32(drv_params.freq_nom,FAST_CALC_TS), rmp.output);
cur_par.ThetaRefCurr = refs.theta_elec;
refs.theta_elec &= 0x00FFFFFF;//отсечение лишней верхней части, если угол больше единицы в IQ (360 градусов)
// Если режим не удержание, то расчитывать угол в зависимости от скорости.
// Иначе задание эл. угла будет браться из параметра и оставаться постоянным.
if (p->run_mode != CTRL_FLUXING) {
//задание скорости на вход задатчика интенсивности
rmp.input = refs.speed_ref;
rmp.calc(&rmp);//расчет задатчика
//угол refs.theta_elec - интеграл от скорости rmp.output.
//Константа FAST_CALC_TS - период дискретизации
//drv_params.freq_nom номинальная частота (базовый параметр частоты для относительных единиц измерения)
refs.theta_elec += _IQmpy(
_IQmpyI32(drv_params.freq_nom,FAST_CALC_TS), rmp.output);
cur_par.ThetaRefCurr = refs.theta_elec;
refs.theta_elec &= 0x00FFFFFF;//отсечение лишней верхней части, если угол больше единицы в IQ (360 градусов)
}
//текущий угол с датчика положения, переведенный в электрический из механического
//cur_par.ThetaCurr = posspeedEqep.theta_elecContinouos;
@ -396,7 +344,7 @@ void SM_Ctrl_Fast_Calc(TSM_Ctrl *p) {
pid_spd.pid_out_max = refs.Iq_ref; //Максимум выхода регулятора скорости - заданный ток
if (sw.recuperation_ena & 1) //если разрешена рекуперация
if (sw.bit.recuperation_ena) //если разрешена рекуперация
pid_spd.pid_out_min = -refs.Iq_ref; //минимум рег. скор. - отрицательный ток
else
//иначе
@ -605,7 +553,7 @@ void SM_Ctrl_Fast_Calc(TSM_Ctrl *p) {
pid_spd.pid_out_max = refs.Iq_ref; //Максимум выхода регулятора скорости - заданный ток
if (sw.recuperation_ena & 1) //если разрешена рекуперация
if (sw.bit.recuperation_ena) //если разрешена рекуперация
pid_spd.pid_out_min = -refs.Iq_ref; //минимум рег. скор. - отрицательный ток
else
//иначе
@ -743,34 +691,6 @@ void SM_Ctrl_Fast_Calc(TSM_Ctrl *p) {
break;
}
case CTRL_RUN_LATENCY_TEST: { //Режим постоянный ток
if (p->E == 1) {
/*ENTRY START*/
pwm.On(&pwm);
p->ctrl_counter = 0;
if (dlog.StartBits & (1 << 1))
dlog.set_mode(1, &dlog);
/*ENTRY END*/
}
/*DO START*/
p->ctrl_counter++;
pwm.UalphaRef = 0;
pwm.UbetaRef = 0;
DebugW1++;
if (p->ctrl_counter > 100){
if (labs(adc.Imeas_a)< refs.i_flux_ref){
pwm.UalphaRef = _IQ(1);
pwm.UbetaRef = 0;
} else {
p->ctrl_counter = 0;
}
}
pwm.update(&pwm);
break;
}
default: {
break;

View File

@ -52,7 +52,7 @@ void SM_Net_Init(TSM_Net *p) {
//логгер событий:
// размер буфера: 50
// стартовый адрес в SPI: 3000
FaultLog.init(&FaultLog, 50, 3000, (Uint32*)&RTCclock.packed_time);//ниже указатель на время может быть переопределен в зависимости от работы часов
FaultLog.init(&FaultLog, 50, 3000, (Uint32*)&global_time.PowerOn_time);//ниже указатель на время может быть переопределен в зависимости от работы часов
////Работа с CANopen через UART (параллельно с CAN, нет конфликта)
@ -113,10 +113,6 @@ void SM_Net_Slow_Calc(TSM_Net *p) {
MBVarsConv.slow_calc(&MBVarsConv);
#endif
if (RTCclock.ClockOk)//часы работают?
FaultLog.time_ptr = (Uint32*)&RTCclock.packed_time;//время для банка аварий из часов
else
FaultLog.time_ptr = (Uint32*)&global_time.PowerOn_time;//если не работают, то из модуля подсчета времени наработки
}
//!Быстрый расчет

View File

@ -34,7 +34,6 @@ int16 WriteCounter = 0;
void SM_Protect_Init(TSM_Protect *p) {
p->state_prev = 0xff;
p->state = 0x00;
GPIOA->DENSET = (1 << 7);//äë˙ ďđčĺěŕ íîćęč ŕďď. ŕâŕđčč đŕçđĺřŕĺě đŕáîňó íîćęč ęŕę öčôđű
}
//! Быстрый расчет.
@ -55,12 +54,15 @@ void SM_Protect_Fast_Calc(TSM_Protect *p) {
}
/*Защита по максимальному току*/
if (adc.Imeas_a > sm_prot.Imax_protect) sm_prot.bit_fault2 |= F_CTRL_MAX_I_PH_A;
if (adc.Imeas_a < -sm_prot.Imax_protect) sm_prot.bit_fault2 |= F_CTRL_MAX_I_PH_A;
if (adc.Imeas_b > sm_prot.Imax_protect) sm_prot.bit_fault2 |= F_CTRL_MAX_I_PH_B;
if (adc.Imeas_b < -sm_prot.Imax_protect) sm_prot.bit_fault2 |= F_CTRL_MAX_I_PH_B;
if (adc.Imeas_c > sm_prot.Imax_protect) sm_prot.bit_fault2 |= F_CTRL_MAX_I_PH_C;
if (adc.Imeas_c < -sm_prot.Imax_protect) sm_prot.bit_fault2 |= F_CTRL_MAX_I_PH_C;
if (labs(adc.Imeas_a) > sm_prot.Imax_protect) sm_prot.bit_fault2 |= F_CTRL_MAX_I_PH_A;
if (labs(adc.Imeas_b) > sm_prot.Imax_protect) sm_prot.bit_fault2 |= F_CTRL_MAX_I_PH_B;
if (labs(adc.Imeas_c) > sm_prot.Imax_protect) sm_prot.bit_fault2 |= F_CTRL_MAX_I_PH_C;
// Защита от пуска при незашунтированном реле плавного заряда ЗПТ
if (udControl.Enabled == 1) { //Если есть цепь шунтирования ЗПТ, то выставляем аварии по выполнению условий
if (udControl.fault_start == 1)
sm_prot.bit_fault1 |= F_RELAY_START;
}
//при превышении скорости выше аварийной нормы
if (labs(cur_par.speed) > sm_prot.speed_max) {
@ -132,19 +134,16 @@ void SM_Protect_Fast_Calc(TSM_Protect *p) {
if (cmd.bit.trip_reset == 1) {//команда на сброс аварии
p->state = PROT_ON_OK;//идем в "норма"
p->clearDrvFault = 1; //отправить драйверу ключей команду сброса
if (udControl.Enabled == 1) { //Если есть цепь шунтирования ЗПТ, то сбрасываем возможные состояния аварий
udControl.fault_start = 0;
}
//обнуляем все флаги аварий
p->bit_fault1 = 0;
p->bit_fault2 = 0;
cmd.all = 0;//командное слово
//â ńŕěîě íčçó!!! ďűňŕĺěń˙ ńáđîńčňü ôëŕă pdp ŕďďŕđŕňíűé
//ĺńëč ŕâŕđč˙ âńĺ ĺůĺ čěĺĺňń˙, ňî ńđŕçó ďđîčçîéäĺň ďđĺđűâŕíčĺ
//č âîçâĺäĺňń˙ ôëŕă ŕâŕđčč
if (PWM0->TZFLG_bit.OST == 1) { //čěĺĺňń˙ ôëŕă ŕďďŕđŕňíîé ŕâŕđčč
//ôëŕă ěîćíî ńáđŕńűâŕňü
PWM0->TZCLR = 0x7;
PWM1->TZCLR = 0x7;
PWM2->TZCLR = 0x7;
}
}
break;
}

View File

@ -28,22 +28,28 @@
#if defined ( __CMCPPARM__ )
extern const Uint32 __Vectors;
#elif defined (__GNUC__)
// ничего
#endif
#define LED_ON GPIOA->MASKLB[8].MASKLB = 8
#define LED_OFF GPIOA->MASKLB[8].MASKLB = 0
void setLedEnabled (Uint8 enabled) {
// Если надо JTAG - включим альт-функцию и хорошо
if (enabled) {
GPIOA->ALTFUNCCLR = 1 << 3;
} else {
GPIOA->ALTFUNCSET = 1 << 3;
}
}
//! Инициализация системы управления после включения
//!Инициализация некоторых модулей и настройка прерываний системы.
//!Здесь настраивается большинство прерываний
//! \memberof TSM_Sys
void SM_Sys_Init(TSM_Sys *p) {
#if defined (HW_VECTORCARD_DRV8301_EVM)
sw.HardwareType = 0;
#elif defined (HW_VECTORCARD_DRV8312_EVM)
sw.HardwareType = 1;
#elif defined (HW_VECTORCARD_SIMULATOR)
sw.HardwareType = 2;
#endif
cmd.all = 0;
drv_status.all = 0;
UserMem.init(&UserMem);
@ -54,10 +60,12 @@ void SM_Sys_Init(TSM_Sys *p) {
sm_ctrl.init(&sm_ctrl); //Структура системы управления
pwm.init(&pwm); //Модуль ШИМ
cur_par.init(&cur_par); //Расчет текущих показателей привода
leds.init(&leds);//светодиоды
udControl.init(&udControl);
//глобальное времЯ (внешние или внутр. часы)
global_time.init(&global_time);
fanControl.init(&fanControl);
DIO_Init();
brakeResistor.init(&brakeResistor);
if (drv_params.sens_type == POS_SENSOR_TYPE_HALL){ //В типе датчика выбран ДПР на элементах Холла
// DPReCAP.Init(&DPReCAP); //ДПР иниц.
@ -173,6 +181,17 @@ void SM_Sys_Init(TSM_Sys *p) {
sm_sys.state = SYS_READY;
// Чтобы можно было по желанию включить светодиод:
// Разрешение изменения регистров настройки порта А, разрешение работы A3 на выход
// Но на этом этапе у нас ещё включена альтернативная функция, поэтому A3 пока ещё JTAG-овая
GPIOA->LOCKKEY = 0xaDeadBee;
__NOP();__NOP();
GPIOA->LOCKCLR = 1 << 3;
GPIOA->OUTENSET = 1 << 3;
// На всякий случай принудительно отключим использование светодиода
sw.bit.use_led = FALSE;
#ifdef WATCHDOG_ON
Watchdog.enable(); //если сторожевой таймер используется, инициализируем
#endif //WATCHDOG_ON
@ -188,25 +207,26 @@ void SM_Sys_Fast_Calc(TSM_Sys *p) {
if (drv_params.sens_type == POS_SENSOR_TYPE_ENCODER) //В типе датчика выбран энкодер
posspeedEqep.calc(&posspeedEqep); //ДПР энкодер
if (drv_params.sens_type == POS_SENSOR_TYPE_HALL){ //В типе датчика выбран ДПР Холла
DPReCAP.AngleCalc(&DPReCAP); //ДПР Холл, интерполяция угла положения (результат в DPReCAP.Angle)
DPReCAP.Angle6Calc(&DPReCAP); //ДПР Холл, получение угла с точнгстью 60 градусов (результат в DPReCAP.Angle6)
DPReCAP.SpeedCalc(&DPReCAP); //ДПР Холл, расчет скорости вращения (DPReCAP.speed)
DPReCAP.calc_10k(&DPReCAP); //ДПР Холл, служебные функции
DPReCAP.AngleCalc(&DPReCAP); //ДПР Холл, интерполяция угла положения (результат в DPReCAP.Angle)
DPReCAP.Angle6Calc(&DPReCAP); //ДПР Холл, получение угла с точнгстью 60 градусов (результат в DPReCAP.Angle6)
DPReCAP.SpeedCalc(&DPReCAP); //ДПР Холл, расчет скорости вращения (DPReCAP.speed)
DPReCAP.calc_10k(&DPReCAP); //ДПР Холл, служебные функции
}
if (drv_params.sens_type == POS_SENSOR_TYPE_SSI){ //Датчик с интерфейсом SSI. Перед употреблением читайте заголовочный файл!
SSI_Encoder.calc(&SSI_Encoder);//Датчик положения SSI
SSI_Encoder.calc(&SSI_Encoder); //Датчик положения SSI
}
sm_prot.fast_calc(&sm_prot); //Защиты
sm_ctrl.fast_calc(&sm_ctrl); //Главный дискретный автомат системы управления
DIO_fast_calc(); // Дискретные входы и выходы
udControl.calc(&udControl); // Контроль заряда ЗПТ
sm_prot.fast_calc(&sm_prot); //Защиты
sm_ctrl.fast_calc(&sm_ctrl); //Главный дискретный автомат системы управления
global_time.calc(&global_time);
cur_par.calc(&cur_par); //Расчет текущих показателей привода
drv_params.sens_type = drv_params.sens_type & 7; //Отсекаем верхнюю часть переменной, там мусор
brakeResistor.fastCalc(&brakeResistor);
#ifdef WATCHDOG_ON
// Watchdog.feed();//если сторожевой таймер используется, сбрасываем его здесь
#endif //WATCHDOG_ON
@ -217,15 +237,29 @@ void SM_Sys_Fast_Calc(TSM_Sys *p) {
//!Вызов расчетов модулей системы управления, требующих миллисекундной дискретизации
//! \memberof TSM_Sys
void SM_Sys_ms_Calc(TSM_Sys* p) {
sm_cmd_logic.ms_calc(&sm_cmd_logic); //Обработка команд управления
sm_net.ms_calc(&sm_net); //обертка для вызова коммуникационных драйверов
adc.ms_calc(&adc); //АЦП
// Светодиодик
if (sm_ctrl.state == CTRL_STOP) p->ledPeriod = 2000;
else p->ledPeriod = 1000;
p->ledTimer++;
if (p->ledTimer < (p->ledPeriod >> 1))
LED_ON;
else if (p->ledTimer < p->ledPeriod)
LED_OFF;
else
p->ledTimer = 0;
sm_cmd_logic.ms_calc(&sm_cmd_logic); //Обработка команд управления
sm_net.ms_calc(&sm_net); //обертка для вызова коммуникационных драйверов
adc.ms_calc(&adc); //АЦП
sm_prot.ms_calc(&sm_prot); //Защиты
AutoOffset.ms_calc(&AutoOffset); //авто смещение некоторых каналов АЦП
//блочная передача драйвера CANopen. Через неё, в частности, грузятся осциллограммы dlog
// Can2BTInterface.ms_calc(&Can2BTInterface, TMR2->VALUE, &co2_vars);
leds.msCalc(&leds);//светодиоды
RTCclock.msCalc(&RTCclock);//часы
fanControl.slow_calc(&fanControl);
UserMem.ms_calc(&UserMem);//пользовательская память в МК
if ((drv_params.sens_type == 2) || (drv_params.sens_type == 3)){ //В типе датчика выбран ДПР Холла
DPReCAP.ms_calc(&DPReCAP);
@ -238,9 +272,13 @@ void SM_Sys_ms_Calc(TSM_Sys* p) {
//!Вызов медленных расчетов остальных модулей
//! \memberof TSM_Sys
void SM_Sys_Slow_Calc(TSM_Sys *p) {
// Can2BTInterface.slow_calc(&Can2BTInterface);//интерфейс блочной передачи CANopen, медленный расчет
//Пересчет коэффициентов для масштабирования токов и напряжений
drv_params._1_Udc_nom = _IQdiv(_IQ16(1), _IQ16(drv_params.Udc_nom));
drv_params._1_I_nom = _IQdiv(_IQ16(1), _IQ16(drv_params.I_nom));
drv_params._1_U_nom = _IQdiv(_IQ16(1), _IQ16(drv_params.U_nom));
UserMem.slow_calc(&UserMem);//пользовательская память в МК
RTCclock.slowCalc(&RTCclock);//часы реального времени
sm_prot.slow_calc(&sm_prot);//модуль защит
sm_net.slow_calc(&sm_net); //обертка для вызова коммуникационных драйверов
dlog.background_analizer(&dlog); //фоновый обработчик модуля осциллографирования
@ -253,14 +291,11 @@ void SM_Sys_Slow_Calc(TSM_Sys *p) {
posspeedEqep.slow_calc(&posspeedEqep);//инициализация модуля энкодера
RotorObserver.slow_calc(&RotorObserver);//наблюдатель потока ротора АД
DPReCAP.slow_calc(&DPReCAP);//ДПР Холла
DIO_slow_calc(); // Дискретные входы и выходы
//Пересчет коэффициентов для масштабирования токов и напряжений
drv_params._1_Udc_nom = _IQdiv(_IQ16(1), _IQ16(drv_params.Udc_nom));
drv_params._1_I_nom = _IQdiv(_IQ16(1), _IQ16(drv_params.I_nom));
drv_params._1_U_nom = _IQdiv(_IQ16(1), _IQ16(drv_params.U_nom));
if (sw.Reboot & 1) { //команда перезагрузки
sw.Reboot = 0; //сбрасываем её
if (sw.bit.Reboot & 1) { //команда перезагрузки
sw.bit.Reboot = 0; //сбрасываем её
if (sm_ctrl.state == CTRL_STOP) { //перезагружаемся только в останове
//выполняем сброс проца
//Перезагружает во флеш!
@ -270,11 +305,16 @@ void SM_Sys_Slow_Calc(TSM_Sys *p) {
//вызов расчета смещения АЦП для токов фаз
//Делаем расчет только в останове и отсутствии аварии
if ((sw.AutoOffset & 1) && (sm_ctrl.state == CTRL_STOP)) AutoOffset.Enabled=1;
if ((sw.bit.AutoOffset) && (sm_ctrl.state == CTRL_STOP)) AutoOffset.Enabled=1;
else AutoOffset.Enabled=0;
// Если разрешили светодиод
if (sw.bit.use_led && !sw.bit.use_led_prev)
setLedEnabled(TRUE);
else if (!sw.bit.use_led && sw.bit.use_led_prev)
setLedEnabled(FALSE);
sw.bit.use_led_prev = sw.bit.use_led;
}
/*@}*/

View File

@ -42,14 +42,12 @@ void AutoOffset_calc(TAutoOffset *p) {
//åñëè ýòî íå òàê, òî èíòåãðàòîðû ïîéäóò ñ÷èòàòü
p->IA_int = p->IA_int + _IQmpy(p->FilterK, adc.Imeas_a);
p->IB_int = p->IB_int + _IQmpy(p->FilterK, adc.Imeas_b);
p->IC_int = p->IC_int + _IQmpy(p->FilterK, adc.Imeas_c);
}
void AutoOffset_slow_calc(TAutoOffset *p) {
long IA_pu;
long IB_pu;
long IC_pu;
if (p->Enabled){//åñëè ìîäóëü àâòîðàñ÷åòà ñìåùåíèÿ òîêîâ âêëþ÷åí
//ïåðåñ÷èòûâàåì èç î.å. îáðàòíî â çíà÷åíèÿ ÀÖÏ
@ -59,12 +57,9 @@ void AutoOffset_slow_calc(TAutoOffset *p) {
IB_pu = -p->IB_int / (_IQ16mpy(adc.Imeas_b_gain, drv_params._1_I_nom));
adc.Imeas_b_offset = IB_pu >> 1;
IC_pu = -p->IC_int / (_IQ16mpy(adc.Imeas_c_gain, drv_params._1_I_nom));
adc.Imeas_c_offset = IC_pu >> 1;
} else {//ìîäóëü âûêëþ÷åí, èíèöèàëèçèðóåì èíòåãðàòîðû òåêóùèìè çíà÷åíÿìè ñìåùåíèé
p->IA_int=-(((long)adc.Imeas_a_offset)<<1)*_IQ16mpy(adc.Imeas_a_gain, drv_params._1_I_nom);
p->IB_int=-(((long)adc.Imeas_b_offset)<<1)*_IQ16mpy(adc.Imeas_b_gain, drv_params._1_I_nom);
p->IC_int=-(((long)adc.Imeas_c_offset)<<1)*_IQ16mpy(adc.Imeas_c_gain, drv_params._1_I_nom);
}
}

73
Vsrc/V_BrakeResistor.c Normal file
View File

@ -0,0 +1,73 @@
/*!
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_BrakeResistor.c
\brief Ìîäóëü óïðàâëåíèÿ ñëèâíûì ðåçèñòîðîì
\author ÎÎÎ "ÍÏÔ Âåêòîð". http://motorcontrol.ru
\version v 1.0 25/08/2017
\addtogroup
@{*/
#include <DSP.h>
#include "main.h"
#if defined (HW_MOTORCONTROLBOARD)
#define BR_CONTROL_OFF GPIOB->DATAOUTCLR = (1 << 7);
#define BR_CONTROL_ON GPIOB->DATAOUTSET = (1 << 7);
#else
#define BR_CONTROL_OFF // îïåðàöèÿ äëÿ âûêëþ÷åíèÿ
#define BR_CONTROL_ON // îïåðàöèÿ äëÿ âêëþ÷åíèÿ
#endif
void BrakeResistor_Init (TbrakeResistor *p) {
p->state = BRAKE_R_STATE_OFF;
// Íàñòðîéêà íîæêè
BR_CONTROL_OFF;
GPIOB->ALTFUNCCLR = (1 << 7);
GPIOB->OUTENSET = (1 << 7);
}
void BrakeResistor_fastCalc (TbrakeResistor *p) {
// Çàùèòà îò îäèíàêîâûõ óñòàâîê (äîëæåí áûòü ãèñòåðåçèñ)
if (p->bottomLevel >= p->upperLevel)
p->bottomLevel = _IQmpy(p->upperLevel, _IQ(0.95));
if (!p->enabled) {
p->state = BRAKE_R_STATE_OFF;
BR_CONTROL_OFF;
return;
}
// Åñëè ðàçðåøåíî óïðàâëåíèå òîðìîçíûì ðåçèñòîðîì, òî
// åñëè íàïðÿæåíèå áîëüøå îäíîé óñòàâêè - âëêþ÷èòü, à åñëè ìåíüøå äðóãîé - âûêëþ÷èòü
if (adc.Udc_meas > p->upperLevel){
p->state = BRAKE_R_STATE_ON;
BR_CONTROL_ON;
} else if (adc.Udc_meas < p->bottomLevel) {
p->state = BRAKE_R_STATE_OFF;
BR_CONTROL_OFF;
}
}
/*@}*/

View File

@ -31,11 +31,9 @@
void CANtoRS_init(TCANtoRS *p) {
GPIOB->ALTFUNCSET = (1 << 8) + (1 << 9);
GPIOB->DENSET = (1 << 8) + (1 << 9);
p->UART=UART1;//Èñïîëüçóåìûé â äðàéâåðå íîìåð UART (0, 1)
p->UART->CR_bit.UARTEN = 1; // Разрешить работу UART
// Íàñòðîéêà ÷àñòîòû â äâóõ ðåãèñòðàõ:
// çàäàíèå äåëèòåëÿ ÷àñòîòû äëÿ ïîëó÷åíèÿ BaudRate
@ -49,14 +47,25 @@ void CANtoRS_init(TCANtoRS *p) {
p->UART->FBRD_bit.DIVFRAC = 8;
p->UART->LCRH_bit.SPS = 0; // Нет проверки четности
p->UART->LCRH_bit.WLEN = 3; // Длина посылки 8 бит
p->UART->LCRH_bit.FEN = 1; // Использовать FIFO
p->UART->CR_bit.TXE = 1; // Разрешить приём
p->UART->CR_bit.RXE = 1; // Разрешить передачу
p->UART->LCRH_bit.STP2 = 0; // 1 стоп-бит
//p->UART->LCRH_bit.SPS = 0; // Íåò ïðîâåðêè ÷åòíîñòè
//p->UART->LCRH_bit.WLEN = 3; // Äëèíà ïîñûëêè 8 áèò
//p->UART->LCRH_bit.FEN = 1; // Èñïîëüçîâàòü FIFO
//p->UART->LCRH_bit.STP2 = 0; // 1 ñòîï-áèò
//
//p->UART->CR_bit.UARTEN = 1; // Ðàçðåøèòü ðàáîòó UART
//p->UART->CR_bit.TXE = 1; // Ðàçðåøèòü ïðè¸ì
//p->UART->CR_bit.RXE = 1; // Ðàçðåøèòü ïåðåäà÷ó
p->CounterWrongCRC=0;
p->UART->LCRH = (0 << UART_LCRH_SPS_Pos) |
(3 << UART_LCRH_WLEN_Pos) |
(1 << UART_LCRH_FEN_Pos) |
(0 << UART_LCRH_STP2_Pos);
p->UART->CR = (1 << UART_CR_UARTEN_Pos) |
(1 << UART_CR_TXE_Pos) |
(1 << UART_CR_RXE_Pos);
p->CounterWrongCRC=0;
p->CounterRes=0;
p->CounterSended=0;
p->PacketInWait=0;
@ -73,8 +82,8 @@ void CANtoRS_init(TCANtoRS *p) {
Uint16 CANtoRS_SendP(Uint16* Data, int16 len, TCANtoRS *p) {
volatile int16 i;
Uint16 MyCRC;
p->buf_out[0]=0x7E;
for (i=0;i<len;i++)
p->buf_out[0] = 0x7E;
for (i = 0; i < len; i++)
p->buf_out[i+1]=Data[i];
MyCRC=CANtoRS_C_CRC(p,Data,len);
p->buf_out[len+1]=MyCRC & 0xFF;//ïåðâûé áàéò

85
Vsrc/V_DIO.c Normal file
View File

@ -0,0 +1,85 @@
/*!
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_DIO.c
\brief Ìîäóëü äèñêðåòíûõ âõîäîâ/âûõîäîâ
\author ÎÎÎ "ÍÏÔ Âåêòîð". http://motorcontrol.ru
\version v 1.0 25/08/2017
\addtogroup
@{*/
#include "main.h"
#include "filter.h"
// Âåêòîð ñîñòîßíèß äèñêðåòíûõ âûõîäîâ
volatile Uint8 output_vect = 0;
// Âåêòîð ñîñòîßíèß äèñêðåòíûõ âõîäîâ
volatile Uint8 input_vect = 0;
// Ôèëüòðû äèñêðåòíûõ âõîäîâ
TFilter fIn1 = FILTER_DEFAULTS;
void DIO_Init()
{
#if defined (HW_MOTORCONTROLBOARD)
// Èíèöèàëèçàöèÿ äèñêðåòíîãî âõîäà
GPIOA->ALTFUNCCLR = (1 << 14);
GPIOA->OUTENCLR = (1 << 14);
// Èíèöèàëèçàöèÿ äèñêðåòíîãî âûõîäà
GPIOA->ALTFUNCCLR = (1 << 15);
GPIOA->OUTENSET = (1 << 15);
// Êîýôôèöèåíò ôèëüòðàöèè äèñêðåòíûõ âõîäîâ
fIn1.T = _IQ(0.03);
#endif
}
void DIO_slow_calc()
{
// Âûâîäèì óïðàâëßþùåå âîçäåéñòâèå ïî Âûõîäó 1
if (BIT_IS_SET(output_vect, 0))
D_OUT1_ON;
else
D_OUT1_OFF;
// Ïîëó÷àåì ñîñòîßíèå Âõîäà 1 ñ ó÷¸òîì ôèëüòðàöèè
if (fIn1.output > _IQ(0.8)) SET_BIT(input_vect, 0);
if (fIn1.output < _IQ(0.3)) CLEAR_BIT(input_vect, 0);
}
void DIO_fast_calc()
{
// Èíåðöèîííûé ôèëüòð äèñêðåòíîãî Âõîäà 1
fIn1.input = (D_IN1 == 1) ? _IQ(1.0) : 0;
fIn1.calc(&fIn1);
}
/*@}*/

View File

@ -41,76 +41,120 @@ void DPReCAP_Init(TDPReCAP* p) {
//Èíèöèàëèçàöèÿ ECAP1
ECAP0->ECEINT = 0x0000; // Disable all capture interrupts
ECAP0->ECCLR = 0xFFFF; // Clear all CAP interrupt flags
ECAP0->ECCTL0_bit.CAPLDEN = 0; // Disable CAP1-CAP4 register loads
ECAP0->ECCTL1_bit.TSCTRSTOP = 0; // Make sure the counter is stopped
ECAP0->ECCTL0_bit.PRESCALE = 0; // DIV1
//ECAP0->ECCTL0 = 0; // Disable CAP1-CAP4 register loads
//ECAP0->ECCTL1 = 0; // Make sure the counter is stopped
// Configure peripheral registers
ECAP0->ECCTL1_bit.CONTOST = 0; // continuous mode
ECAP0->ECCTL0_bit.CAP0POL = 0; // rising edge
ECAP0->ECCTL0_bit.CAP1POL = 1; // falling edge
ECAP0->ECCTL0_bit.CTRRST0 = 0; // absolute time stamp
ECAP0->ECCTL0_bit.CTRRST1 = 0; // absolute time stamp
ECAP0->ECCTL1_bit.STOPWRAP = 1; // Wrap after Capture Event 2
// ECAP0->ECCTL1_bit.SYNCI_EN = 1; // Enable sync in
ECAP0->ECCTL1_bit.SYNCOSEL = 0; // Pass through
ECAP0->ECCTL0_bit.CAPLDEN = 1; // Enable capture units
//ECAP0->ECCTL0_bit.CAP0POL = 0; // rising edge
//ECAP0->ECCTL0_bit.CAP1POL = 1; // falling edge
//ECAP0->ECCTL0_bit.CTRRST0 = 0; // absolute time stamp
//ECAP0->ECCTL0_bit.CTRRST1 = 0; // absolute time stamp
//ECAP0->ECCTL0_bit.CAPLDEN = 1; // Enable capture units
//ECAP0->ECCTL0_bit.PRESCALE = 0; // DIV1
//
//ECAP0->ECCTL1_bit.CONTOST = 0; // continuous mode
//ECAP0->ECCTL1_bit.STOPWRAP = 1; // Wrap after Capture Event 2
//ECAP0->ECCTL1_bit.SYNCOSEL = 0; // Pass through
//ECAP0->ECCTL1_bit.TSCTRSTOP = 1; // Start Counter
//ECAP0->ECCTL1_bit.REARM = 0; // Has no effect (Íå î÷åíü ïîíèìàþ ýòîò ðåãèñòð)
//
//ECAP0->ECEINT_bit.CEVT0 = 1; // 1 events = interrupt
//ECAP0->ECEINT_bit.CEVT1 = 1; // 2 events = interrupt
ECAP0->ECCTL0 = (0 << ECAP_ECCTL0_CAP0POL_Pos) |
(1 << ECAP_ECCTL0_CAP1POL_Pos) |
(0 << ECAP_ECCTL0_CTRRST0_Pos) |
(0 << ECAP_ECCTL0_CTRRST1_Pos) |
(1 << ECAP_ECCTL0_CAPLDEN_Pos) |
(0 << ECAP_ECCTL0_PRESCALE_Pos);
ECAP0->ECCTL1 = (0 << ECAP_ECCTL1_CONTOST_Pos) |
(1 << ECAP_ECCTL1_STOPWRAP_Pos) |
(1 << ECAP_ECCTL1_TSCTRSTOP_Pos) |
(0 << ECAP_ECCTL1_REARM_Pos) |
(0 << ECAP_ECCTL1_SYNCOSEL_Pos);
ECAP0->ECCTL1_bit.TSCTRSTOP = 1; // Start Counter
ECAP0->ECCTL1_bit.REARM = 0; // Has no effect (Íå î÷åíü ïîíèìàþ ýòîò ðåãèñòð)
ECAP0->ECCTL0_bit.CAPLDEN = 1; // Enable CAP1-CAP4 register loads
ECAP0->ECEINT_bit.CEVT0 = 1; // 1 events = interrupt
ECAP0->ECEINT_bit.CEVT1 = 1; // 2 events = interrupt
ECAP0->ECEINT = (1 << ECAP_ECEINT_CEVT0_Pos) |
(1 << ECAP_ECEINT_CEVT1_Pos);
//Èíèöèàëèçàöèÿ ECAP2
ECAP1->ECEINT = 0x0000; // Disable all capture interrupts
ECAP1->ECCLR = 0xFFFF; // Clear all CAP interrupt flags
ECAP1->ECCTL0_bit.CAPLDEN = 0; // Disable CAP1-CAP4 register loads
ECAP1->ECCTL1_bit.TSCTRSTOP = 0; // Make sure the counter is stopped
ECAP1->ECCTL0_bit.PRESCALE = 0; // DIV1
//ECAP1->ECCTL0_bit.CAPLDEN = 0; // Disable CAP1-CAP4 register loads
//ECAP1->ECCTL1_bit.TSCTRSTOP = 0; // Make sure the counter is stopped
//
//// Configure peripheral registers
//ECAP1->ECCTL0_bit.CAP0POL = 0; // rising edge
//ECAP1->ECCTL0_bit.CAP1POL = 1; // falling edge
//ECAP1->ECCTL0_bit.CTRRST0 = 0; // absolute time stamp
//ECAP1->ECCTL0_bit.CTRRST1 = 0; // absolute time stamp
//ECAP1->ECCTL0_bit.CAPLDEN = 1; // Enable capture units
//ECAP1->ECCTL0_bit.PRESCALE = 0; // DIV1
//
//ECAP1->ECCTL1_bit.CONTOST = 0; // continuous mode
//ECAP1->ECCTL1_bit.STOPWRAP = 1; // Wrap after Capture Event 2
//ECAP1->ECCTL1_bit.TSCTRSTOP = 1; // Start Counter
//ECAP1->ECCTL1_bit.REARM = 0; // Has no effect (Íå î÷åíü ïîíèìàþ ýòîò ðåãèñòð)
//ECAP1->ECCTL1_bit.SYNCOSEL = 0; // Pass through
//
//ECAP1->ECEINT_bit.CEVT0 = 1; // 1 events = interrupt
//ECAP1->ECEINT_bit.CEVT1 = 1; // 2 events = interrupt
// Configure peripheral registers
ECAP1->ECCTL1_bit.CONTOST = 0; // continuous mode
ECAP1->ECCTL0_bit.CAP0POL = 0; // rising edge
ECAP1->ECCTL0_bit.CAP1POL = 1; // falling edge
ECAP1->ECCTL0_bit.CTRRST0 = 0; // absolute time stamp
ECAP1->ECCTL0_bit.CTRRST1 = 0; // absolute time stamp
ECAP1->ECCTL1_bit.STOPWRAP = 1; // Wrap after Capture Event 2
// ECAP1->ECCTL1_bit.SYNCI_EN = 1; // Enable sync in
ECAP1->ECCTL1_bit.SYNCOSEL = 0; // Pass through
ECAP1->ECCTL0_bit.CAPLDEN = 1; // Enable capture units
ECAP1->ECCTL0 = (0 << ECAP_ECCTL0_CAP0POL_Pos) |
(1 << ECAP_ECCTL0_CAP1POL_Pos) |
(0 << ECAP_ECCTL0_CTRRST0_Pos) |
(0 << ECAP_ECCTL0_CTRRST1_Pos) |
(1 << ECAP_ECCTL0_CAPLDEN_Pos) |
(0 << ECAP_ECCTL0_PRESCALE_Pos);
ECAP1->ECCTL1 = (0 << ECAP_ECCTL1_CONTOST_Pos) |
(1 << ECAP_ECCTL1_STOPWRAP_Pos) |
(1 << ECAP_ECCTL1_TSCTRSTOP_Pos) |
(0 << ECAP_ECCTL1_REARM_Pos) |
(0 << ECAP_ECCTL1_SYNCOSEL_Pos);
ECAP1->ECEINT = (1 << ECAP_ECEINT_CEVT0_Pos) |
(1 << ECAP_ECEINT_CEVT1_Pos);
ECAP1->ECCTL1_bit.TSCTRSTOP = 1; // Start Counter
ECAP1->ECCTL1_bit.REARM = 0; // Has no effect (Íå î÷åíü ïîíèìàþ ýòîò ðåãèñòð)
ECAP1->ECCTL0_bit.CAPLDEN = 1; // Enable CAP1-CAP4 register loads
ECAP1->ECEINT_bit.CEVT0 = 1; // 1 events = interrupt
ECAP1->ECEINT_bit.CEVT1 = 1; // 2 events = interrupt
//Èíèöèàëèçàöèÿ ECap3
ECAP2->ECEINT = 0x0000; // Disable all capture interrupts
ECAP2->ECCLR = 0xFFFF; // Clear all CAP interrupt flags
ECAP2->ECCTL0_bit.CAPLDEN = 0; // Disable CAP1-CAP4 register loads
ECAP2->ECCTL1_bit.TSCTRSTOP = 0; // Make sure the counter is stopped
ECAP2->ECCTL0_bit.PRESCALE = 0; // DIV1
//ECAP2->ECCTL0_bit.CAPLDEN = 0; // Disable CAP1-CAP4 register loads
//ECAP2->ECCTL1_bit.TSCTRSTOP = 0; // Make sure the counter is stopped
//
//// Configure peripheral registers
//ECAP2->ECCTL0_bit.CAP0POL = 0; // rising edge
//ECAP2->ECCTL0_bit.CAP1POL = 1; // falling edge
//ECAP2->ECCTL0_bit.CTRRST0 = 0; // absolute time stamp
//ECAP2->ECCTL0_bit.CTRRST1 = 0; // absolute time stamp
//ECAP2->ECCTL0_bit.CAPLDEN = 1; // Enable capture units
//ECAP2->ECCTL0_bit.PRESCALE = 0; // DIV1
//
//ECAP2->ECCTL1_bit.CONTOST = 0; // continuous mode
//ECAP2->ECCTL1_bit.STOPWRAP = 1; // Wrap after Capture Event 2
//ECAP2->ECCTL1_bit.TSCTRSTOP = 1; // Start Counter
//ECAP2->ECCTL1_bit.REARM = 0; // Has no effect (Íå î÷åíü ïîíèìàþ ýòîò ðåãèñòð)
//ECAP2->ECCTL1_bit.SYNCOSEL = 0; // Pass through
//
//ECAP2->ECEINT_bit.CEVT0 = 1; // 1 events = interrupt
//ECAP2->ECEINT_bit.CEVT1 = 1; // 2 events = interrupt
// Configure peripheral registers
ECAP2->ECCTL1_bit.CONTOST = 0; // continuous mode
ECAP2->ECCTL0_bit.CAP0POL = 0; // rising edge
ECAP2->ECCTL0_bit.CAP1POL = 1; // falling edge
ECAP2->ECCTL0_bit.CTRRST0 = 0; // absolute time stamp
ECAP2->ECCTL0_bit.CTRRST1 = 0; // absolute time stamp
ECAP2->ECCTL1_bit.STOPWRAP = 1; // Wrap after Capture Event 2
// ECAP2->ECCTL1_bit.SYNCI_EN = 1; // Enable sync in
ECAP2->ECCTL1_bit.SYNCOSEL = 0; // Pass through
ECAP2->ECCTL0_bit.CAPLDEN = 1; // Enable capture units
ECAP2->ECCTL0 = (0 << ECAP_ECCTL0_CAP0POL_Pos) |
(1 << ECAP_ECCTL0_CAP1POL_Pos) |
(0 << ECAP_ECCTL0_CTRRST0_Pos) |
(0 << ECAP_ECCTL0_CTRRST1_Pos) |
(1 << ECAP_ECCTL0_CAPLDEN_Pos) |
(0 << ECAP_ECCTL0_PRESCALE_Pos);
ECAP2->ECCTL1_bit.TSCTRSTOP = 1; // Start Counter
ECAP2->ECCTL1_bit.REARM = 0; // Has no effect (Íå î÷åíü ïîíèìàþ ýòîò ðåãèñòð)
ECAP2->ECCTL0_bit.CAPLDEN = 1; // Enable CAP1-CAP4 register loads
ECAP2->ECEINT_bit.CEVT0 = 1; // 1 events = interrupt
ECAP2->ECEINT_bit.CEVT1 = 1; // 2 events = interrupt
ECAP2->ECCTL1 = (0 << ECAP_ECCTL1_CONTOST_Pos) |
(1 << ECAP_ECCTL1_STOPWRAP_Pos) |
(1 << ECAP_ECCTL1_TSCTRSTOP_Pos) |
(0 << ECAP_ECCTL1_REARM_Pos) |
(0 << ECAP_ECCTL1_SYNCOSEL_Pos);
ECAP2->ECEINT = (1 << ECAP_ECEINT_CEVT0_Pos) |
(1 << ECAP_ECEINT_CEVT1_Pos);
p->TsNom = ((SystemCoreClock / (drv_params.speed_nom * drv_params.p)) * 15*2);
//êîýôôèöèåíò äëÿ ïåðåñ÷åòà âðåìåíè ìåæäó ìåòêàìè â ìñ â ñêîðîñòü â îá/ìèí
@ -560,7 +604,6 @@ void DPReCAP_SlowCalc(TDPReCAP* p) {
if (p->initialized==0){
p->Init(p);
GPIOA->ALTFUNCSET = (1 << 4) + (1 << 5) + (1 << 6);
GPIOA->DENSET = (1 << 4) + (1 << 5) + (1 << 6);
SIU->REMAPAF_bit.ECAP0EN = 1;
SIU->REMAPAF_bit.ECAP1EN = 1;
SIU->REMAPAF_bit.ECAP2EN = 1;

92
Vsrc/V_Fan.c Normal file
View File

@ -0,0 +1,92 @@
/*!
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_Fan.c
\brief Ìîäóëü ðàáîòû âåíòèëÿòîðà
\author ÎÎÎ "ÍÏÔ Âåêòîð". http://motorcontrol.ru
\version v 1.0 25/08/2017
\addtogroup
@{*/
#include "main.h"
//! \memberof TFanControl
void FanControl_init(TFanControl *p)
{
#if defined (HW_MOTORCONTROLBOARD)
p->Enabled = 1; //Âêëþ÷àåì áëîê âåíòèëÿòîðà
//Ïðîèíèòèì âûõîä äëÿ óïðàâëåíèÿ âåíòèëÿòîðîì
FAN_OFF;
GPIOB->ALTFUNCCLR = (1 << 4); //âûêëþ÷èòü àëüò. ôóíêöèþ
GPIOB->OUTENSET = (1 << 4); //íà âûõîä
#endif
}
//! \memberof TFanControl
void FanControl_slow_calc(TFanControl *p) {
if (p->Enabled){//åñëè åñòü âåíòèëÿòîð
//ñ÷èòàåì äèñêðåòíûé àâòîìàò
p->state_shadow = p->state;
p->state_prev = p->state_shadow;
switch (p->state_shadow) {
case FAN_CONTROL_STATE_OFF: //âåíòèëÿòîð íå ðàáîòàåò, òåìïåðàòóðà èíâåðòîðà ìåíüøå T_on
{
FAN_OFF;
p->StateOn = 0;
if ((p->temperature > p->T_on) || (p->manualOn))
p->state = FAN_CONTROL_STATE_ON;
break;
}
case FAN_CONTROL_STATE_ON: //âêëþ÷åíèå âåíòèëÿòîðà, òåìïåðàòóðà áîëüøå T_on è ìåíüøå T_alarm
{
FAN_ON; //âêëþ÷èòü âåíòèëÿòîð
p->StateOn = 1; //ñîñòîÿíèå ðàáîòû
if (p->temperature > p->T_alarm) //åñëè òåìïåðàòóðà ïîäíÿëàñü åùå áîëüøå, ïåðåõîäèì â ðåæèì ïåðåãðåâà
p->state = FAN_CONTROL_STATE_OVERHEAT;
if ((p->temperature < p->T_off) && (!p->manualOn)) //åñëè òåìïåðàòóðà îïóñòèëàñü íèæå çàäàííîãî óðîâíÿ, ïåðåõîäèì â îáû÷íûé ðåæèì
p->state = FAN_CONTROL_STATE_OFF;
break;
}
case FAN_CONTROL_STATE_OVERHEAT: //òåìïåðàòóðà áîëüøå T_alarm, âåíòèëÿòîð ðàáîòàåò, âûâîäèòñÿ ïðåäóïðåæäåíèå î ïåðåãðåâå
{
FAN_ON; //âêëþ÷èòü âåíòèëÿòîð
p->StateOn = 1; //ñîñòîÿíèå ðàáîòû
drv_status.bit.overheat = 1; //âûâîä ïðåäóïðåæäåíèÿ î ïåðåãðåâå
if (p->temperature < p->T_alarm) { //åñëè òåìïåðàòóðà îïóñòèëàñü íèæå çàäàííîãî óðîâíÿ, ïåðåõîäèì â îáû÷íûé ðåæèì
drv_status.bit.overheat = 0; //ñáðîñ ïðåäóïðåæäåíèÿ î ïåðåãðåâå
p->state = FAN_CONTROL_STATE_ON;
}
break;
}
}
}
}
/*@}*/

View File

@ -32,10 +32,7 @@
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)
@ -44,43 +41,58 @@ void PWM_Module_Init(TPWM_Module *p) {
p->k_pwm = PWM0->TBPRD;
p->FreqPrev = p->Frequency; //предыдущая частота
// ------------------------------------------------------------------------
// Настраиваем модуль ePWM0
// ------------------------------------------------------------------------
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
// Настройка счётчика. в комментарии расписано по полям, но для ускорения всё грузится за один раз
//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; // Разрешить нормальную работу теневых регистров
// Setup shadowing
PWM0->CMPCTL_bit.SHDWAMODE = CC_SHADOW; //âêëþ÷èòü SHADOW äëÿ ñðàâíåíèÿ
PWM0->CMPCTL_bit.LOADAMODE = CC_CTR_ZERO; // Load on period and zero
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.SHDWBMODE = CC_SHADOW; //âêëþ÷èòü SHADOW äëÿ ñðàâíåíèÿ
PWM0->CMPCTL_bit.LOADBMODE = CC_CTR_ZERO; // Load on period and zero
// Настройка теневых загрузок регистров
//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);
// 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; //îáíóëÿåì ïðè ñðàâíåíèè è äåêðåìåíòðîâàíèè
// Настройка действий при сравнении счётчика с уставками
//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 òîæå ñàìîå, ÷òî äëÿ 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; //îáíóëÿåì ïðè ñðàâíåíèè è äåêðåìåíòðîâàíèè
//Для PWMB настройка не нужна, так как он при помощи блока мёртвого времени будет инверсией от канала A
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;
@ -92,82 +104,60 @@ void PWM_Module_Init(TPWM_Module *p) {
// с задержанным задним фронтом инвертируется
// 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_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);
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)
// Настройка 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->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; // ïðîïóñêàåì ñèíõðî-ñèãíàë "íàñêâîçü"
// Настройка счётчика
//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);
// 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
// Теневые регистры, изменения выходных сигналов, мёртвое время
// TZ и прерывания настраиваются так же, как у PWM0
PWM1->CMPCTL = PWM0->CMPCTL;
PWM1->AQCTLA = PWM0->AQCTLA;
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;
PWM1->DBFED = PWM0->DBFED;
PWM1->DBCTL = PWM0->DBCTL;
PWM1->TZCTL = PWM0->TZCTL;
PWM1->ETSEL = PWM0->ETSEL;
// 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; // ØÈÌ âûõîäû â íóæíîå ñîñòîÿíèå
// Обнуление уставок
PWM1->CMPA_bit.CMPA = 0;
PWM1->AQSFRC_bit.RLDCSF = 0;
// ------------------------------------------------------------------------
// Настраиваем модуль ePWM2
@ -177,53 +167,31 @@ void PWM_Module_Init(TPWM_Module *p) {
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; // ðàçðåøàåì âûäà÷ó ñèíõðî-ñèãíàëà
// Настройка счётчика такая же, как у 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;
// 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
// Теневые регистры, изменения выходных сигналов, мёртвое время
// TZ и прерывания настраиваются так же, как у PWM0 и PWM1
PWM2->CMPCTL = PWM0->CMPCTL;
PWM2->AQCTLA = PWM0->AQCTLA;
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;
PWM2->DBFED = PWM0->DBFED;
PWM2->DBCTL = PWM0->DBCTL;
PWM2->TZCTL = PWM0->TZCTL;
PWM2->ETSEL = PWM0->ETSEL;
// 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; // ØÈÌ âûõîäû â íóæíîå ñîñòîÿíèå
// Обнуление уставок
PWM2->CMPA_bit.CMPA = 0;
PWM2->AQSFRC_bit.RLDCSF = 0;
// Отключаем ключи
@ -231,12 +199,8 @@ void PWM_Module_Init(TPWM_Module *p) {
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;
@ -480,7 +444,8 @@ void PWM_Module_Sin_Update(TPWM_Module *p) {
//! \memberof TPWM_Module
void PWM_Module_Separate_Update(TPWM_Module *p) {
_iq PhasePtsA;
// Закомментировано для экономии места
/* _iq PhasePtsA;
_iq PhasePtsB;
_iq PhasePtsC;
_iq knorm;
@ -497,7 +462,7 @@ void PWM_Module_Separate_Update(TPWM_Module *p) {
p->GammaB = _IQmpy(p->k_pwm, PhasePtsB);
p->GammaC = _IQmpy(p->k_pwm, PhasePtsC);
/*íàñûùåíèÿ */
//насыщения
if (p->GammaA < 0)
p->GammaA = 0;
@ -506,7 +471,7 @@ void PWM_Module_Separate_Update(TPWM_Module *p) {
if (p->GammaC < 0)
p->GammaC = 0;
if (p->GammaA > p->k_pwm)
if (p->GammaA > p->k_pwm)
p->GammaA = p->k_pwm + 1;
if (p->GammaB > p->k_pwm)
p->GammaB = p->k_pwm + 1;
@ -516,7 +481,7 @@ void PWM_Module_Separate_Update(TPWM_Module *p) {
PWM0->CMPA_bit.CMPA = (Uint16) p->GammaB;
PWM1->CMPA_bit.CMPA = (Uint16) p->GammaC;
PWM2->CMPA_bit.CMPA = (Uint16) p->GammaA;
*/
}
//! Функция ШИМ для начальной зарядки будстрепных конденсаторов инвертора
@ -555,8 +520,10 @@ void PWM_Module_Update(TPWM_Module *p) {
PWM_Module_Sin_Update(p);
break;
}
case PWM_TYPE_SRD: {
PWM_Module_Separate_Update(p);
default: {
// Защита от неправильных типов ШИМ
p->PWM_type = PWM_TYPE_6SECT_NO_SV;
PWM_Module_No_SV_Update(p);
break;
}
}
@ -610,15 +577,6 @@ void PWM_Module_SlowCalc(TPWM_Module *p) {
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;

View File

@ -80,10 +80,11 @@ void TposspeedEqep_init(TposspeedEqep *p) {
p->resol_inv = 1.0 / ((float) p->resol);
p->Index_eventCounter = 0;
//Инициализация портов ввода вывода
GPIOB->ALTFUNCSET = (1 << 11) + (1 << 12) + (1 << 13);
SIU->REMAPAF_bit.QEPEN = 1;
GPIOB->DENSET = (1 << 11) + (1 << 12) + (1 << 13);//для приема ножки апп. аварии разрешаем работу ножки как цифры
}
//! Функция расчёта скорости и положения, вызывается с необходимой дискретностью
@ -305,6 +306,7 @@ void TposspeedEqep_Calc(TposspeedEqep *p) {
//! \memberof TposspeedEqep
void TposspeedEqep_IndexEvent(TposspeedEqep *p) {
p->Posspeed_FLG2.bit.pos_ident = 1;
p->Index_eventCounter++;
}
//! \memberof TposspeedEqep

View File

@ -1,206 +0,0 @@
/*!
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_RTC_Clock.c
\brief Модуль для работы с часами реального времени
\author ООО "НПФ Вектор". http://motorcontrol.ru
\version v 2.0 25/03/2016
*/
/*
*
* Часы DS1340 работают в режиме слэйва и имеют 10 регимтров данных/контроля (0x0 ... 0x9).
* Время и дата лежат в регистрах 0x0 ... 0x6.
* Регистр контроля часов, регистр заряда акк., и регистр флагов лежат в 0x7 ... 0x9.
* Указатель на текущий регистр можно поменять, отправив в часы соответствующий номер .
* Чтобы прочитать что-то из часов, сначала нужно обратиться к часам в режиме записи и передать номер
* регистра, с которого нужно считать данные. После этого снова нужно обратиться к часам, но уже
* в режиме чтения. Тогда часы начнут слать содержимое всех регистров по очереди, начиная с того
* регистра, адрес которого был передан в предыдущем обращении. При такой "потоковой" передаче
* указатель на текущий регистр будет автоинкрементироваться, причем в такой последовательности
* (предположим, был установлен адрес 0x5)
* 0x5 -> 0x6 -> 0x7 -> 0x0 -> 0x1 -> ... -> 0x7 -> 0x0
* Чтобы попасть в последние два регистра, нужно передать их адреса явно.
*
* Для того, чтобы записать в часики время, нужно проделать примерно то же самое.
* В режиме записи отправляется сначала номер регистра, в который нужно записать что-то, а затем
* данные, которые нужно туда положить. Указатель на регистры при потоковой передаче инкрементируется
* так же, как и при чтении.
*
* Данные хранятся в двоично-десятичном формате.
*/
//Закомменченные функции вверху отличаются от нижних регистрами (NT_RTC и RTC_REG). Нужны ли закомменченные - не знаю.
#include <DSP.h>
#include <main.h>
// Включатель постоянного считывания времени с ЧРВ. Если дефайн закоменчен - считывание производится только при запуске, а потом
// время считается программно. Если раскомменчен - каждую секунду время считается с часов (секунда отсчитывается в мс)
//#define USE_RTC
/* Инициализация RTC */
void RTC_Clock_Init(TRTCClock *p) {
}
/* Функция считывания текущего времени */
void RTC_Clock_Read_Time(TRTCClock *p) {
// Uint16 tempSec, tempMin, tempHour, tempDOW, tempDay, tempMonth, tempYear;
//
// /* Остановить обновление теневых регисторв */
// NT_RTC->SHDW = 0x0;
//
// /* Прочитать время */
// tempSec = NT_RTC->SECOND;
// tempMin = NT_RTC->MINUTE;
// tempHour = NT_RTC->HOUR;
// tempDOW = NT_RTC->WDAY;
// tempDay = NT_RTC->DAY;
// tempMonth = NT_RTC->MONTH;
// tempYear = NT_RTC->YEAR;
//
// /* Запустить обновление теневых регисторв */
//// NT_RTC->SHDW = 0x80;
//
// // Затем нужно отформатировать пришедшие данные, т.к. они приходят в виде двоично-десятичных чисел (отстой)
// p->second = (tempSec & 0xF) + (((tempSec & 0x70) >> 4) * 10);
// p->minute = (tempMin & 0xF) + (((tempMin & 0x70) >> 4) * 10);
// p->hour = (tempHour & 0xF) + (((tempHour & 0x30) >> 4) * 10);
// p->DOW = (tempDOW & 0x7);
// p->day = (tempDay & 0xF) + (((tempDay & 0x30) >> 4) * 10);
// p->month = (tempMonth & 0xF) + (((tempMonth & 0x10) >> 4) * 10);
// p->year = (tempYear & 0xF) + (((tempYear & 0xF0) >> 4) * 10);
//
// // Наконец, упаковка основных показателей в структурку
// p->packed_time = ((Uint32) p->day << 27) + ((Uint32) p->month << 23)
// + ((Uint32) p->year << 17) + ((Uint32) p->hour << 12)
// + ((Uint32) p->minute << 6) + (Uint32) p->second;
}
/* Функция установки времени */
void RTC_Clock_Set_Time(TRTCClock *p) {
// // Временные переменные (секунды, минуты, часы...)
// unsigned char tempSec, tempMin, tempHour, tempDOW, tempDay, tempMonth,
// tempYear;
// p->tryCounter = 0;
//
// // Сначала нужно распаковать дату
// p->second = p->timeToSet & 0x3F;
// p->minute = (p->timeToSet >> 6) & 0x3F;
// p->hour = (p->timeToSet >> 12) & 0x1F;
// p->year = (p->timeToSet >> 17) & 0x3F;
// p->month = (p->timeToSet >> 23) & 0xF;
// p->day = (p->timeToSet >> 27) & 0x1F;
//
// tempSec = ((p->second / 10) << 4) + ((p->second % 10) & 0xF);
// tempMin = ((p->minute / 10) << 4) + ((p->minute % 10) & 0xF);
// tempHour = ((p->hour / 10) << 4) + ((p->hour % 10) & 0xF);
// tempDOW = p->DOW & 0x3;
// tempDay = ((p->day / 10) << 4) + ((p->day % 10) & 0xF);
// tempMonth = ((p->month / 10) << 4) + ((p->month % 10) & 0xF);
// tempYear = ((p->year / 10) << 4) + ((p->year % 10) & 0xF);
//
// p->msInDay = (Uint32) p->hour * 3600000 + (Uint32) p->minute * 60000
// + (Uint32) p->second * 1000;
//
// // Расчёт дня недели (пижонство)
// int16 a = (14 - p->month) / 12;
// int16 y = p->year - a;
// int16 m = p->month + 12 * a - 2;
// p->DOW = (7000 + (p->day + y + y / 4 - y / 100 + y / 400 + (31 * m) / 12))
// % 7;
//
// NT_RTC->YEAR = tempYear;
// NT_RTC->MONTH = tempMonth;
// NT_RTC->DAY = tempDay;
// NT_RTC->WDAY = tempDOW;
// NT_RTC->HOUR = tempHour;
// NT_RTC->MINUTE = tempMin;
// NT_RTC->SECOND = tempSec;
}
void RTC_Clock_Ms_Calc(TRTCClock *p) {
p->ms++;
p->msInDay++;
#ifdef USE_RTC
if (p->ms > 999) {
p->ms = 0;
p->readTimeFlag = 1;
}
//проверка работы часов реального времени и установка, в зависимсоти от этого, указателя для банка аварий
if (p->secondPrev == p->second) //секунда не меняется
p->stoppedCounter++; //считаем, как долго
else //сменилась, значит часы работают
p->stoppedCounter = 0;
if ((p->stoppedCounter < RTC_SECOND_WAITING_TIMEOUT) && (p->year<48)) //часы работают - тикают и год не 2048 (как когда нет батарейки)
p->ClockOk=1;
else
{
p->ClockOk=0;
p->stoppedCounter = RTC_SECOND_WAITING_TIMEOUT;
}
p->secondPrev = p->second;
#else
if (p->ms == 1000) {
p->ms = 0;
p->second++;
if (p->second == 60) {
p->second = 0;
p->minute++;
if (p->minute == 60) {
p->minute = 0;
p->hour++;
if (p->hour == 24) {
p->hour = 0;
p->msInDay = 0;
p->day++;
}
}
}
p->packed_time = ((Uint32)p->day << 27) + ((Uint32)p->month << 23) + ((Uint32)p->year << 17) +
((Uint32)p->hour << 12) + ((Uint32)p->minute << 6) + (Uint32)p->second;
}
#endif
}
void RTC_Clock_Slow_Calc(TRTCClock *p) {
if (p->setTimeFlag == 1) {
p->timeToSet = p->packed_time;
p->set(p);
p->read(p);
p->msInDay = (Uint32) p->hour * 3600000 + (Uint32) p->minute * 60000
+ (Uint32) p->second * 1000;
p->setTimeFlag = 0;
} else if (p->readTimeFlag == 1) {
p->read(p);
p->readTimeFlag = 0;
}
}

View File

@ -32,71 +32,59 @@
//! \memberof TSSI_Encoder
void SSI_Encoder_init(TSSI_Encoder *p) {
// volatile long delay;
// volatile Uint32 tempREG;
//
// //SPI-SOMI - на VectorCard нога 88, на проце B15, SPI_RXD2
// //SPI-SIMO - на VectorCard нога 38, на проце C6, SPI_TXD2
// //SPI-CLK - на VectorCard нога 39, на проце B14, SPI_CLK2
// //SPI-STE - на VectorCard нога 89, на проце B13, SPI_FSS2
// //Плата texas DRV8301-HC-EVM разведена так, что микроконтроллер - это ведомое устройство.
// //Нужно сделать его мастером. Подробнее читайте комментарий в заголовочном файле.
//
// // Настройка ног SPI
// GPIOB->ALTFUNCSET = (1 << 13);//чип-селект
// GPIOB->ALTFUNCSET = (1 << 14) | (1 << 15);
// NT_GPIOC->ALTFUNCSET = (1 << 6);//SIMO
// NT_COMMON_REG->GPIOPCTLB_bit.PIN13 = 2;//чип-селект
// NT_COMMON_REG->GPIOPCTLB_bit.PIN14 = 2;
// NT_COMMON_REG->GPIOPCTLB_bit.PIN15 = 2;
// NT_COMMON_REG->GPIOPCTLC_bit.PIN6 = 2;//SIMO
//
//
// // Настройка тактирования SSP модуля
// // Всего 4 модуля, на каждый модуль по 8 бит из регистра SSP_CLK_CTRL и по два бита из UART_SSP_CLK_SEL
//
// // UART_SSP_CLK_SEL
// // Во втором байте слова на каждый из 4-ёх модулей SSP отводится по два бита для выбора источника тактирования 0x0000XX00
// // "00" - в качестве иточника тактирования модуля SSP выбирается системная частота 100 МГц, таким образом f_SSP_IN = SysClk = 100 MHz
//
// // SSP_CLK_CTRL
// // Младший бит разрешает тактирование (1 - разрешить)
// // Второй бит разрешает деление частоты f_SSP_IN источника тактового сигнала (0 - не делить, 1 - делить)
// // Старшие шесть выбирают делитель частоты этого исотчника:
// // X - деление по формуле SSPclk = f_SSP_IN /( 2 * (X +1) )
// // Из документации на блок SSP - минимальная частота для работы модуля в режимах и мастер и слейв,
// // f_SSP_IN > 22.12 MHz, поэтому 25 МГц сделаем
// /* закомменчены, так как тоже самое делается в DRV8301_SPI
// tempREG = NT_COMMON_REG->UART_SPI_CLK_SEL;// Через tempREG, чтобы не задеть другие биты, отвечающие за тактирование UART'a
// tempREG &= 0xFFFF00FF;
// NT_COMMON_REG->UART_SPI_CLK_SEL = tempREG;
// NT_COMMON_REG->SPI_CLK = 0x07070707;// Разрешить тактирование, разрешить деление частоты, делить на 4 - 25 МГц
// */
//
//
// // Настройка самого модуля SPI
// // Продолжение настройки тактирования.
// // Полученная ранее частота f_SSP_IN проходит ещё через два делителя.
// // SSPCPSR - первый делитель, в диапазоне 2 ... 254, может быть только чётным (младший бит всегда хардварно равен 0)
// // SSPCR0.bit.SCR - второй делитель от 0 до 255.
// // Битрейт в итоге BitRate = f_SSP_IN / ( SSPCPSR * (SCR + 1) )
//
// SPI2->SPI_CR1 = 0;// Режим - мастер, LoopBack отключён, сам модуль SSP тоже отключён
// SPI2->SPI_IMSC = 0x0; // Запретить все прерывания
// SPI2->SPI_DMACR = 0; // Запретить DMA
// SPI2->SPI_ICR = 0x3; // Очистка прерываний ("переполнение FIFO приёма" и "необслуженное FIFO приёма")
//
// SPI2->SPI_CPSR = 4; // Деление входной частоты на 4 -> 6,25 MHz
// SPI2->SPI_CR0_bit.DSS = 12; // Размер данных - 12 бит
// SPI2->SPI_CR0_bit.SCR = 0x3F; // Второй делитель
// SPI2->SPI_CR0_bit.FRF = 0x0; // Какая-то "фаза" для протокола Motorola SPI
// SPI2->SPI_CR0_bit.SPH = 0x1; // Какая-то "полярность" для протокола Motorola SPI
// SPI2->SPI_CR0_bit.SPO = 0x0; // Выбор формата кадра Motorola/TI/Microwire. "0" - по протоколу Motorola SPI
// SPI2->SPI_CR1_bit.SSE = 1; // Разрешить работу
//
// p->resol_inv = 1.0 / ((float) p->resol);
//
// p->read(p);
volatile long delay;
volatile Uint32 tempREG;
// Настройка ножек под SPI
GPIOB->ALTFUNCSET = (1 << 5) | (1 << 6); // Тактирование (SPI_SCK)
// Настройка модуля SPI
// Тактирование модуля SPI в файле "src/system_K1921VK035.c" настроено на fIN = 25 МГц
// Эта частота проходит ещё через два делителя.
// SSPCPSR - первый делитель, в диапазоне 2 ... 254, может быть только чётным (младший бит всегда аппаратно равен 0)
// SSPCR0.bit.SCR - второй делитель от 0 до 255.
// Битрейт в итоге BitRate = fIN / ( CPSR * (SCR + 1) )
SPI->IMSC = 0x0; // Запретить все прерывания
SPI->DMACR = 0; // Запретить DMA
SPI->ICR = 0x3; // Сброс прерываний на всякий случай ("переполнение FIFO приёма" и "необслуженное FIFO приёма")
SPI->CPSR = 4; // Деление входной частоты на 4
// В CR0 настраивается второй делитель частоты, разрешение и режим работы энкодера.
//
// Второй делитель = 62, итого f_ssp = 25 МГц / (4 * (62 + 1)) = 99,2 кГц
//
// Настройка фазы и полярности для работы в режиме SPI
// По описанию на датчик дела такие: по первому падающему фронту он загружает в свой
// внутренний регистр новые данные, а с каждым растущим фронтов выводит их на линию.
// Стало быть данные на линии меняются на растущем фронте, а значит считывать их надо
// на падающем. Но при этом по самому первому фронту ничего вычитывать не надо, а значит
// старший бит принятых данных надо обнулять.
// Кроме того на ОИ клок инвертируется, и это надо учитывать в настройке.
//
// Размер кадра на 1 больше, чем число в регитсре, стало быть (12 + 1) = 13 бит, из которых первый выкинем
//
// В целях экономии места, запись одной строкой
//SPI->CR0_bit.FRF = 0x0; // SSI работает в режиме SPI, что позволяет задать, по какому фронту читать данные
//SPI->CR0_bit.SPO = 0x0; // В режиме ожидания CLK в нуле (после инверсии получится в единице)
//SPI->CR0_bit.SPH = 0x0; // Выборка данных по растущему фронту синхросигнала (после инверсии получится по падающему)
//SPI->CR0_bit.SCR = 62; // Второй делитель = 62 + 1 = 63
//SPI->CR0_bit.DSS = SSI_ENC_RESOLUTION; // Размер кадра 12 + 1 = 13 бит
SPI->CR0 = (SSI_ENC_RESOLUTION << SPI_CR0_DSS_Pos) | (62 << SPI_CR0_SCR_Pos);
// В этих комментариях расписано по каждому полю, что как присваивается, но
// для экономии на инструкциях записывается одним действием
//SPI->CR1_bit.MS = 0; // Режим - мастер
//SPI->CR1_bit.RXIFLSEL = 0; // Глубина FIFO на приём = 0 (FIFO не используется)
//SPI->CR1_bit.TXIFLSEL = 0; // Глубина FIFO на отправку = 0 (FIFO не используется)
//SPI->CR1_bit.SSE = 1; // Разрешить работу SPI
SPI->CR1 = (1 << SPI_CR1_SSE_Pos);
p->resol_inv = 1.0 / ((float) p->resol);
p->read(p);
}
@ -110,51 +98,51 @@ void SSI_Encoder_Calc(TSSI_Encoder *p) {
void SSI_Encoder_Read(TSSI_Encoder*p) {
// _iq theta_elec_temp;
// Uint16 Data_read=0;
// _iq theta_mech_temp;
//
// if (SPI2->SPI_SR_bit.BSY == 0){//SPI свободен
// Data_read = SPI2->SPI_DR;//код с датчика (число от 0 до resol)
// SPI2->SPI_DR = 0xff;//отправляем что угодно, главное, чтобы тактирование шло
//
//
// if (p->rotation_dir)//обратное направление вращения
// Data_read=(p->resol-1)-Data_read;//период - текущее
// p->Poscnt_res=Data_read;
// }
//
// //перевод угла в метках на обороте в механический угол
// //Здесь расчет во float - желательно переделать в IQ
// p->theta_mech = _IQ((float )p->Poscnt_res * p->resol_inv); //расчёт механического угла
// p->theta_mech &= 0x00FFFFFF;
// //Фильтр угла
// if (p->theta_mech_filterK!=0){
// p->theta_mech_filtered=p->theta_mech_filtered+_IQmpy(p->theta_mech_filterK,((p->theta_mech-p->theta_mech_filtered+_IQ(0.5))&0x00FFFFFF)-_IQ(0.5));
// p->theta_mech_filtered&=0x00FFFFFF;
// }else
// p->theta_mech_filtered=p->theta_mech;
//
// // Подсчёт количества полных оборотов.
// if (p->prevThetaMech - p->theta_mech_filtered > _IQ(0.5))
// p->RevolutionCounter++;
// if (p->prevThetaMech - p->theta_mech_filtered < _IQ(-0.5))
// p->RevolutionCounter--;
// p->prevThetaMech=p->theta_mech_filtered;
//
// //угол в метках без обнуления на обороте, абсолютный
// p->Poscnt_resContinouosLong=p->Poscnt_res+(p->resol*p->RevolutionCounter);
// p->Poscnt_resContinouosInt=p->Poscnt_resContinouosLong;//чтобы было уднобно смотреть в 16ти разрядном осциллографе
// p->Poscnt_resContinouosInt8=p->Poscnt_resContinouosLong&0xF;//чтобы видеть метки в крупном масштабе
//
// //перевод угла в метках абсолютных (не обнуляемых наобороте) в механический угол
// //на 127 оборотах всё переполнится, но для демо сгодится
// p->theta_mechContinouos = p->theta_mech_filtered + _IQ(p->RevolutionCounter); //расчёт механического угла
// p->theta_elecContinouos = p->theta_mechContinouos*p->pole_pairs+ p->AngleOffset;//электрический угол абсолютный (не обнуляемый)
//
// //Расчёт электрического положения обнулемого по достижению 360 градусов
// p->theta_el_tmp = p->theta_mech_filtered*p->pole_pairs + p->AngleOffset;
// p->theta_elec = p->theta_el_tmp & 0x00FFFFFF;
_iq theta_elec_temp;
Uint16 Data_read=0;
_iq theta_mech_temp;
if (SPI->SR_bit.BSY == 0){//SPI свободен
Data_read = SPI->DR & SSI_ENC_DATA_MASK;//код с датчика (число от 0 до resol) с обнулённым старшим разрядом
SPI->DR = 0xff;//отправляем что угодно, главное, чтобы тактирование шло
if (p->rotation_dir)//обратное направление вращения
Data_read=(p->resol-1)-Data_read;//период - текущее
p->Poscnt_res=Data_read;
}
//перевод угла в метках на обороте в механический угол
//Здесь расчет во float - желательно переделать в IQ
p->theta_mech = _IQ((float )p->Poscnt_res * p->resol_inv); //расчёт механического угла
p->theta_mech &= 0x00FFFFFF;
//Фильтр угла
if (p->theta_mech_filterK!=0){
p->theta_mech_filtered=p->theta_mech_filtered+_IQmpy(p->theta_mech_filterK,((p->theta_mech-p->theta_mech_filtered+_IQ(0.5))&0x00FFFFFF)-_IQ(0.5));
p->theta_mech_filtered&=0x00FFFFFF;
}else
p->theta_mech_filtered=p->theta_mech;
// Подсчёт количества полных оборотов.
if (p->prevThetaMech - p->theta_mech_filtered > _IQ(0.5))
p->RevolutionCounter++;
if (p->prevThetaMech - p->theta_mech_filtered < _IQ(-0.5))
p->RevolutionCounter--;
p->prevThetaMech=p->theta_mech_filtered;
//угол в метках без обнуления на обороте, абсолютный
p->Poscnt_resContinouosLong=p->Poscnt_res+(p->resol*p->RevolutionCounter);
p->Poscnt_resContinouosInt=p->Poscnt_resContinouosLong;//чтобы было уднобно смотреть в 16ти разрядном осциллографе
p->Poscnt_resContinouosInt8=p->Poscnt_resContinouosLong&0xF;//чтобы видеть метки в крупном масштабе
//перевод угла в метках абсолютных (не обнуляемых наобороте) в механический угол
//на 127 оборотах всё переполнится, но для демо сгодится
p->theta_mechContinouos = p->theta_mech_filtered + _IQ(p->RevolutionCounter); //расчёт механического угла
p->theta_elecContinouos = p->theta_mechContinouos*p->pole_pairs+ p->AngleOffset;//электрический угол абсолютный (не обнуляемый)
//Расчёт электрического положения обнулемого по достижению 360 градусов
p->theta_el_tmp = p->theta_mech_filtered*p->pole_pairs + p->AngleOffset;
p->theta_elec = p->theta_el_tmp & 0x00FFFFFF;
}

129
Vsrc/V_UdControl.c Normal file
View File

@ -0,0 +1,129 @@
/*!
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_UdControl.c
\brief Ìîäóëü ïëàâíîãî çàðÿäà ÇÏÒ
\author ÎÎÎ "ÍÏÔ Âåêòîð". http://motorcontrol.ru
\version v 1.0 25/08/2017
\addtogroup
@{*/
#include "main.h"
#if defined (HW_MOTORCONTROLBOARD)
#define UD_CONTROL_OFF GPIOB->DATAOUTCLR = (1 << 10);
#define UD_CONTROL_ON GPIOB->DATAOUTSET = (1 << 10);
#else
#define UD_CONTROL_OFF // îïåðàöèÿ äëÿ âûêëþ÷åíèÿ
#define UD_CONTROL_ON // îïåðàöèÿ äëÿ âêëþ÷åíèÿ
#endif
//!Èíèöèàëèçàöèÿ.
//!Êîíôèãóðèðóåì íîæêó êîíòðîëëåðà, óïðàâëÿþùóþ öåïüþ çàðÿäà íà âûâîä.
//! \memberof TUdControl
void UdControl_init(TUdControl *p) {
#ifdef HW_MOTORCONTROLBOARD
p->Enabled = 1; //Âêëþ÷àåì áëîê çàðÿäà ÇÏÒ
// Íîæêà, óïðàâëÿþùàÿ öåïüþ çàðÿäà
GPIOB->ALTFUNCCLR = (1 << 10); // Îáû÷íûé GPIO
GPIOB->OUTENSET = (1 << 10); // Ðàáîòàùèé íà âûõîä
UD_CONTROL_OFF; //ñíà÷àëà âûêëþ÷èì
p->state = UD_CONTROL_STATE_OFF; //è åùå â ñîñòîÿíèå "âûêëþ÷åíî"
p->StateOn = 0;
#else
p->Enabled = 0; //Âûêëþ÷èòü áëîê çàðÿäà ÇÏÒ
#endif
}
//!Ðàñ÷åò.
//!Äèñêðåòíûé àâòîìàò, óïðàâëÿþùèé öåïüþ çàðÿäà. Âûçûâàòü íàäî â êàêîì-íèáóäü
//!áûñòðîì ïðåðûâàíèè (íàïðèìåð 10êÃö). Ìîæåò, áóäåò ðàáîòàòü è â 1êÃö, íî
//!íå ïðîâåðÿëîñü. Èìååò òðè ñîñòîÿíèÿ: âûêëþ÷åíî, îæèäàíèå çàðÿäà è âêëþ÷åíî.
//!âñå ïåðåêëþ÷åíèÿ ïðîèñõîäÿò íà îñíîâå èçìåðÿåìîãî íàïðÿæåíèÿ íà ÇÏÒ.
//! \memberof TUdControl
void UdControl_calc(TUdControl *p) {
if (p->Enabled){//åñëè åñòü öåïü óïðàâëåíèÿ çàðÿäîì ÇÏÒ
p->fUdc.input = adc.Udc_meas; //íà âõîä ôèëüòðà - íàïðÿæåíèå ñ ÇÏÒ
p->fUdc.calc(&(p->fUdc));
//ñ÷èòàåì äèñêðåòíûé àâòîìàò
if (p->state_prev != p->state)
p->E = 1; //ïåðâîå âõîæäåíèå
else
p->E = 0;
p->state_prev = p->state;
switch (p->state) {
case UD_CONTROL_STATE_OFF: //êëþ÷ âûêëþ÷åí
{
UD_CONTROL_OFF; //âûêëþ÷àåì êëþ÷
p->StateOn = 0; //ñîñòîÿíèå âûêëþ÷åíî
if (adc.Udc_meas > p->U_on) //íàïðÿæåíèå ïî÷òè âûñîêî
p->state = UD_CONTROL_STATE_WAIT; //ïåðåõîäèì â îæèäàíèå
break;
}
case UD_CONTROL_STATE_WAIT: //êëþ÷ âûêëþ÷åí, ãîòîâèìñÿ âêëþ÷èòü
{
if (p->E == 1) //ïåðâîå âõîæäåíèå
{
p->StateCounter = 0;
}
p->StateCounter += global_time.relative_time1.delta_millisecond;
UD_CONTROL_OFF; //âûêëþ÷àåì êëþ÷
p->StateOn = 0; //ñîñòîÿíèå âûêëþ÷åíî
if (adc.Udc_meas < p->U_off) //õîòåëè âðîäå âêëþ÷àòü, íî íàïðÿæåíèå ñíèçèëîñü...
p->state = UD_CONTROL_STATE_OFF;
if (global_time.relative_time1.delta_millisecond) { //åñëè ñòîèò áèò ìèëëèñåêóíäû
//ïðîèçâîäíàÿ íà ìèëëèñåêóíäå
p->deriv_time_ZPT = (labs(p->fUdc.output - p->fUdc_output_prev))<<11; //ïîäíèìåì çíà÷åíèå ïðîèçâîäíîé äëÿ ïîëó÷åíèÿ óðîâíÿ îêîëî 1
p->fUdc_output_prev = p->fUdc.output;
}
//òàéìàóò âêëþ÷åíèÿ è ïðîèçâîäíàÿ
if ((p->StateCounter >= p->Timeout_on) && (p->deriv_time_ZPT < p->deriv_const) && (adc.Udc_meas > p->U_off)) { //è ïðîèçâîäíàÿ ìåíüøå çàäàííîãî óðîâíÿ
p->state = UD_CONTROL_STATE_ON;
p->StateCounter = 0;
}
break;
}
case UD_CONTROL_STATE_ON: {
if ((adc.Udc_meas < p->U_off) && (drv_status.bit.running == 0)) //ðàáîòàëè-ðàáîòàëè, à òóò íàïðÿæåíèå ñíèçèëîñü... Åñëè âäðóã íàïðÿæåíèå ñíèçèëîñü âî âðåìÿ ðàáîòû, òî ðàçìûêàòü íå äàåì
p->state = UD_CONTROL_STATE_OFF;
UD_CONTROL_ON; //âêëþ÷åì êëþ÷
p->StateOn = 1; //ñîñòîÿíèå âêëþ÷åíî
break;
}
}
}
}
/*@}*/

View File

@ -103,19 +103,18 @@ void AdcDrv_fast_calc(TAdcDrv *p) {
p->IA_temp = ADC->SEQ[0].SFIFO;
p->IB_temp = ADC->SEQ[0].SFIFO;
p->Udc_temp = ADC->SEQ[0].SFIFO;
p->T_temp = ADC->SEQ[0].SFIFO;
p->AI_temp = ADC->SEQ[0].SFIFO;
// Î÷èñòêà FIFO íà ñëó÷àé, åñëè ïî÷åìó-òî òàì îêàçàëîñü áîëüøå ÷åì íàäî çíà÷åíèé (áûâàåò ïîñëå îñòàíîâêè æèòàãîì)
while (ADC->SEQ[0].SFLOAD)
trash = ADC->SEQ[0].SFIFO;
p->Imeas_a = p->IaGainNom * (((p->IA_temp<< 4) + p->Imeas_a_offset));
p->Imeas_b = p->IbGainNom * (((p->IB_temp<< 4) + p->Imeas_b_offset));
p->Imeas_a = p->IaGainNom * ((p->IA_temp<< 4) + p->Imeas_a_offset);
p->Imeas_b = p->IbGainNom * ((p->IB_temp<< 4) + p->Imeas_b_offset);
p->Udc_meas = p->UdcGainNom * (p->Udc_temp + p->Udc_meas_offset);
p->Imeas_c = -p->Imeas_a - p->Imeas_b;
p->T_meas = p->T_temp * p->TGainNom;
p->AI_meas = p->AI_temp * p->AIGainNom;
//ADC->SEQ[0].SCCTL_bit.RAVGEN ^= 1;
}
//!Ìåäëåííûé ðàñ÷åò.
@ -172,9 +171,8 @@ void AdcDrv_slow_calc(TAdcDrv *p) {
p->IaGainNom = _IQ16mpy(p->Imeas_a_gain, drv_params._1_I_nom) << 1;
p->IbGainNom = _IQ16mpy(p->Imeas_b_gain, drv_params._1_I_nom) << 1;
p->IcGainNom = _IQ16mpy(p->Imeas_c_gain, drv_params._1_I_nom) << 1;
p->UdcGainNom = _IQ16mpy(p->Udc_meas_gain, drv_params._1_Udc_nom) << 4;
p->TGainNom = _IQ16mpy(p->T_meas_gain,_IQ(0.05)) << 4;
p->AIGainNom = _IQ16mpy(p->AI_meas_gain, _IQ(1)) << 4;
}
//! Ìèëëèñåêóíäíûé ðàñ÷åò

View File

@ -248,8 +248,7 @@ Uint16 i2c_readArray(Uint16 address, Uint16* readDataPtr_u16, Uint16 length_u8){
// Инит модуля I2C и GPIO, к которым подключена память
void I2CMEM_Init(TI2cMem*p){
// Разрешаем работу 0 и 1 ножек порта А и переводим их в периферийный режим
GPIOA->DENSET |= 0x3;
GPIOA->ALTFUNCSET |= 0x3;
GPIOA->ALTFUNCSET = 0x3;
// Разрешаем работу I2C модуля и ставим ему скорость
// Fi2c = Fcpu / (4 * SCLFRQ), а Fcpu для 035 = 100 МГц

View File

@ -1,78 +0,0 @@
/*!
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 Vled.c
\brief Óïðàâëåíèå ñâåòîäèîäàìè
\author ÎÎÎ "ÍÏÔ Âåêòîð". http://motorcontrol.ru
\version v 2.0 25/03/2016
\addtogroup led
*/
#include "DSP.h"
#include "main.h"
void LED_init(Tled *p) {
}
void LED_toggle(Tled *p, Uint16 led) {
}
void LED_on(Tled *p, Uint16 led) {
}
void LED_off(Tled *p, Uint16 led) {
}
void LED_clearAll(Tled *p) {
}
void LED_mode0(Tled *p) {
}
void LED_mode1(Tled *p) {
}
void LED_mode2(Tled *p) {
}
void LED_mode3(Tled *p) {
}
void LED_msCalc(Tled *p) {
}

View File

@ -1,109 +0,0 @@
/*!
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_pid_reg3.c
\brief ÏÈÄ-ðåãóëÿòîð (ñì. TPidReg3)
\author ÎÎÎ "ÍÏÔ Âåêòîð". http://motorcontrol.ru
\version v 2.0 25/03/2016
\addtogroup V_pid_reg3
@{*/
#include "V_IQmath.h" // Include header for IQmath library
#include "V_pid_reg3_pos.h"
#include "stdlib.h"
#include "main.h"
//! Ôóíêöèÿ ðàñ÷åòà ÏÈÄ ðåãóëÿòîðà
//! Âîîáùå ýòî ÷óòü äîðàáîòàííàÿ âåðñèÿ òåêñàñîâñêîãî ðåãóëÿòîðà
//! Äîêóìåíòàöèþ ýòîé ìàãèè ëó÷øå âñåãî ïîñìîòðåòü, çàãóãëèâ pid_reg3.pdf
//! Íà âõîäå pid_ref_reg3 - çàäàíèå, pid_fdb_reg3 - îáðàòíàÿ ñâÿçü
//! Íà âûõîäå pid_out_reg3.
//! \memberof TPidReg3
void pid_reg3_calc_pos(TPidReg3_pos *v) {
v->e_reg3 = v->pid_ref_reg3 - v->pid_fdb_reg3;//îøèáêà - çàäàíèå ìèíóñ îáðàòíàÿ ñâÿçü
v->e_reg3Dz=v->e_reg3;//îøèáêà ïîñëå êîððåêöèè áëîêà ìåðòâîé çîíû
if (v->DeadZone!=0){//åñëè åñòü óñòàâêà çîíû íå÷óâñòâèòåëüíîñòè
if (v->e_reg3Dz>0){//îøèáêà â ïëþñ
v->e_reg3Dz=v->e_reg3Dz-v->DeadZone;//âû÷èòàåì ìåðòâóþ çîíó
if (v->e_reg3Dz<0)//íî òàê, ÷òîáû îøèáêà íå ñòàëà îòðèöàòåëüíîé
v->e_reg3Dz=0;
}
if (v->e_reg3Dz<0){
v->e_reg3Dz=v->e_reg3Dz+v->DeadZone;
if (v->e_reg3Dz>0)
v->e_reg3Dz=0;
}
}
v->up_reg3 = _IQmpy(v->Kp_reg3, v->e_reg3Dz);
v->uprsat_reg3 = v->up_reg3 + v->ui_reg3 + v->ud_reg3;
if (v->uprsat_reg3 > v->pid_out_max)
v->pid_out_reg3 = v->pid_out_max;
else if (v->uprsat_reg3 < v->pid_out_min)
v->pid_out_reg3 = v->pid_out_min;
else
v->pid_out_reg3 = v->uprsat_reg3;
v->saterr_reg3 = v->pid_out_reg3 - v->uprsat_reg3 + v->saterr_reg3Add;
//èñïîëüçîâàòü ëè ôèëüòð äëÿ äèôô. ÷àñòè. Åñëè êôèëüòðà íîëü, òî íåò.
if (v->Kf_d == 0){
v->e_reg3_filterOut = v->e_reg3;//âûõîä ôèëüòðà
}
else{//èíà÷å ñ÷èòàåì ôèëüòð
v->e_reg3_filterOut = posspeedEqep.speed_elec;
}
if ((v->DiffCounter++ + 1) >= v->DiffDelim) {//êàæäûå ñêîëüêî âûçîâîâ ñ÷èòàòü äèôô. ÷àñòü
if (v->KdFilterInitFlag==1){//ýòî ïåðâûé òàêò ðàñ÷åòà ðåãóëÿòîðà
v->e_reg3_filterOut = posspeedEqep.speed_elec;//âûõîä ôèëüòðà îøèáêè èíèöèàëèçèðóåì îøèáêîé
v->KdFilterInitFlag=0;//èíèöèàëèçàöèÿ çàâåðøåíà
}
//v->ud_reg3 = _IQmpy(v->Kd_reg3, (v->e_reg3_filterOut - v->up1_reg3)<<6);//äèôôåðåíöèàëüíàÿ ÷àñòü
v->ud_reg3 = _IQmpy(v->Kd_reg3,-posspeedEqep.speed_filter.output);
v->DiffCounter = 0;
}
if (v->Ki_reg3 != 0)//åñòü èíòåãðàëüíàÿ ñîñòàâëÿþùàÿ
v->ui_reg3 = v->ui_reg3
+ _IQmpy(v->Ki_reg3,
v->up_reg3) + _IQmpy(v->Kc_reg3,v->saterr_reg3);
else
v->ui_reg3 = 0;
if (v->Kc_reg3 == 0) {
if (v->ui_reg3 > v->pid_out_max)
v->ui_reg3 = v->pid_out_max;
else if (v->ui_reg3 < v->pid_out_min)
v->ui_reg3 = v->pid_out_min;
}
}
//! \memberof TPidReg3
void pid_reg3_reset_pos(TPidReg3_pos *v) {
v->pid_fdb_reg3=0;
v->pid_ref_reg3=0;
v->ui_reg3=0;
v->KdFilterInitFlag=1;
}
/*@}*/

File diff suppressed because it is too large Load Diff

View File

@ -26,52 +26,49 @@
#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_pos pid_pos = PIDREG3_DEFAULTS_POS; //!<Рег. положения
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; //!< Модуль защит
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
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; //!< Модуль работы с энергонезависимой памятью.
Tled leds = LED_DEFAULTS; //!< модуль для красивого мигания светодиодами
//TCanBTInterface Can2BTInterface = T_CANBT_INTERFACE_DEFAULTS;//!<Пакетная передача CANopen
TRTCClock RTCclock = RTC_CLOCK_DEFAULTS; //!< Модуль работы с часами реальноговремени. "spi" - по историческим причинам совместимости
TAutoOffset AutoOffset = AUTO_OFFSET_DEFAULTS; //!<Автоматическая подстройка смещения токов АЦП
TSSI_Encoder SSI_Encoder = SSI_ENCODER_DEFAULTS; //!<Драйвер обработки датчика положения с SSI интерфейсом
//TMotorModel model = MOTOR_MODEL_DEFAULTS; //!< Модели электродвигателей для отладки "на столе" в режиме симулятора
TRotorObserver RotorObserver = ROTOR_OBSERVER_DEFAULTS; //!<Датчиковый наблюдатель потокосцепления ротора асинхронного двигателя
TCANtoRS CANtoRS = CAN_TO_RS_DEFAULTS; //!<Модуль для работы с драйвером CANopen через UART (RS). Посылки CAN запаковываются в UART
//TModBus ModBus = MODBUS_DEFAULTS; //!<Драйвер для работы по протоколу MODBUS
//TMBVarsConv MBVarsConv = MBVARSCONV_DEFAULTS;//!< Модуль преобразования данных из формата 16 разрядов Modbus в формат системы управления (IQ 24)
TDrvInterface drv_interface = DRV_INTERFACE_DEFAULTS; //!<Интерфейс длЯ работы с банками аварий, событий и т.п.
TLogger FaultLog = LOGGER_DEFAULTS; //!<Протоколирование аварий
TGlobalTime global_time = GLOBAL_TIME_DEFAULTS; //!<Работа с часами
TRefs refs; //!< Структура с заданиями (токи, скорости)
TCmd cmd = { 0 }; //!< Структура с командами управления
TDrvStatus drv_status = { 0 }; //!< Текущий статус привода
TDrvParams drv_params; //!< Параметры двигателя
TSysSwitches sw; //!< Различные дискретные настройки системы управления
TRefs refs; //!< Структура с заданиями (токи, скорости)
TCmd cmd = { 0 }; //!< Структура с командами управления
TDrvStatus drv_status = { 0 }; //!< Текущий статус привода
TDrvParams drv_params; //!< Параметры двигателя
TSysSwitches sw; //!< Различные дискретные настройки системы управления
Uint32 VendorToken=0x11111111;//!< Уникальный ключ производителя, нужный для программы UniCON и COODEdit для различных наборов текстов разных произхводителей
int drv_status_code; //!<Статус системы управления в виде константы (ГОТОВ, РАБОТА и т.п.)
Uint32 VendorToken=0x11111111; //!< Уникальный ключ производителя, нужный для программы UniCON и COODEdit для различных наборов текстов разных произхводителей
int drv_status_code; //!<Статус системы управления в виде константы (ГОТОВ, РАБОТА и т.п.)
//Переменные для отладки - выведены в словарь CANOpen,
//В них можно присваивать любую другую переменную и наблюдать её
@ -216,11 +213,7 @@ void CAP0_IRQHandler(void)
//Засекает время между этим импульсом и предыдущими для расчета интерполятора угла и частоты вращения (скорости)
DPReCAP.CAP1Calc(&DPReCAP);
//Подтверждение прерываний
ECAP0->ECCLR_bit.CEVT0 = 1;
ECAP0->ECCLR_bit.CEVT1 = 1;
ECAP0->ECCLR_bit.INT = 1;
//Подтверждение прерываний производится в 10 кГц прерывании
}
//!Прерывание, возникающее по событиям захвата модуля CAP1
@ -247,10 +240,7 @@ void CAP1_IRQHandler(void)
DPReCAP.Angle6Calc(&DPReCAP);
DPReCAP.CAP2Calc(&DPReCAP);
//Подтверждение прерываний
ECAP1->ECCLR_bit.CEVT0 = 1;
ECAP1->ECCLR_bit.CEVT1 = 1;
ECAP1->ECCLR_bit.INT = 1;
//Подтверждение прерываний производится в 10 кГц прерывании
}
@ -278,10 +268,7 @@ void CAP2_IRQHandler(void)
DPReCAP.Angle6Calc(&DPReCAP); //если убрать, то в момент прихода метки на один период ШИМ косяк, так как прерывание посчиталось, а Angle6Calc нет
DPReCAP.CAP3Calc(&DPReCAP);
//Подтверждение прерываний
ECAP2->ECCLR_bit.CEVT0 = 1;
ECAP2->ECCLR_bit.CEVT1 = 1;
ECAP2->ECCLR_bit.INT = 1;
//Подтверждение прерываний производится в 10 кГц прерывании
}
//!Прерывание, возникающее по событию реперной метки(индекса) модуля QEP

233
cood.xml
View File

@ -2861,12 +2861,6 @@
<defaults default="0" min="" max=""/>
<description description=""/>
</obj_2506h.04h>
<obj_250Fh.00h DataType="Editable" name="×àñû ðåàëüíîãî âðåìåíè" addr="RTCclock.packed_time" group="1" groupName="Íàáëþäàåìûå" fullgroup="" callback="callback_RTC">
<format Type="StandartNum" Size="32" Signed="false"/>
<text text="RTC" textID="311"/>
<defaults default="438392299" min="" max=""/>
<description description=""/>
</obj_250Fh.00h>
<obj_2532h.00h DataType="Viewable" name="Ñèñòåìíûé îáúåêò" addr="" group="12" groupName="Ðåã. òîêà ÿêîðÿ" fullgroup="12" callback="">
<format Type="Root"/>
<text text="System" textID="312"/>
@ -3667,42 +3661,36 @@
<defaults default="0" min="" max=""/>
<description description=""/>
</obj_5114h.00h>
<obj_5114h.01h DataType="Viewable" name="Òèï àïïàðàòíîé ÷àñòè" addr="sw.HardwareType" group="14" groupName="Íàñòðîéêè ÑÓ" fullgroup="28" callback="">
<format Type="Bit" Visualization="Text" Length="8" StartBit="0"/>
<text text="HardwareType" textID="410"/>
<defaults default="0" min="0" max="1"/>
<description description=""/>
</obj_5114h.01h>
<obj_5114h.02h DataType="Editable" name="Ðåæèì ðàáîòû" addr="sm_ctrl.run_mode" group="14" groupName="Íàñòðîéêè ÑÓ" fullgroup="28" callback="">
<obj_5114h.01h DataType="Editable" name="Ðåæèì ðàáîòû" addr="sm_ctrl.run_mode" group="14" groupName="Íàñòðîéêè ÑÓ" fullgroup="28" callback="">
<format Type="StandartNum" Size="16" Signed="false"/>
<text text="ÐåæÐàá" textID="411"/>
<defaults default="4" min="" max=""/>
<description description="Æåëàåìîå ñîñòîÿíèå ðàáîòû ïðèâîäà. 5 - äàò÷èêîâîå, 4 - èñòî÷íèê òîêà, 3 - ñêàëÿðíîå óïðàâëåíèå U(f), 2 - ðåæèì óæåðæàíèÿ ïîä òîêîì."/>
</obj_5114h.02h>
<obj_5114h.03h DataType="Editable" name="Ðåêóïåðàöèÿ" addr="sw.recuperation_ena" group="14" groupName="Íàñòðîéêè ÑÓ" fullgroup="28" callback="">
<format Type="StandartNum" Size="16" Signed="false"/>
</obj_5114h.01h>
<obj_5114h.02h DataType="Editable" name="Ðåêóïåðàöèÿ" addr="sw.all" group="14" groupName="Íàñòðîéêè ÑÓ" fullgroup="28" callback="">
<format Type="Bit" Visualization="Bin" Length="1" StartBit="0"/>
<text text="Ðåêóïð" textID="412"/>
<defaults default="0" min="" max=""/>
<description description="Ðàæðåøåíèå ãåíåðèðîâàíèÿ ýíåðãèè ïðè òîðìîæåíèè"/>
</obj_5114h.03h>
<obj_5114h.04h DataType="Editable" name="ÀÖÏ àâòî ñìåù." addr="sw.AutoOffset" group="14" groupName="Íàñòðîéêè ÑÓ" fullgroup="28" callback="">
<format Type="StandartNum" Size="16" Signed="false"/>
</obj_5114h.02h>
<obj_5114h.03h DataType="Editable" name="ÀÖÏ àâòî ñìåù." addr="sw.all" group="14" groupName="Íàñòðîéêè ÑÓ" fullgroup="28" callback="">
<format Type="Bit" Visualization="Bin" Length="1" StartBit="2"/>
<text text="ÀÖÏñìåù" textID="413"/>
<defaults default="1" min="" max=""/>
<description description="Ôëàã ðàçðåøåíèÿ ðàáîòû àâòîìàòè÷åñêîé óñòàíîâêè ñìåùåíèÿ äàò÷èêîâ íàïðÿæåíèÿ ñòàòîðà"/>
</obj_5114h.04h>
<obj_5114h.05h DataType="Editable" name="Ïåðåçàãðóçêà" addr="sw.Reboot" group="14" groupName="Íàñòðîéêè ÑÓ" fullgroup="28" callback="">
<format Type="StandartNum" Size="16" Signed="false"/>
</obj_5114h.03h>
<obj_5114h.04h DataType="Editable" name="Ïåðåçàãðóçêà" addr="sw.all" group="14" groupName="Íàñòðîéêè ÑÓ" fullgroup="28" callback="">
<format Type="Bit" Visualization="Bin" Length="1" StartBit="1"/>
<text text="Ïåðåçàãðóçêà" textID="414"/>
<defaults default="0" min="0" max="1"/>
<description description=""/>
</obj_5114h.04h>
<obj_5114h.05h DataType="Editable" name="Ðàçðåøèòü ñâåòîäèîä âìåñòî JTAG" addr="sw.all" group="14" groupName="Íàñòðîéêè ÑÓ" fullgroup="28" callback="">
<format Type="Bit" Visualization="Bin" Length="1" StartBit="3"/>
<text text="" textID="710"/>
<defaults default="0" min="0" max="1"/>
<description description=""/>
</obj_5114h.05h>
<obj_5114h.06h DataType="Editable" name="Âîçáóäèòåëü" addr="sw.excitation_ena" group="14" groupName="Íàñòðîéêè ÑÓ" fullgroup="28" callback="">
<format Type="StandartNum" Size="16" Signed="false"/>
<text text="Âîçá" textID="590"/>
<defaults default="0" min="" max=""/>
<description description="Ðàæðåøåíèå èñïîëüçîâàíèÿ âîçáóäèòåëÿ"/>
</obj_5114h.06h>
<obj_5116h.00h DataType="Viewable" name="ÀÖÏ" addr="" group="16" groupName="ÀÖÏ" fullgroup="16" callback="">
<format Type="Root"/>
<text text="ÀÖÏ" textID="415"/>
@ -3745,54 +3733,42 @@
<defaults default="0" min="" max=""/>
<description description=""/>
</obj_5116h.06h>
<obj_5116h.07h DataType="Editable" name="Êîýôôèöèåíò òîêà ôàçû C" addr="adc.Imeas_c_gain" group="16" groupName="ÀÖÏ" fullgroup="16" callback="">
<format Type="IQ" Size="16" Signed="true" QValue="0" ScaleNum="14"/>
<text text="IcÓñèë" textID="422"/>
<defaults default="40" min="" max=""/>
<description description=""/>
</obj_5116h.07h>
<obj_5116h.08h DataType="Editable" name="Ñìåùåíèå òîêà ôàçû C" addr="adc.Imeas_c_offset" group="16" groupName="ÀÖÏ" fullgroup="16" callback="">
<format Type="IQ" Size="16" Signed="true" QValue="0" ScaleNum="0"/>
<text text="IcÑìåù" textID="423"/>
<defaults default="62836" min="" max=""/>
<description description=""/>
</obj_5116h.08h>
<obj_5116h.09h DataType="Viewable" name="Òîê ôàçû Ñ" addr="adc.Imeas_c" group="16" groupName="ÀÖÏ" fullgroup="16" callback="">
<obj_5116h.07h DataType="Viewable" name="Òîê ôàçû Ñ" addr="adc.Imeas_c" group="16" groupName="ÀÖÏ" fullgroup="16" callback="">
<format Type="IQ" Size="32" Signed="true" QValue="24" ScaleNum="4"/>
<text text="Ic_ìãí" textID="424"/>
<defaults default="0" min="" max=""/>
<description description=""/>
</obj_5116h.09h>
<obj_5116h.0Ah DataType="Editable" name="Êîýôôèöèåíò íàïðÿæåíèÿ ÇÏÒ" addr="adc.Udc_meas_gain" group="16" groupName="ÀÖÏ" fullgroup="16" callback="">
</obj_5116h.07h>
<obj_5116h.08h DataType="Editable" name="Êîýôôèöèåíò íàïðÿæåíèÿ ÇÏÒ" addr="adc.Udc_meas_gain" group="16" groupName="ÀÖÏ" fullgroup="16" callback="">
<format Type="IQ" Size="16" Signed="true" QValue="0" ScaleNum="13"/>
<text text="UdÓñèë" textID="425"/>
<defaults default="2050" min="" max=""/>
<description description=""/>
</obj_5116h.0Ah>
<obj_5116h.0Bh DataType="Editable" name="Ñìåùåíèå íàïðÿæ. ÇÏÒ" addr="adc.Udc_meas_offset" group="16" groupName="ÀÖÏ" fullgroup="16" callback="">
</obj_5116h.08h>
<obj_5116h.09h DataType="Editable" name="Ñìåùåíèå íàïðÿæ. ÇÏÒ" addr="adc.Udc_meas_offset" group="16" groupName="ÀÖÏ" fullgroup="16" callback="">
<format Type="IQ" Size="16" Signed="true" QValue="0" ScaleNum="0"/>
<text text="Udñìåù" textID="426"/>
<defaults default="0" min="" max=""/>
<description description=""/>
</obj_5116h.0Bh>
<obj_5116h.0Ch DataType="Viewable" name="Íàïðÿæåíèå ÇÏÒ" addr="adc.Udc_meas" group="16" groupName="ÀÖÏ" fullgroup="16" callback="">
</obj_5116h.09h>
<obj_5116h.0Ah DataType="Viewable" name="Íàïðÿæåíèå ÇÏÒ" addr="adc.Udc_meas" group="16" groupName="ÀÖÏ" fullgroup="16" callback="">
<format Type="IQ" Size="32" Signed="true" QValue="24" ScaleNum="7"/>
<text text="Ud" textID="427"/>
<defaults default="0" min="" max=""/>
<description description=""/>
</obj_5116h.0Ch>
<obj_5116h.0Dh DataType="Editable" name="Êîýôôèöèåíò òåìïåðàòóðû" addr="adc.T_meas_gain" group="16" groupName="ÀÖÏ" fullgroup="" callback="">
<format Type="IQ" Size="16" Signed="true" QValue="0" ScaleNum="27"/>
<text text="t_gain" textID="633"/>
<defaults default="1500" min="" max=""/>
</obj_5116h.0Ah>
<obj_5116h.0Bh DataType="Editable" name="Äèàïàçîí àíàëîãîâîãî âõîäà" addr="adc.AI_meas_gain" group="16" groupName="ÀÖÏ" fullgroup="" callback="">
<format Type="IQ" Size="16" Signed="true" QValue="0" ScaleNum="0"/>
<text text="" textID="711"/>
<defaults default="15" min="" max=""/>
<description description=""/>
</obj_5116h.0Dh>
<obj_5116h.0Eh DataType="Viewable" name="Òåìïåðàòóðà" addr="adc.T_meas" group="16" groupName="ÀÖÏ" fullgroup="" callback="">
<format Type="IQ" Size="32" Signed="true" QValue="24" ScaleNum="10"/>
<text text="t" textID="634"/>
</obj_5116h.0Bh>
<obj_5116h.0Ch DataType="Viewable" name="Âíåøíèé àíàëîãîâûé âõîä 1" addr="adc.AI_meas" group="16" groupName="ÀÖÏ" fullgroup="" callback="">
<format Type="IQ" Size="32" Signed="true" QValue="24" ScaleNum="0"/>
<text text="ADC_ext1" textID="641"/>
<defaults default="0" min="" max=""/>
<description description=""/>
</obj_5116h.0Eh>
</obj_5116h.0Ch>
<obj_511Ah.00h DataType="Viewable" name="Ìîäóëü U/F" addr="" group="20" groupName="Êðèâàÿ U-f" fullgroup="18" callback="">
<format Type="Root"/>
<text text="Çàêîí U(f) (ÀÄ)" textID="428"/>
@ -4111,6 +4087,13 @@
<defaults default="0" min="" max=""/>
<description description="Óãîë ýëåêòð. ñ äàò÷èêà"/>
</obj_5152h.17h>
<obj_5152h.18h DataType="Editable" name="Ñ÷åò÷èê ñîáûòèé èíäåêñíîé ìåòêè" addr="posspeedEqep.Index_eventCounter" group="26" groupName="ÄÏÐ-Ýíêîäåð" fullgroup="" callback="">
<format Type="StandartNum" Size="16" Signed="false"/>
<text text="" textID="714"/>
<defaults default="0" min="" max=""/>
<description description="Ñ÷¸ò÷èê èíäåêñîâ
"/>
</obj_5152h.18h>
<obj_5155h.00h DataType="Viewable" name="Äàò÷èê Õîëëà" addr="" group="25" groupName="ÄÏÐ-Õîëë" fullgroup="20" callback="">
<format Type="Root"/>
<text text="Äàò÷èê Õîëëà" textID="475"/>
@ -4543,6 +4526,142 @@
<defaults default="16777216" min="" max=""/>
<description description="Èíäóêòèâíîñòü ôàçû ñòàòîðà"/>
</obj_5B04h.08h>
<obj_5B05h.00h DataType="Viewable" name="Ïëàâíûé çàðÿä ÇÏÒ" addr="" group="48" groupName="Ïëàâíûé çàðÿä ÇÏÒ" fullgroup="" callback="">
<format Type="Root"/>
<text text="smooth_charge" textID="626"/>
<defaults default="0" min="" max=""/>
<description description="Ïëàâíûé çàðÿä ÷åðåç òåðìèñòîð è ïîñëåäóþùåå çàêîðà÷èâàíèå öåïè ÷åðåç ðåëå"/>
</obj_5B05h.00h>
<obj_5B05h.01h DataType="Viewable" name="Òåêóùåå ñîñòîÿíèå ðåëå" addr="udControl.StateOn" group="48" groupName="Ïëàâíûé çàðÿä ÇÏÒ" fullgroup="" callback="">
<format Type="StandartNum" Size="8" Signed="false"/>
<text text="Relay_state" textID="631"/>
<defaults default="0" min="" max=""/>
<description description=""/>
</obj_5B05h.01h>
<obj_5B05h.02h DataType="Editable" name="Çàäåæêà âêëþ÷åíèÿ ðåëå, ìñ" addr="udControl.Timeout_on" group="48" groupName="Ïëàâíûé çàðÿä ÇÏÒ" fullgroup="" callback="">
<format Type="StandartNum" Size="16" Signed="false"/>
<text text="relay on-delay" textID="627"/>
<defaults default="2000" min="" max=""/>
<description description=""/>
</obj_5B05h.02h>
<obj_5B05h.03h DataType="Editable" name="Íàïðÿæåíèå âêëþ÷åíèÿ, Â" addr="udControl.U_on" group="48" groupName="Ïëàâíûé çàðÿä ÇÏÒ" fullgroup="" callback="">
<format Type="IQ" Size="32" Signed="false" QValue="24" ScaleNum="7"/>
<text text="on-voltage" textID="628"/>
<defaults default="15099494" min="" max=""/>
<description description=""/>
</obj_5B05h.03h>
<obj_5B05h.04h DataType="Editable" name="Íàïðÿæåíèå âûêëþ÷åíèÿ, Â" addr="udControl.U_off" group="48" groupName="Ïëàâíûé çàðÿä ÇÏÒ" fullgroup="" callback="">
<format Type="IQ" Size="32" Signed="false" QValue="24" ScaleNum="7"/>
<text text="off-voltage" textID="629"/>
<defaults default="11744051" min="" max=""/>
<description description=""/>
</obj_5B05h.04h>
<obj_5B05h.05h DataType="Viewable" name="Ïðîèçâîäíàÿ íàïðÿæåíèÿ ÇÏÒ" addr="udControl.deriv_time_ZPT" group="48" groupName="Ïëàâíûé çàðÿä ÇÏÒ" fullgroup="" callback="">
<format Type="IQ" Size="32" Signed="true" QValue="24" ScaleNum="15"/>
<text text="derivative_voltage" textID="630"/>
<defaults default="0" min="" max=""/>
<description description=""/>
</obj_5B05h.05h>
<obj_5B05h.06h DataType="Editable" name="Óñòàâêà ïî ïðîèçâîäíîé ÇÏÒ" addr="udControl.deriv_const" group="48" groupName="Ïëàâíûé çàðÿä ÇÏÒ" fullgroup="" callback="">
<format Type="IQ" Size="32" Signed="true" QValue="24" ScaleNum="15"/>
<text text="derivative_const" textID="632"/>
<defaults default="16777216" min="" max=""/>
<description description=""/>
</obj_5B05h.06h>
<obj_5B06h.00h DataType="Viewable" name="Äèñêðåòíûå âõîäû" addr="" group="4" groupName="Äèñêðåòíûå âõîäû è âûõîäû" fullgroup="" callback="">
<format Type="Root"/>
<text text="Âõîäû" textID="482"/>
<defaults default="0" min="" max=""/>
<description description=""/>
</obj_5B06h.00h>
<obj_5B06h.01h DataType="Viewable" name="Äèñêðåòíûå âõîäû" addr="input_vect" group="4" groupName="Äèñêðåòíûå âõîäû è âûõîäû" fullgroup="" callback="">
<format Type="Bit" Visualization="Bin" Length="8" StartBit="0"/>
<text text="Âõîäû" textID="482"/>
<defaults default="0" min="" max=""/>
<description description=""/>
</obj_5B06h.01h>
<obj_5B06h.02h DataType="Editable" name="Äèñêðåòíûå âûõîäû" addr="output_vect" group="4" groupName="Äèñêðåòíûå âõîäû è âûõîäû" fullgroup="" callback="">
<format Type="Bit" Visualization="Bin" Length="8" StartBit="0"/>
<text text="dout" textID="694"/>
<defaults default="0" min="" max=""/>
<description description=""/>
</obj_5B06h.02h>
<obj_5B07h.00h DataType="Viewable" name="Ñèñòåìà îõëàæäåíèÿ" addr="" group="47" groupName="Ñèñòåìà îõëàæäåíèÿ" fullgroup="" callback="">
<format Type="Root"/>
<text text="cool_syst" textID="635"/>
<defaults default="0" min="" max=""/>
<description description=""/>
</obj_5B07h.00h>
<obj_5B07h.01h DataType="Viewable" name="Òåêóùåå ñîñòîÿíèå âåíòèëÿòîðà" addr="fanControl.StateOn" group="47" groupName="Ñèñòåìà îõëàæäåíèÿ" fullgroup="" callback="">
<format Type="StandartNum" Size="16" Signed="false"/>
<text text="fan_state" textID="636"/>
<defaults default="0" min="" max=""/>
<description description="Ñîñòîÿíèå âåíòèëÿòîðà (âêëþ÷åí/âûêëþ÷åí)"/>
</obj_5B07h.01h>
<obj_5B07h.02h DataType="Editable" name="Òåìïåðàòóðà âêëþ÷åíèÿ âåíòèëÿòîðà" addr="fanControl.T_on" group="47" groupName="Ñèñòåìà îõëàæäåíèÿ" fullgroup="" callback="">
<format Type="IQ" Size="32" Signed="true" QValue="24" ScaleNum="10"/>
<text text="t_on" textID="637"/>
<defaults default="41943040" min="" max=""/>
<description description="Òåìïåðàòóðà âêëþ÷åíèÿ âåíòèëÿòîðà "/>
</obj_5B07h.02h>
<obj_5B07h.03h DataType="Editable" name="Òåìïåðàòóðà âûêëþ÷åíèÿ âåíòèëÿòîðà" addr="fanControl.T_off" group="47" groupName="Ñèñòåìà îõëàæäåíèÿ" fullgroup="" callback="">
<format Type="IQ" Size="32" Signed="true" QValue="24" ScaleNum="10"/>
<text text="t_off" textID="638"/>
<defaults default="25165824" min="" max=""/>
<description description="Òåìïåðàòóðà âûêëþ÷åíèÿ âåíòèëÿòîðà
"/>
</obj_5B07h.03h>
<obj_5B07h.04h DataType="Editable" name="Òåìïåðàòóðà âûâîäà ïðåäóïðåæäåíèÿ î ïåðåãðåâå" addr="fanControl.T_alarm" group="47" groupName="Ñèñòåìà îõëàæäåíèÿ" fullgroup="" callback="">
<format Type="IQ" Size="32" Signed="true" QValue="24" ScaleNum="10"/>
<text text="t_alarm" textID="640"/>
<defaults default="67108864" min="" max=""/>
<description description="Òåìïåðàòóðà âûêëþ÷åíèÿ âåíòèëÿòîðà
"/>
</obj_5B07h.04h>
<obj_5B07h.05h DataType="Viewable" name="Òåìïåðàòóðà" addr="fanControl.temperature" group="47" groupName="Ñèñòåìà îõëàæäåíèÿ" fullgroup="" callback="">
<format Type="IQ" Size="32" Signed="true" QValue="24" ScaleNum="10"/>
<text text="t" textID="634"/>
<defaults default="67108864" min="" max=""/>
<description description="Òåìïåðàòóðà âûêëþ÷åíèÿ âåíòèëÿòîðà
"/>
</obj_5B07h.05h>
<obj_5B07h.06h DataType="Editable" name="Âêëþ÷èòü ïðèíóäèòåëüíî" addr="fanControl.manualOn" group="47" groupName="Ñèñòåìà îõëàæäåíèÿ" fullgroup="" callback="">
<format Type="StandartNum" Size="16" Signed="false"/>
<text text="" textID="712"/>
<defaults default="0" min="" max=""/>
<description description="Òåìïåðàòóðà âûêëþ÷åíèÿ âåíòèëÿòîðà
"/>
</obj_5B07h.06h>
<obj_5B08h.00h DataType="Viewable" name="Òîðìîçíîé ðåçèñòîð" addr="" group="46" groupName="Òîðìîçíîé ðåçèñòîð" fullgroup="" callback="">
<format Type="Root"/>
<text text="" textID="713"/>
<defaults default="0" min="" max=""/>
<description description=""/>
</obj_5B08h.00h>
<obj_5B08h.01h DataType="Editable" name="Âêëþ÷åí" addr="brakeResistor.enabled" group="46" groupName="Òîðìîçíîé ðåçèñòîð" fullgroup="" callback="">
<format Type="StandartNum" Size="16" Signed="false"/>
<text text="Âêë" textID="589"/>
<defaults default="0" min="" max=""/>
<description description=""/>
</obj_5B08h.01h>
<obj_5B08h.02h DataType="Editable" name="Íàïðÿæåíèå âêëþ÷åíèÿ, Â" addr="brakeResistor.upperLevel" group="46" groupName="Òîðìîçíîé ðåçèñòîð" fullgroup="" callback="">
<format Type="IQ" Size="32" Signed="true" QValue="24" ScaleNum="7"/>
<text text="on-voltage" textID="628"/>
<defaults default="0" min="" max=""/>
<description description=""/>
</obj_5B08h.02h>
<obj_5B08h.03h DataType="Editable" name="Íàïðÿæåíèå âûêëþ÷åíèÿ, Â" addr="brakeResistor.bottomLevel" group="46" groupName="Òîðìîçíîé ðåçèñòîð" fullgroup="" callback="">
<format Type="IQ" Size="32" Signed="true" QValue="24" ScaleNum="7"/>
<text text="off-voltage" textID="629"/>
<defaults default="0" min="" max=""/>
<description description=""/>
</obj_5B08h.03h>
<obj_5B08h.04h DataType="Viewable" name="Ñîñòîÿíèå" addr="brakeResistor.state" group="46" groupName="Òîðìîçíîé ðåçèñòîð" fullgroup="" callback="">
<format Type="StandartNum" Size="16" Signed="false"/>
<text text="Ñîñòîÿíèå" textID="570"/>
<defaults default="0" min="" max=""/>
<description description=""/>
</obj_5B08h.04h>
</Indexes>
<SubProfiles/>
</root>

View File

@ -162,19 +162,41 @@ void FPUInit()
// Đŕçđĺřĺíčĺ ňŕęňčđîâŕíč˙ âńĺé ďĺđčôĺđčč
void PeripheralClockEnable(){
// Разрешение клоков
// Разрешение тактирования периферии
RCU->HCLKCFG = 0b00000111; // CAN, GPIOA, GPIOB
RCU->PCLKCFG = 0b0000111111111111; // PWM, CAP, QEP, I2C ňŕéěĺđű
RCU->UARTCFG[1].UARTCFG_bit.CLKEN = 1;//включили тактирование UART
RCU->UARTCFG[1].UARTCFG_bit.CLKSEL = 1;//PLL = 100МГц
RCU->UARTCFG[1].UARTCFG_bit.DIVEN = 1;//включить делитель
RCU->UARTCFG[1].UARTCFG_bit.DIVN = 1;//делим на 4 по формуле N = 2*(DIVN+1)
RCU->UARTCFG[1].UARTCFG_bit.RSTDIS = 1; //вывели из резета
// Настройка тактирования UART
//RCU->UARTCFG[1].UARTCFG_bit.CLKEN = 1; // включили тактирование UART
//RCU->UARTCFG[1].UARTCFG_bit.CLKSEL = 1; // Источник тактирования PLL = 100МГц
//RCU->UARTCFG[1].UARTCFG_bit.DIVEN = 1; // включить делитель
//RCU->UARTCFG[1].UARTCFG_bit.DIVN = 1; // делим на 4 по формуле N = 2*(DIVN+1), итого частота тактирования равна 25 МГц
//RCU->UARTCFG[1].UARTCFG_bit.RSTDIS = 1; // вывели из резета
RCU->UARTCFG[1].UARTCFG = (1 << RCU_UARTCFG_UARTCFG_CLKEN_Pos) |
(1 << RCU_UARTCFG_UARTCFG_CLKSEL_Pos) |
(1 << RCU_UARTCFG_UARTCFG_DIVEN_Pos) |
(1 << RCU_UARTCFG_UARTCFG_DIVN_Pos) |
(1 << RCU_UARTCFG_UARTCFG_RSTDIS_Pos);
// Настройка тактирования SPI
//RCU->SPICFG_bit.CLKEN = 1; // включили тактирование SPI
//RCU->SPICFG_bit.CLKSEL = 1; // Источник тактирования PLL = 100МГц
//RCU->SPICFG_bit.DIVEN = 1; // включить делитель
//RCU->SPICFG_bit.DIVN = 1; // делим на 4 по формуле N = 2*(DIVN+1), итого частота тактирования равна 25 МГц
//RCU->SPICFG_bit.RSTDIS = 1; //вывели из резета
RCU->SPICFG = (1 << RCU_SPICFG_CLKEN_Pos) |
(1 << RCU_SPICFG_CLKSEL_Pos) |
(1 << RCU_SPICFG_DIVEN_Pos) |
(1 << RCU_SPICFG_DIVN_Pos) |
(1 << RCU_SPICFG_RSTDIS_Pos);
// Ńí˙ňčĺ đĺńĺňŕ
RCU->HRSTCFG = 0b00000111; // CAN, GPIOA, GPIOB
RCU->PRSTCFG = 0b0000111111111111; // PWM, CAP, QEP, I2C ňŕéěĺđű
// Разрешение всех GPIO
GPIOA->DENSET = 0xFFFF;
GPIOB->DENSET = 0xFFFF;
}
void SystemInit(void)