From adf04373413280a0d1d244b5c5048b8b7b47ab7c Mon Sep 17 00:00:00 2001 From: Razvalyaev Date: Mon, 13 Jan 2025 13:05:34 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B0=D0=BB=D0=B3=D0=BE=D1=80=D0=B8=D1=82?= =?UTF-8?q?=D0=BC=20=D0=B2=D0=B5=D0=BA=D1=82=D0=BE=D1=80=D0=BD=D0=BE=D0=B3?= =?UTF-8?q?=D0=BE=20=D1=83=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=B2=D1=8B=D0=B7=D1=8B=D0=B2=D0=B0=D0=B5=D1=82=D1=81?= =?UTF-8?q?=D1=8F=20=D0=B8=20=D0=B4=D0=B0=D0=B6=D0=B5=20=D1=87=D1=82=D0=BE?= =?UTF-8?q?-=D1=82=D0=BE=20=D1=81=D1=87=D0=B8=D1=82=D0=B0=D0=B5=D1=82.=20?= =?UTF-8?q?=D1=82=D0=B5=D0=BF=D0=B5=D1=80=D1=8C=20=D0=BD=D0=B0=D0=B4=D0=BE?= =?UTF-8?q?=20=D0=B7=D0=B0=D0=B2=D0=B5=D1=81=D1=82=D0=B8=20=D0=B2=20=D0=BD?= =?UTF-8?q?=D0=B5=D0=B3=D0=BE=20=D1=83=D1=81=D1=82=D0=B0=D0=B2=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=B8=20=D0=B8=D0=B7=D0=BC=D0=B5=D1=80=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D1=81=20=D1=80=D0=BE=D1=82=D0=BE=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Inu/Src/main/v_rotor.c | 2196 ++++++++++++------------ Inu/Src/main_matlab/IQmathLib.h | 1 + Inu/Src/main_matlab/IQmathLib_matlab.c | 8 + Inu/Src/main_matlab/init28335.c | 67 + Inu/Src/main_matlab/init28335.h | 10 + Inu/Src/main_matlab/main_matlab.c | 7 + Inu/Src/main_matlab/main_matlab.h | 10 - Inu/controller.c | 195 +-- Inu/controller.h | 24 + Inu/init28335.c | 1621 ----------------- Inu/init28335.h | 24 - Inu/wrapper_inu.h | 2 +- controller.ilk | Bin 385240 -> 0 bytes inu_im_2wnd_3lvl.slx | Bin 80373 -> 80301 bytes run_mex.bat | 14 +- 15 files changed, 1271 insertions(+), 2908 deletions(-) create mode 100644 Inu/Src/main_matlab/init28335.c create mode 100644 Inu/Src/main_matlab/init28335.h delete mode 100644 Inu/init28335.c delete mode 100644 Inu/init28335.h delete mode 100644 controller.ilk diff --git a/Inu/Src/main/v_rotor.c b/Inu/Src/main/v_rotor.c index 1da2a2f..0fe887c 100644 --- a/Inu/Src/main/v_rotor.c +++ b/Inu/Src/main/v_rotor.c @@ -1,1095 +1,1101 @@ -#include "DSP281x_Examples.h" // DSP281x Examples Include File -#include "DSP281x_SWPrioritizedIsrLevels.h" // DSP281x Examples Include File -#include "DSP281x_Device.h" // DSP281x Headerfile Include File -#include "IQmathLib.h" - -#include -#include - -#include "filter_v1.h" -#include "xp_cds_in.h" -#include "xp_inc_sensor.h" -#include "xp_project.h" -#include "params.h" -#include "pwm_test_lines.h" -#include "params_norma.h" -#include "mathlib.h" #include "params_alg.h" - - -#pragma DATA_SECTION(WRotor,".fast_vars"); -WRotorValues WRotor = WRotorValues_DEFAULTS; - -#if (SENSOR_ALG==SENSOR_ALG_23550) - -#pragma DATA_SECTION(WRotorPBus,".slow_vars"); -WRotorValuesAngle WRotorPBus = WRotorValuesAngle_DEFAULTS; - -#pragma DATA_SECTION(rotor_error_update_count,".fast_vars"); -unsigned int rotor_error_update_count = 0; - - -#define SIZE_BUF_SENSOR_LOGS 32 -#pragma DATA_SECTION(sensor_1_zero,".slow_vars"); -unsigned int sensor_1_zero[6+4+8][SIZE_BUF_SENSOR_LOGS], count_sensor_1_zero=0; - -#endif - -_iq koefW = _IQ(0.05); //0.05 -_iq koefW2 = _IQ(0.01); //0.05 -_iq koefW3 = _IQ(0.002); //0.05 - - - - - - - -#if (SENSOR_ALG==SENSOR_ALG_23550) -/////////////////////////////////////////////////////////////// -void rotorInit(void) -{ - WRotorPBus.ModeAutoDiscret = 1; -} - - - -/////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////// -#define MAX_COUNT_OVERFULL_DISCRET 2250 -#define MAX_DIRECTION 4000 -#define MAX_DIRECTION_2 2000 -/////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////// -void RotorDirectionFilter(int RotorDirectionIn, int *RotorDirectionOut, int *RotorDirectionOut2, int *count_direction) -{ - -// static int count_direction = 0; -// static int count_direction_minus = 0; - - - if (RotorDirectionIn==0) - { - if (*count_direction>0) (*count_direction)--; - if (*count_direction<0) (*count_direction)++; -// if (count_direction_minus>0) count_direction_minus--; - } - else - if (RotorDirectionIn>0) - { - if (*count_direction0) count_direction_minus--; - } - else - { - if (*count_direction>-MAX_DIRECTION) (*count_direction)--; -// if (count_direction_plus>0) count_direction_plus--; - } - - - if (RotorDirectionIn==0) - *RotorDirectionOut = 0; - else - if (RotorDirectionIn>0) - *RotorDirectionOut = 1; - else - *RotorDirectionOut = -1; - - - if (*count_direction>MAX_DIRECTION_2) - *RotorDirectionOut2 = 1; - else - if (*count_direction<-MAX_DIRECTION_2) - *RotorDirectionOut2 = -1; - else - *RotorDirectionOut2 = 0; - - - -} -/////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////// -#define LEVEL_VALUE_SENSOR_OVERFULL 65535 -#define MAX_COUNT_ERROR_ANALISATOR_SENSOR_PBUS 4000 -/////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////// - -#pragma CODE_SECTION(AnalisatorRotorSensorPBus,".fast_run"); -int AnalisatorRotorSensorPBus(_iq d1, _iq d2, unsigned int *count_overfull_discret, unsigned int *count_zero_discret, _iq *prev_iqTimeRotor, - unsigned int *discret_out, unsigned int discret_in, _iq *iqWRotorCalcBeforeRegul, _iq *iqWRotorCalc, - int modeS1, int modeS2, - int valid_sensor_direct, int valid_sensor_90, - unsigned int *error_count ) -{ - int flag_not_ready_rotor, flag_overfull_rotor; - _iq iqTimeRotor; - // discret0 = 2 mks -// static long long KoefNorm_discret0 = 409600000LL;//((500 000/1024/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 - static long long KoefNorm_discret0 = 102400000LL;//((500 000/4096/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 - // discret1 = 20 ns -// static long long KoefNorm_discret1 = 40960000000LL;//((50 000 000/1024/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 - static long long KoefNorm_discret1 = 10240000000LL;//((50 000 000/4096/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 - -// _iq iqWRotorSumm;//,iqWRotorCalc; - - static _iq time_level_discret_1to0 = 60000 ;//682666; // KoefNorm_discret1/60000 = 0.813801288604736328125 Ãö. - static _iq time_level_discret_0to1 = 400;//204800; // KoefNorm_discret0/2000 = 0.244140625 Ãö. - static unsigned int discret; - - - if (valid_sensor_direct == 0) - d1 = 0; - if (valid_sensor_90 == 0) - d2 = 0; - - -// òóò ÷òî-òî ïîøëî íå òàê, áûëà ñìåíà äèñêðåòèçàöèè ïî îáîèì êàíàëàì. - if (valid_sensor_direct == 0 && valid_sensor_90 == 0) - { - if (*error_count>1; - - - -// max OVERFULL - if (flag_overfull_rotor) - { - if (*count_overfull_discret0) - (*count_overfull_discret)--; - } - -// zero? - if (flag_not_ready_rotor) - { - if (*count_zero_discret0) - (*count_zero_discret)--; - } - -// real zero? - if (*count_zero_discret==MAX_COUNT_OVERFULL_DISCRET) - { - // íîëü áûë ñëèøêîì äîëãî, çíà÷èò òî÷íî íîëü! - iqWRotorCalc = 0; - *prev_iqTimeRotor = 0; - iqTimeRotor = 0; - } - else - { - // íîëü åùå íå ñëèøêîì äîëãî, çíà÷èò áåðåì ñòàðîå çíà÷åíèå prev_iqTimeRotor - if (iqTimeRotor==0) - iqTimeRotor = *prev_iqTimeRotor; - } - *prev_iqTimeRotor = iqTimeRotor; - - - -// âûáîð íóæíîãî äèàïàçîíà - if (WRotorPBus.ModeAutoDiscret==1) - { - if ( (*count_overfull_discret==MAX_COUNT_OVERFULL_DISCRET) || (iqTimeRotor==0) ) - { - // òóò èëè ïåðåïîëíåíèå ïðîèçîøëî èëè âäðóã îñòàíîâèëèñü, îáîðîòû=0 - // òîãäà âêëþ÷àåì discret_out = 0 - if (discret_in == 1) // èëè òóò íàäî èñïëüçîâàòü discret? - { - // discret áûë =1, ïåðåêëþ÷àåì íà 0. - *discret_out = 0; - *count_overfull_discret = 0; // äàëè åùå îäèí øàíñ! - } - - } - else - { - // òåêóù. óðîâåíü discret==0 òîãäà... - if (discret==0 && iqTimeRotortime_level_discret_1to0 && iqTimeRotor!=65535) - *discret_out = 0; - } - } - - if (WRotorPBus.ModeAutoDiscret==2) - { - *discret_out = 0; - } - - if (WRotorPBus.ModeAutoDiscret==3) - { - *discret_out = 1; - } - - if ( (*count_overfull_discret==MAX_COUNT_OVERFULL_DISCRET) ) - { - // òóò óæå òî÷íî â 0, ò.ê. ñëèøêîì ìåäëåííî èäóò èìïóëüñû! - *prev_iqTimeRotor = iqTimeRotor = 0; - } - - - - - if ((iqTimeRotor != 0)) // && (WRotorPBus.iqTimeRotor<65535) - { - if (discret==0) - *iqWRotorCalcBeforeRegul = KoefNorm_discret0 / iqTimeRotor; - if (discret==1) - *iqWRotorCalcBeforeRegul = KoefNorm_discret1 / iqTimeRotor; - - *iqWRotorCalc = exp_regul_iq(koefW, *iqWRotorCalc, *iqWRotorCalcBeforeRegul); - } - else - { - *iqWRotorCalc = 0; - *iqWRotorCalcBeforeRegul = 0; - } - - -// if (*iqWRotorCalc == 0) -// *RotorDirection = 0; - - - return 0; - -} -/////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////// - - -#pragma CODE_SECTION(RotorMeasurePBus,".fast_run"); -void RotorMeasurePBus(void) -{ - // discret0 = 2 mks -// static long long KoefNorm_discret0 = 409600000LL;//((500 000/1024/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 - static long long KoefNorm_discret0 = 102400000LL;//((500 000/4096/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 - // discret1 = 20 ns -// static long long KoefNorm_discret1 = 40960000000LL;//((50 000 000/1024/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 - static long long KoefNorm_discret1 = 10240000000LL;//((50 000 000/4096/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 - - static _iq time_level_discret_1to0 = 60000 ;//682666; // KoefNorm_discret1/60000 = 0.813801288604736328125 Ãö. - static _iq time_level_discret_0to1 = 400;//204800; // KoefNorm_discret0/2000 = 0.244140625 Ãö. - - static long long KoefNorm_angle = 16384LL; //2^24/1024 -// volatile float MyVar0 = 0; - - unsigned int MyVar3 = 0; -// int direction1 = 0, direction2 = 0; - volatile unsigned int discret; - - static unsigned int discret_out1, discret_out2; - - static int count_full_oborots = 0; - static unsigned int count_overfull_discret1 = 0; - static unsigned int count_zero_discret1 = 0; - static unsigned int count_overfull_discret2 = 0; - static unsigned int count_zero_discret2 = 0; - - static unsigned int count_discret_to_1 = 0; - static unsigned int count_discret_to_0 = 0; - - static unsigned int c_error_pbus_1 = 0; - static unsigned int c_error_pbus_2 = 0; - - - static _iq prev_iqTimeRotor1 = 0, prev_iqTimeRotor2 = 0; - - _iq iqWRotorSumm = 0; - - int flag_not_ready_rotor1, flag_overfull_rotor1; - int flag_not_ready_rotor2, flag_overfull_rotor2; - - //i_led1_on_off(1); - - - - flag_not_ready_rotor1 = 0; - flag_overfull_rotor1 = 0; - flag_not_ready_rotor2 = 0; - flag_overfull_rotor2 = 0; - - - - discret = project.cds_in[0].read.sbus.enabled_channels.bit.discret; - if (project.cds_in[0].read.sbus.enabled_channels.bit.discret != project.cds_in[0].write.sbus.enabled_channels.bit.discret) - discret = 2; - - if (project.cds_in[0].type_cds_xilinx == TYPE_CDS_XILINX_SP6) - { - sensor_1_zero[0][count_sensor_1_zero] = project.cds_in[0].read.pbus.Time_since_zero_point_S1; - sensor_1_zero[1][count_sensor_1_zero] = project.cds_in[0].read.pbus.Impulses_since_zero_point_Rising_S1; - sensor_1_zero[2][count_sensor_1_zero] = project.cds_in[0].read.pbus.Impulses_since_zero_point_Falling_S1; - sensor_1_zero[3][count_sensor_1_zero] = project.cds_in[0].read.pbus.Time_since_zero_point_S2; - sensor_1_zero[4][count_sensor_1_zero] = project.cds_in[0].read.pbus.Impulses_since_zero_point_Rising_S2; - sensor_1_zero[5][count_sensor_1_zero] = project.cds_in[0].read.pbus.Impulses_since_zero_point_Falling_S2; - } - sensor_1_zero[6][count_sensor_1_zero] = project.cds_in[0].read.pbus.SpeedS1_cnt; - sensor_1_zero[7][count_sensor_1_zero] = project.cds_in[0].read.pbus.SpeedS1_cnt90; - sensor_1_zero[8][count_sensor_1_zero] = project.cds_in[0].read.pbus.SpeedS2_cnt; - sensor_1_zero[9][count_sensor_1_zero] = project.cds_in[0].read.pbus.SpeedS2_cnt90; - - sensor_1_zero[10][count_sensor_1_zero] = inc_sensor.data.Time1; - sensor_1_zero[11][count_sensor_1_zero] = inc_sensor.data.Impulses1; - sensor_1_zero[12][count_sensor_1_zero] = inc_sensor.data.CountZero1; - sensor_1_zero[13][count_sensor_1_zero] = inc_sensor.data.CountOne1; - - sensor_1_zero[14][count_sensor_1_zero] = inc_sensor.data.Time2; - sensor_1_zero[15][count_sensor_1_zero] = inc_sensor.data.Impulses2; - sensor_1_zero[16][count_sensor_1_zero] = inc_sensor.data.CountZero2; - sensor_1_zero[17][count_sensor_1_zero] = inc_sensor.data.CountOne2; - - count_sensor_1_zero++; - if (count_sensor_1_zero>=SIZE_BUF_SENSOR_LOGS) - { - count_sensor_1_zero = 0; - count_full_oborots++; - if (count_full_oborots>3) - count_full_oborots = 0; - } -/* - if (count_sensor_1_zero==904) - { - discret = 3; - } -*/ - -#if (ENABLE_ROTOR_SENSOR_ZERO_SIGNAL==1) - if (project.cds_in[0].type_cds_xilinx == TYPE_CDS_XILINX_SP6) - { - -#if (ENABLE_ROTOR_SENSOR_1_PBUS==1) - WRotorPBus.iqWRotorRawAngle1F = project.cds_in[0].read.pbus.Impulses_since_zero_point_Falling_S1-32768; - WRotorPBus.iqWRotorRawAngle1R = project.cds_in[0].read.pbus.Impulses_since_zero_point_Rising_S1-32768; - WRotorPBus.iqAngle1F = KoefNorm_angle * WRotorPBus.iqWRotorRawAngle1F; - WRotorPBus.iqAngle1R = KoefNorm_angle * WRotorPBus.iqWRotorRawAngle1R; -#else - WRotorPBus.iqWRotorRawAngle1F = 0; - WRotorPBus.iqWRotorRawAngle1R = 0; - WRotorPBus.iqAngle1F = 0; - WRotorPBus.iqAngle1R = 0; -#endif - -#if (ENABLE_ROTOR_SENSOR_2_PBUS==1) - WRotorPBus.iqWRotorRawAngle2F = project.cds_in[0].read.pbus.Impulses_since_zero_point_Falling_S2-32768; - WRotorPBus.iqWRotorRawAngle2R = project.cds_in[0].read.pbus.Impulses_since_zero_point_Rising_S2-32768; - WRotorPBus.iqAngle2F = KoefNorm_angle * WRotorPBus.iqWRotorRawAngle2F; - WRotorPBus.iqAngle2R = KoefNorm_angle * WRotorPBus.iqWRotorRawAngle2R; -#else - WRotorPBus.iqWRotorRawAngle2F = 0; - WRotorPBus.iqWRotorRawAngle2R = 0; - WRotorPBus.iqAngle2F = 0; - WRotorPBus.iqAngle2R = 0; -#endif - } - else - { - WRotorPBus.iqWRotorRawAngle1F = 0; - WRotorPBus.iqWRotorRawAngle1R = 0; - WRotorPBus.iqAngle1F = 0; - WRotorPBus.iqAngle1R = 0; - - WRotorPBus.iqWRotorRawAngle2F = 0; - WRotorPBus.iqWRotorRawAngle2R = 0; - WRotorPBus.iqAngle2F = 0; - WRotorPBus.iqAngle2R = 0; - - } -#endif - - -#if (ENABLE_ROTOR_SENSOR_1_PBUS==1) - //************************************************************************************************** - MyVar3 = project.cds_in[0].read.pbus.SpeedS1_cnt; - - if ((MyVar3 <= COUNT_DECODER_ZERO_WROTORPBus) - && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) - { - WRotorPBus.iqWRotorRaw0 = MyVar3; - } - else - { - WRotorPBus.iqWRotorRaw0 = 0; - } - - MyVar3 = project.cds_in[0].read.pbus.SpeedS1_cnt90; - - if ((MyVar3 <= COUNT_DECODER_ZERO_WROTORPBus) - && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) - { - WRotorPBus.iqWRotorRaw1 = MyVar3; - } - else - { - WRotorPBus.iqWRotorRaw1 = 0; - } -#else - WRotorPBus.iqWRotorRaw0 = 0; - WRotorPBus.iqWRotorRaw1 = 0; -#endif - - -#if (ENABLE_ROTOR_SENSOR_2_PBUS==1) - //*************************************************************************************************** - MyVar3 = project.cds_in[0].read.pbus.SpeedS2_cnt; - - if ((MyVar3 <= COUNT_DECODER_ZERO_WROTORPBus) - && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) - { - WRotorPBus.iqWRotorRaw2 = MyVar3; - } - else - { - WRotorPBus.iqWRotorRaw2 = 0; - } - - MyVar3 = project.cds_in[0].read.pbus.SpeedS2_cnt90; - - if ((MyVar3 <= COUNT_DECODER_ZERO_WROTORPBus) - && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) - { - WRotorPBus.iqWRotorRaw3 = MyVar3; - } - else - { - WRotorPBus.iqWRotorRaw3 = 0; - } -#else - WRotorPBus.iqWRotorRaw2 = 0; - WRotorPBus.iqWRotorRaw3 = 0; -#endif - - -#if (ENABLE_ROTOR_SENSOR_1_PBUS==1) -// if (project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor1_direct && project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor1_90 ) - AnalisatorRotorSensorPBus(WRotorPBus.iqWRotorRaw0, WRotorPBus.iqWRotorRaw1, &count_overfull_discret1, &count_zero_discret1, - &prev_iqTimeRotor1, &discret_out1, project.cds_in[0].read.sbus.enabled_channels.bit.discret, - &WRotorPBus.iqWRotorCalcBeforeRegul1, &WRotorPBus.iqWRotorCalc1, - project.cds_in[0].read.pbus.direction_in.bit.mode_sensor1_direct, project.cds_in[0].read.pbus.direction_in.bit.mode_sensor1_90, - project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor1_direct, project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor1_90, - &c_error_pbus_1 ); -#endif - -#if (ENABLE_ROTOR_SENSOR_2_PBUS==1) -// if (project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor2_direct && project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor2_90 ) - AnalisatorRotorSensorPBus(WRotorPBus.iqWRotorRaw2, WRotorPBus.iqWRotorRaw3, &count_overfull_discret2, &count_zero_discret2, - &prev_iqTimeRotor2, &discret_out2, project.cds_in[0].read.sbus.enabled_channels.bit.discret, - &WRotorPBus.iqWRotorCalcBeforeRegul2, &WRotorPBus.iqWRotorCalc2, - project.cds_in[0].read.pbus.direction_in.bit.mode_sensor2_direct, project.cds_in[0].read.pbus.direction_in.bit.mode_sensor2_90, - project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor2_direct, project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor2_90, - &c_error_pbus_2); -#endif - - - // RotorDirectionFilter(WRotorPBus.RotorDirectionInstant, &WRotorPBus.RotorDirectionSlow); - - - - if (discret_out1==1 || discret_out2==1) - { - project.cds_in[0].write.sbus.enabled_channels.bit.discret = 1; - count_discret_to_1++; - } - else - { - project.cds_in[0].write.sbus.enabled_channels.bit.discret = 0; - count_discret_to_0++; - } - - -} - - - -#define MAX_COUNT_OVERFULL_DISCRET_2 150 -#pragma CODE_SECTION(RotorMeasure,".fast_run"); -void RotorMeasure(void) -{ - - // 600 Khz clock on every edge -// static long long KoefNorm = 53635601LL;//((600 000/6256/NORMA_WROTOR/2) * ((long)2 << 24)); //15 - NormaWRotor 782*8 = 6256 -// static long long KoefNormMS = 491520000LL;//((600 000/1024/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 -// static long long KoefNormNS = 49152000000LL;//((60 000 000/1024/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 - static long long KoefNormMS = 122880000LL;//((600 000/4096/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 - static long long KoefNormNS = 12288000000LL;//((60 000 000/4096/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 - static long long KoefNormImpulses = 838860800000000LL;// (2^24 * 1000000000 / (Impulses(ns)) / NORMA_WROTOR - - static _iq max_value_rotor = _IQ(500.0/60.0/NORMA_FROTOR); - static _iq wrotor_add_ramp = _IQ(0.001/NORMA_FROTOR); - -// volatile float MyVar0 = 0; -// volatile unsigned int MyVar1 = 0; -// volatile unsigned int MyVar2 = 0; - unsigned int MyVar3; - - - inc_sensor.read_sensors(&inc_sensor); - - // flag_not_ready_rotor = 0; - -//************************************************************************************************** -// sensor 1 - - if (inc_sensor.use_sensor1) - { - MyVar3 = inc_sensor.data.CountOne1; -// MyVar3 = (unsigned long) rotation_sensor.in_plane.out.CountOne1; - - if ((MyVar3 < COUNT_DECODER_ZERO_WROTOR) - && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) - { - -#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) - PWM_LINES_TK_21_ON; -#endif - - WRotor.iqWRotorRaw0 = MyVar3; - } - else - { - -#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) - PWM_LINES_TK_21_OFF; -#endif - - WRotor.iqWRotorRaw0 = 0; - } - MyVar3 = inc_sensor.data.CountZero1; - - if ((MyVar3 < COUNT_DECODER_ZERO_WROTOR) - && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) - { -#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) - PWM_LINES_TK_22_ON; -#endif - WRotor.iqWRotorRaw1 = MyVar3; - } - else - { -#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) - PWM_LINES_TK_22_OFF; -#endif - WRotor.iqWRotorRaw1 = 0; - } - } - else - { - WRotor.iqWRotorRaw0 = 0; - WRotor.iqWRotorRaw1 = 0; - } - //logpar.uns_log0 = (Uint16)(my_var1); - //logpar.uns_log1 = (Uint16)(my_var2); - - // sensor 2 - if (inc_sensor.use_sensor2) - { - MyVar3 = inc_sensor.data.CountOne2; - - if ((MyVar3 < COUNT_DECODER_ZERO_WROTOR) - && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) - { -#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) - PWM_LINES_TK_18_ON; -#endif - WRotor.iqWRotorRaw2 = MyVar3; - } - else - { -#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) - PWM_LINES_TK_18_OFF; -#endif - WRotor.iqWRotorRaw2 = 0; - } - - MyVar3 = inc_sensor.data.CountZero2; - - if ((MyVar3 < COUNT_DECODER_ZERO_WROTOR) - && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) - { -#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) - PWM_LINES_TK_23_ON; -#endif - WRotor.iqWRotorRaw3 = MyVar3; - } - else - { -#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) - PWM_LINES_TK_23_OFF; -#endif - WRotor.iqWRotorRaw3 = 0; - } - } - else - { - WRotor.iqWRotorRaw2 = 0; - WRotor.iqWRotorRaw3 = 0; - } - -// if (WRotor.iqWRotorRaw0==0 && WRotor.iqWRotorRaw1==0 && WRotor.iqWRotorRaw2==0 && WRotor.iqWRotorRaw3==0) -// flag_not_ready_rotor = 1; - - if (WRotor.iqWRotorRaw0==0) - { - if (WRotor.count_zero_discret0==MAX_COUNT_OVERFULL_DISCRET_2) - { - WRotor.prev_iqWRotorRaw0 = WRotor.iqWRotorRaw0 = 0; - } - else - { - WRotor.iqWRotorRaw0 = WRotor.prev_iqWRotorRaw0; - WRotor.count_zero_discret0++; - } - } - else - { - WRotor.count_zero_discret0 = 0; - WRotor.prev_iqWRotorRaw0 = WRotor.iqWRotorRaw0; - } - - if (WRotor.iqWRotorRaw1==0) - { - if (WRotor.count_zero_discret1==MAX_COUNT_OVERFULL_DISCRET_2) - { - WRotor.prev_iqWRotorRaw1 = WRotor.iqWRotorRaw1 = 0; - } - else - { - WRotor.iqWRotorRaw1 = WRotor.prev_iqWRotorRaw1; - WRotor.count_zero_discret1++; - } - } - else - { - WRotor.count_zero_discret1 = 0; - WRotor.prev_iqWRotorRaw1 = WRotor.iqWRotorRaw1; - } - - if (WRotor.iqWRotorRaw2==0) - { - if (WRotor.count_zero_discret2==MAX_COUNT_OVERFULL_DISCRET_2) - { - WRotor.prev_iqWRotorRaw2 = WRotor.iqWRotorRaw2 = 0; - } - else - { - WRotor.iqWRotorRaw2 = WRotor.prev_iqWRotorRaw2; - WRotor.count_zero_discret2++; - } - } - else - { - WRotor.count_zero_discret2 = 0; - WRotor.prev_iqWRotorRaw2 = WRotor.iqWRotorRaw2; - } - - if (WRotor.iqWRotorRaw3==0) - { - if (WRotor.count_zero_discret3==MAX_COUNT_OVERFULL_DISCRET_2) - { - WRotor.prev_iqWRotorRaw3 = WRotor.iqWRotorRaw3 = 0; - } - else - { - WRotor.iqWRotorRaw3 = WRotor.prev_iqWRotorRaw3; - WRotor.count_zero_discret3++; - } - } - else - { - WRotor.count_zero_discret3 = 0; - WRotor.prev_iqWRotorRaw3 = WRotor.iqWRotorRaw3; - } - - - WRotor.iqTimeSensor1 = WRotor.iqWRotorRaw0 + WRotor.iqWRotorRaw1; - WRotor.iqTimeSensor2 = WRotor.iqWRotorRaw2 + WRotor.iqWRotorRaw3; - - // -// // zero? -// if (flag_not_ready_rotor) -// { -// if (*count_zero_discret0) -// (*count_zero_discret)--; -// } -// -// // real zero? -// if (count_zero_discret==MAX_COUNT_OVERFULL_DISCRET) -// { -// // íîëü áûë ñëèøêîì äîëãî, çíà÷èò òî÷íî íîëü! -// WRotor.iqTimeSensor1 = 0; -// WRotor.prev_iqTimeSensor1 = 0; -// } -// else -// { -// // íîëü åùå íå ñëèøêîì äîëãî, çíà÷èò áåðåì ñòàðîå çíà÷åíèå prev_iqTimeRotor -// if (WRotor.iqTimeSensor1==0) -// WRotor.iqTimeSensor1 = WRotor.prev_iqTimeSensor1; -// } -// WRotor.prev_iqTimeSensor1 = WRotor.iqTimeSensor1; -// -// -// // max OVERFULL -// if (flag_overfull_rotor) -// { -// if (*count_overfull_discret0) -// (*count_overfull_discret)--; -// } -// -// // zero? -// if (flag_not_ready_rotor) -// { -// if (*count_zero_discret0) -// (*count_zero_discret)--; -// } -// -// // real zero? -// if (*count_zero_discret==MAX_COUNT_OVERFULL_DISCRET) -// { -// // íîëü áûë ñëèøêîì äîëãî, çíà÷èò òî÷íî íîëü! -// iqWRotorCalc = 0; -// *prev_iqTimeRotor = 0; -// iqTimeRotor = 0; -// } -// else -// { -// // íîëü åùå íå ñëèøêîì äîëãî, çíà÷èò áåðåì ñòàðîå çíà÷åíèå prev_iqTimeRotor -// if (iqTimeRotor==0) -// iqTimeRotor = *prev_iqTimeRotor; -// } -// *prev_iqTimeRotor = iqTimeRotor; -// -// -// - -/// - if (WRotor.iqTimeSensor1 != 0 && inc_sensor.use_sensor1) - { - if (inc_sensor.pm67regs.read_comand_reg.bit.sampling_time1==0) - WRotor.iqWRotorCalcBeforeRegul1 = KoefNormMS / WRotor.iqTimeSensor1; - if (inc_sensor.pm67regs.read_comand_reg.bit.sampling_time1==1) - WRotor.iqWRotorCalcBeforeRegul1 = KoefNormNS / WRotor.iqTimeSensor1; - - if (WRotor.iqWRotorCalcBeforeRegul1 > max_value_rotor) - { - WRotor.iqWRotorCalc1 = 0; - WRotor.iqWRotorCalcBeforeRegul1 = 0; - } - else - WRotor.iqWRotorCalc1 = exp_regul_iq(koefW, WRotor.iqWRotorCalc1, WRotor.iqWRotorCalcBeforeRegul1); - - ///// - if (WRotor.iqWRotorCalc1) - { - if (WRotor.iqPrevWRotorCalc1 != WRotor.iqWRotorCalc1) - { - WRotor.iqWRotorCalc1Ramp = zad_intensiv_q(wrotor_add_ramp, wrotor_add_ramp, WRotor.iqWRotorCalc1Ramp, WRotor.iqWRotorCalc1); - WRotor.iqPrevWRotorCalc1 = WRotor.iqWRotorCalc1; - } - } - else - { - WRotor.iqPrevWRotorCalc1 = 0; - WRotor.iqWRotorCalc1Ramp = 0; - } - //// - } - else - { - WRotor.iqWRotorCalc1 = 0; - WRotor.iqWRotorCalcBeforeRegul1 = 0; - } -/// - if (WRotor.iqTimeSensor2 != 0 && inc_sensor.use_sensor2) - { - if (inc_sensor.pm67regs.read_comand_reg.bit.sampling_time2==0) - WRotor.iqWRotorCalcBeforeRegul2 = KoefNormMS / WRotor.iqTimeSensor2; - if (inc_sensor.pm67regs.read_comand_reg.bit.sampling_time2==1) - WRotor.iqWRotorCalcBeforeRegul2 = KoefNormNS / WRotor.iqTimeSensor2; - - if (WRotor.iqWRotorCalcBeforeRegul2 > max_value_rotor) - { - WRotor.iqWRotorCalc2 = 0; - WRotor.iqWRotorCalcBeforeRegul2 = 0; - } - else - WRotor.iqWRotorCalc2 = exp_regul_iq(koefW, WRotor.iqWRotorCalc2, WRotor.iqWRotorCalcBeforeRegul2); - - - - ///// - if (WRotor.iqWRotorCalc2) - { - if (WRotor.iqPrevWRotorCalc2 != WRotor.iqWRotorCalc2) - { - WRotor.iqWRotorCalc2Ramp = zad_intensiv_q(wrotor_add_ramp, wrotor_add_ramp, WRotor.iqWRotorCalc2Ramp, WRotor.iqWRotorCalc2); - WRotor.iqPrevWRotorCalc2 = WRotor.iqWRotorCalc2; - } - } - else - { - WRotor.iqPrevWRotorCalc2 = 0; - WRotor.iqWRotorCalc2Ramp = 0; - } - //// - } - else - { - WRotor.iqWRotorCalc2 = 0; - WRotor.iqWRotorCalcBeforeRegul2 = 0; - } -/// - if (inc_sensor.data.TimeCalcFromImpulses1 && inc_sensor.use_sensor1) - WRotor.iqWRotorImpulsesBeforeRegul1 = (long long) KoefNormImpulses / (inc_sensor.data.TimeCalcFromImpulses1 * ROTOR_SENSOR_IMPULSES_PER_ROTATE); - else - WRotor.iqWRotorImpulsesBeforeRegul1 = 0; - - WRotor.iqWRotorImpulses1 = exp_regul_iq(koefW, WRotor.iqWRotorImpulses1, WRotor.iqWRotorImpulsesBeforeRegul1); - - if (inc_sensor.data.TimeCalcFromImpulses2 && inc_sensor.use_sensor2) - WRotor.iqWRotorImpulsesBeforeRegul2 = (long long) KoefNormImpulses / (inc_sensor.data.TimeCalcFromImpulses2 * ROTOR_SENSOR_IMPULSES_PER_ROTATE); - else - WRotor.iqWRotorImpulsesBeforeRegul2 = 0; - - WRotor.iqWRotorImpulses2 = exp_regul_iq(koefW, WRotor.iqWRotorImpulses2, WRotor.iqWRotorImpulsesBeforeRegul2); - - - // WRotor.iqWRotorCalcBeforeRegul = _IQdiv(WRotor.iqWRotorCalcBeforeRegul,IQ_CONST_3); -} -#define LEVEL_SWITCH_TO_GET_IMPULSES_OBOROTS 50 // Oborot -void select_values_wrotor(void) -{ - static _iq level_switch_to_get_impulses_hz = _IQ(LEVEL_SWITCH_TO_GET_IMPULSES_OBOROTS/60.0/NORMA_FROTOR); - static unsigned int prev_RotorDirectionInstant = 0; - static unsigned int status_RotorRotation = 0; // åñòü âðàùåíèå? - static _iq wrotor_add = _IQ(0.002/NORMA_FROTOR); - - - - - if (WRotor.iqWRotorCalc1>level_switch_to_get_impulses_hz - || WRotor.iqWRotorCalc2>level_switch_to_get_impulses_hz) - { - // óæå áîëüøèå îáîðîòû - if (WRotor.iqWRotorImpulses1 || WRotor.iqWRotorImpulses2) - { - if(WRotor.iqWRotorImpulses1>WRotor.iqWRotorImpulses2) - WRotor.iqWRotorSum = WRotor.iqWRotorImpulsesBeforeRegul1; - else - WRotor.iqWRotorSum = WRotor.iqWRotorImpulsesBeforeRegul2; - } - else - { - if(WRotor.iqWRotorCalc1>WRotor.iqWRotorCalc2) - WRotor.iqWRotorSum = WRotor.iqWRotorCalcBeforeRegul1; - else - WRotor.iqWRotorSum = WRotor.iqWRotorCalcBeforeRegul2; - } - - - } - else - { - if(WRotor.iqWRotorCalc1>WRotor.iqWRotorCalc2) - WRotor.iqWRotorSum = WRotor.iqWRotorCalcBeforeRegul1; - else - WRotor.iqWRotorSum = WRotor.iqWRotorCalcBeforeRegul2; - - } - - - // ïðîïàëî íàïðàâëåíèå -// if (prev_prev_RotorDirectionInstant && WRotorPBus.RotorDirectionSlow) -// if (WRotor.iqWRotorSum) -// { -// inc_sensor.break_direction = 1; -// } -// prev_prev_RotorDirectionInstant = WRotorPBus.RotorDirectionSlow; - - - -//// îøèáêà íàïðàâëåíèÿ!!! -// if (WRotorPBus.RotorDirectionSlow==0) -// { -// if (WRotor.iqWRotorSum) -// inc_sensor.break_direction = 1; -// } -// else -// inc_sensor.break_direction = 0; - - -// if (WRotorPBus.RotorDirectionSlow==0) -// { -// // ãîíèì â 0 îáîðîòû !!! îøèáêà íàïðàâëåíèÿ!!! -// WRotor.iqWRotorSumFilter = exp_regul_iq(koefW, WRotor.iqWRotorSumFilter, 0); -// } -// else - - - WRotor.iqWRotorSumFilter = exp_regul_iq(koefW, WRotor.iqWRotorSumFilter, WRotor.iqWRotorSum*WRotorPBus.RotorDirectionSlow); - - WRotor.iqWRotorSumRamp = zad_intensiv_q(wrotor_add, wrotor_add, WRotor.iqWRotorSumRamp, WRotor.iqWRotorSumFilter); - - - WRotor.iqWRotorSumFilter2 = exp_regul_iq(koefW2, WRotor.iqWRotorSumFilter2, WRotor.iqWRotorSumFilter); - WRotor.iqWRotorSumFilter3 = exp_regul_iq(koefW3, WRotor.iqWRotorSumFilter3, WRotor.iqWRotorSumFilter); - -} - - -#pragma CODE_SECTION(RotorMeasure,".fast_run"); -void RotorMeasureDetectDirection(void) -{ - int direction1, direction2, sum_direct; - - direction1 = project.cds_in[0].read.pbus.direction_in.bit.dir_sens_1 == ROTOR_SENSOR_CODE_CLOCKWISE ? 1 : - project.cds_in[0].read.pbus.direction_in.bit.dir_sens_1 == ROTOR_SENSOR_CODE_COUNTERCLOCKWISE ? -1 : - 0; - - direction2 = project.cds_in[0].read.pbus.direction_in.bit.dir_sens_2 == ROTOR_SENSOR_CODE_COUNTERCLOCKWISE ? 1 : - project.cds_in[0].read.pbus.direction_in.bit.dir_sens_2 == ROTOR_SENSOR_CODE_CLOCKWISE ? -1 : - 0; - - sum_direct = (direction1 + direction2) > 0 ? 1 : - (direction1 + direction2) < 0 ? -1 : - 0; - - WRotorPBus.RotorDirectionInstant = sum_direct; - -} - - -/////////////////////////////////////////////////////////////// - -#endif - - - -/////////////////////////////////////////////////////////////// - -#pragma CODE_SECTION(update_rot_sensors,".fast_run"); -void update_rot_sensors(void) -{ - inc_sensor.update_sensors(&inc_sensor); -} -/////////////////////////////////////////////////////////////// +#include "DSP281x_Examples.h" // DSP281x Examples Include File +#include "DSP281x_SWPrioritizedIsrLevels.h" // DSP281x Examples Include File +#include "DSP281x_Device.h" // DSP281x Headerfile Include File +#include "IQmathLib.h" + +#include +#include + +#include "filter_v1.h" +#include "xp_cds_in.h" +#include "xp_inc_sensor.h" +#include "xp_project.h" +#include "params.h" +#include "pwm_test_lines.h" +#include "params_norma.h" +#include "mathlib.h" +#include "params_alg.h" + + + +#pragma DATA_SECTION(WRotor,".fast_vars"); +WRotorValues WRotor = WRotorValues_DEFAULTS; + +#if (SENSOR_ALG==SENSOR_ALG_23550) + +#pragma DATA_SECTION(WRotorPBus,".slow_vars"); +WRotorValuesAngle WRotorPBus = WRotorValuesAngle_DEFAULTS; + + +#pragma DATA_SECTION(rotor_error_update_count,".fast_vars"); +unsigned int rotor_error_update_count = 0; + + +#define SIZE_BUF_SENSOR_LOGS 32 +#pragma DATA_SECTION(sensor_1_zero,".slow_vars"); +unsigned int sensor_1_zero[6+4+8][SIZE_BUF_SENSOR_LOGS], count_sensor_1_zero=0; + +#endif + +_iq koefW = _IQ(0.05); //0.05 +_iq koefW2 = _IQ(0.01); //0.05 +_iq koefW3 = _IQ(0.002); //0.05 + + + + + + + +#if (SENSOR_ALG==SENSOR_ALG_23550) +/////////////////////////////////////////////////////////////// +void rotorInit(void) +{ + WRotorPBus.ModeAutoDiscret = 1; +} + + + +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +#define MAX_COUNT_OVERFULL_DISCRET 2250 +#define MAX_DIRECTION 4000 +#define MAX_DIRECTION_2 2000 +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +void RotorDirectionFilter(int RotorDirectionIn, int *RotorDirectionOut, int *RotorDirectionOut2, int *count_direction) +{ + +// static int count_direction = 0; +// static int count_direction_minus = 0; + + + if (RotorDirectionIn==0) + { + if (*count_direction>0) (*count_direction)--; + if (*count_direction<0) (*count_direction)++; +// if (count_direction_minus>0) count_direction_minus--; + } + else + if (RotorDirectionIn>0) + { + if (*count_direction0) count_direction_minus--; + } + else + { + if (*count_direction>-MAX_DIRECTION) (*count_direction)--; +// if (count_direction_plus>0) count_direction_plus--; + } + + + if (RotorDirectionIn==0) + *RotorDirectionOut = 0; + else + if (RotorDirectionIn>0) + *RotorDirectionOut = 1; + else + *RotorDirectionOut = -1; + + + if (*count_direction>MAX_DIRECTION_2) + *RotorDirectionOut2 = 1; + else + if (*count_direction<-MAX_DIRECTION_2) + *RotorDirectionOut2 = -1; + else + *RotorDirectionOut2 = 0; + + + +} +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +#define LEVEL_VALUE_SENSOR_OVERFULL 65535 +#define MAX_COUNT_ERROR_ANALISATOR_SENSOR_PBUS 4000 +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// + +#pragma CODE_SECTION(AnalisatorRotorSensorPBus,".fast_run"); +int AnalisatorRotorSensorPBus(_iq d1, _iq d2, unsigned int *count_overfull_discret, unsigned int *count_zero_discret, _iq *prev_iqTimeRotor, + unsigned int *discret_out, unsigned int discret_in, _iq *iqWRotorCalcBeforeRegul, _iq *iqWRotorCalc, + int modeS1, int modeS2, + int valid_sensor_direct, int valid_sensor_90, + unsigned int *error_count ) +{ + int flag_not_ready_rotor, flag_overfull_rotor; + _iq iqTimeRotor; + // discret0 = 2 mks +// static long long KoefNorm_discret0 = 409600000LL;//((500 000/1024/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + static long long KoefNorm_discret0 = 102400000LL;//((500 000/4096/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + // discret1 = 20 ns +// static long long KoefNorm_discret1 = 40960000000LL;//((50 000 000/1024/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + static long long KoefNorm_discret1 = 10240000000LL;//((50 000 000/4096/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + +// _iq iqWRotorSumm;//,iqWRotorCalc; + + static _iq time_level_discret_1to0 = 60000 ;//682666; // KoefNorm_discret1/60000 = 0.813801288604736328125 Ãö. + static _iq time_level_discret_0to1 = 400;//204800; // KoefNorm_discret0/2000 = 0.244140625 Ãö. + static unsigned int discret; + + + if (valid_sensor_direct == 0) + d1 = 0; + if (valid_sensor_90 == 0) + d2 = 0; + + +// òóò ÷òî-òî ïîøëî íå òàê, áûëà ñìåíà äèñêðåòèçàöèè ïî îáîèì êàíàëàì. + if (valid_sensor_direct == 0 && valid_sensor_90 == 0) + { + if (*error_count>1; + + + +// max OVERFULL + if (flag_overfull_rotor) + { + if (*count_overfull_discret0) + (*count_overfull_discret)--; + } + +// zero? + if (flag_not_ready_rotor) + { + if (*count_zero_discret0) + (*count_zero_discret)--; + } + +// real zero? + if (*count_zero_discret==MAX_COUNT_OVERFULL_DISCRET) + { + // íîëü áûë ñëèøêîì äîëãî, çíà÷èò òî÷íî íîëü! + iqWRotorCalc = 0; + *prev_iqTimeRotor = 0; + iqTimeRotor = 0; + } + else + { + // íîëü åùå íå ñëèøêîì äîëãî, çíà÷èò áåðåì ñòàðîå çíà÷åíèå prev_iqTimeRotor + if (iqTimeRotor==0) + iqTimeRotor = *prev_iqTimeRotor; + } + *prev_iqTimeRotor = iqTimeRotor; + + + +// âûáîð íóæíîãî äèàïàçîíà + if (WRotorPBus.ModeAutoDiscret==1) + { + if ( (*count_overfull_discret==MAX_COUNT_OVERFULL_DISCRET) || (iqTimeRotor==0) ) + { + // òóò èëè ïåðåïîëíåíèå ïðîèçîøëî èëè âäðóã îñòàíîâèëèñü, îáîðîòû=0 + // òîãäà âêëþ÷àåì discret_out = 0 + if (discret_in == 1) // èëè òóò íàäî èñïëüçîâàòü discret? + { + // discret áûë =1, ïåðåêëþ÷àåì íà 0. + *discret_out = 0; + *count_overfull_discret = 0; // äàëè åùå îäèí øàíñ! + } + + } + else + { + // òåêóù. óðîâåíü discret==0 òîãäà... + if (discret==0 && iqTimeRotortime_level_discret_1to0 && iqTimeRotor!=65535) + *discret_out = 0; + } + } + + if (WRotorPBus.ModeAutoDiscret==2) + { + *discret_out = 0; + } + + if (WRotorPBus.ModeAutoDiscret==3) + { + *discret_out = 1; + } + + if ( (*count_overfull_discret==MAX_COUNT_OVERFULL_DISCRET) ) + { + // òóò óæå òî÷íî â 0, ò.ê. ñëèøêîì ìåäëåííî èäóò èìïóëüñû! + *prev_iqTimeRotor = iqTimeRotor = 0; + } + + + + + if ((iqTimeRotor != 0)) // && (WRotorPBus.iqTimeRotor<65535) + { + if (discret==0) + *iqWRotorCalcBeforeRegul = KoefNorm_discret0 / iqTimeRotor; + if (discret==1) + *iqWRotorCalcBeforeRegul = KoefNorm_discret1 / iqTimeRotor; + + *iqWRotorCalc = exp_regul_iq(koefW, *iqWRotorCalc, *iqWRotorCalcBeforeRegul); + } + else + { + *iqWRotorCalc = 0; + *iqWRotorCalcBeforeRegul = 0; + } + + +// if (*iqWRotorCalc == 0) +// *RotorDirection = 0; + + + return 0; + +} +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// + + +#pragma CODE_SECTION(RotorMeasurePBus,".fast_run"); +void RotorMeasurePBus(void) +{ + // discret0 = 2 mks +// static long long KoefNorm_discret0 = 409600000LL;//((500 000/1024/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + static long long KoefNorm_discret0 = 102400000LL;//((500 000/4096/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + // discret1 = 20 ns +// static long long KoefNorm_discret1 = 40960000000LL;//((50 000 000/1024/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + static long long KoefNorm_discret1 = 10240000000LL;//((50 000 000/4096/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + + static _iq time_level_discret_1to0 = 60000 ;//682666; // KoefNorm_discret1/60000 = 0.813801288604736328125 Ãö. + static _iq time_level_discret_0to1 = 400;//204800; // KoefNorm_discret0/2000 = 0.244140625 Ãö. + + static long long KoefNorm_angle = 16384LL; //2^24/1024 +// volatile float MyVar0 = 0; + + unsigned int MyVar3 = 0; +// int direction1 = 0, direction2 = 0; + volatile unsigned int discret; + + static unsigned int discret_out1, discret_out2; + + static int count_full_oborots = 0; + static unsigned int count_overfull_discret1 = 0; + static unsigned int count_zero_discret1 = 0; + static unsigned int count_overfull_discret2 = 0; + static unsigned int count_zero_discret2 = 0; + + static unsigned int count_discret_to_1 = 0; + static unsigned int count_discret_to_0 = 0; + + static unsigned int c_error_pbus_1 = 0; + static unsigned int c_error_pbus_2 = 0; + + + static _iq prev_iqTimeRotor1 = 0, prev_iqTimeRotor2 = 0; + + _iq iqWRotorSumm = 0; + + int flag_not_ready_rotor1, flag_overfull_rotor1; + int flag_not_ready_rotor2, flag_overfull_rotor2; + + //i_led1_on_off(1); + + + + flag_not_ready_rotor1 = 0; + flag_overfull_rotor1 = 0; + flag_not_ready_rotor2 = 0; + flag_overfull_rotor2 = 0; + + + + discret = project.cds_in[0].read.sbus.enabled_channels.bit.discret; + if (project.cds_in[0].read.sbus.enabled_channels.bit.discret != project.cds_in[0].write.sbus.enabled_channels.bit.discret) + discret = 2; + + if (project.cds_in[0].type_cds_xilinx == TYPE_CDS_XILINX_SP6) + { + sensor_1_zero[0][count_sensor_1_zero] = project.cds_in[0].read.pbus.Time_since_zero_point_S1; + sensor_1_zero[1][count_sensor_1_zero] = project.cds_in[0].read.pbus.Impulses_since_zero_point_Rising_S1; + sensor_1_zero[2][count_sensor_1_zero] = project.cds_in[0].read.pbus.Impulses_since_zero_point_Falling_S1; + sensor_1_zero[3][count_sensor_1_zero] = project.cds_in[0].read.pbus.Time_since_zero_point_S2; + sensor_1_zero[4][count_sensor_1_zero] = project.cds_in[0].read.pbus.Impulses_since_zero_point_Rising_S2; + sensor_1_zero[5][count_sensor_1_zero] = project.cds_in[0].read.pbus.Impulses_since_zero_point_Falling_S2; + } + sensor_1_zero[6][count_sensor_1_zero] = project.cds_in[0].read.pbus.SpeedS1_cnt; + sensor_1_zero[7][count_sensor_1_zero] = project.cds_in[0].read.pbus.SpeedS1_cnt90; + sensor_1_zero[8][count_sensor_1_zero] = project.cds_in[0].read.pbus.SpeedS2_cnt; + sensor_1_zero[9][count_sensor_1_zero] = project.cds_in[0].read.pbus.SpeedS2_cnt90; + + sensor_1_zero[10][count_sensor_1_zero] = inc_sensor.data.Time1; + sensor_1_zero[11][count_sensor_1_zero] = inc_sensor.data.Impulses1; + sensor_1_zero[12][count_sensor_1_zero] = inc_sensor.data.CountZero1; + sensor_1_zero[13][count_sensor_1_zero] = inc_sensor.data.CountOne1; + + sensor_1_zero[14][count_sensor_1_zero] = inc_sensor.data.Time2; + sensor_1_zero[15][count_sensor_1_zero] = inc_sensor.data.Impulses2; + sensor_1_zero[16][count_sensor_1_zero] = inc_sensor.data.CountZero2; + sensor_1_zero[17][count_sensor_1_zero] = inc_sensor.data.CountOne2; + + count_sensor_1_zero++; + if (count_sensor_1_zero>=SIZE_BUF_SENSOR_LOGS) + { + count_sensor_1_zero = 0; + count_full_oborots++; + if (count_full_oborots>3) + count_full_oborots = 0; + } +/* + if (count_sensor_1_zero==904) + { + discret = 3; + } +*/ + +#if (ENABLE_ROTOR_SENSOR_ZERO_SIGNAL==1) + if (project.cds_in[0].type_cds_xilinx == TYPE_CDS_XILINX_SP6) + { + +#if (ENABLE_ROTOR_SENSOR_1_PBUS==1) + WRotorPBus.iqWRotorRawAngle1F = project.cds_in[0].read.pbus.Impulses_since_zero_point_Falling_S1-32768; + WRotorPBus.iqWRotorRawAngle1R = project.cds_in[0].read.pbus.Impulses_since_zero_point_Rising_S1-32768; + WRotorPBus.iqAngle1F = KoefNorm_angle * WRotorPBus.iqWRotorRawAngle1F; + WRotorPBus.iqAngle1R = KoefNorm_angle * WRotorPBus.iqWRotorRawAngle1R; +#else + WRotorPBus.iqWRotorRawAngle1F = 0; + WRotorPBus.iqWRotorRawAngle1R = 0; + WRotorPBus.iqAngle1F = 0; + WRotorPBus.iqAngle1R = 0; +#endif + +#if (ENABLE_ROTOR_SENSOR_2_PBUS==1) + WRotorPBus.iqWRotorRawAngle2F = project.cds_in[0].read.pbus.Impulses_since_zero_point_Falling_S2-32768; + WRotorPBus.iqWRotorRawAngle2R = project.cds_in[0].read.pbus.Impulses_since_zero_point_Rising_S2-32768; + WRotorPBus.iqAngle2F = KoefNorm_angle * WRotorPBus.iqWRotorRawAngle2F; + WRotorPBus.iqAngle2R = KoefNorm_angle * WRotorPBus.iqWRotorRawAngle2R; +#else + WRotorPBus.iqWRotorRawAngle2F = 0; + WRotorPBus.iqWRotorRawAngle2R = 0; + WRotorPBus.iqAngle2F = 0; + WRotorPBus.iqAngle2R = 0; +#endif + } + else + { + WRotorPBus.iqWRotorRawAngle1F = 0; + WRotorPBus.iqWRotorRawAngle1R = 0; + WRotorPBus.iqAngle1F = 0; + WRotorPBus.iqAngle1R = 0; + + WRotorPBus.iqWRotorRawAngle2F = 0; + WRotorPBus.iqWRotorRawAngle2R = 0; + WRotorPBus.iqAngle2F = 0; + WRotorPBus.iqAngle2R = 0; + + } +#endif + + +#if (ENABLE_ROTOR_SENSOR_1_PBUS==1) + //************************************************************************************************** + MyVar3 = project.cds_in[0].read.pbus.SpeedS1_cnt; + + if ((MyVar3 <= COUNT_DECODER_ZERO_WROTORPBus) + && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) + { + WRotorPBus.iqWRotorRaw0 = MyVar3; + } + else + { + WRotorPBus.iqWRotorRaw0 = 0; + } + + MyVar3 = project.cds_in[0].read.pbus.SpeedS1_cnt90; + + if ((MyVar3 <= COUNT_DECODER_ZERO_WROTORPBus) + && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) + { + WRotorPBus.iqWRotorRaw1 = MyVar3; + } + else + { + WRotorPBus.iqWRotorRaw1 = 0; + } +#else + WRotorPBus.iqWRotorRaw0 = 0; + WRotorPBus.iqWRotorRaw1 = 0; +#endif + + +#if (ENABLE_ROTOR_SENSOR_2_PBUS==1) + //*************************************************************************************************** + MyVar3 = project.cds_in[0].read.pbus.SpeedS2_cnt; + + if ((MyVar3 <= COUNT_DECODER_ZERO_WROTORPBus) + && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) + { + WRotorPBus.iqWRotorRaw2 = MyVar3; + } + else + { + WRotorPBus.iqWRotorRaw2 = 0; + } + + MyVar3 = project.cds_in[0].read.pbus.SpeedS2_cnt90; + + if ((MyVar3 <= COUNT_DECODER_ZERO_WROTORPBus) + && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) + { + WRotorPBus.iqWRotorRaw3 = MyVar3; + } + else + { + WRotorPBus.iqWRotorRaw3 = 0; + } +#else + WRotorPBus.iqWRotorRaw2 = 0; + WRotorPBus.iqWRotorRaw3 = 0; +#endif + + +#if (ENABLE_ROTOR_SENSOR_1_PBUS==1) +// if (project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor1_direct && project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor1_90 ) + AnalisatorRotorSensorPBus(WRotorPBus.iqWRotorRaw0, WRotorPBus.iqWRotorRaw1, &count_overfull_discret1, &count_zero_discret1, + &prev_iqTimeRotor1, &discret_out1, project.cds_in[0].read.sbus.enabled_channels.bit.discret, + &WRotorPBus.iqWRotorCalcBeforeRegul1, &WRotorPBus.iqWRotorCalc1, + project.cds_in[0].read.pbus.direction_in.bit.mode_sensor1_direct, project.cds_in[0].read.pbus.direction_in.bit.mode_sensor1_90, + project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor1_direct, project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor1_90, + &c_error_pbus_1 ); +#endif + +#if (ENABLE_ROTOR_SENSOR_2_PBUS==1) +// if (project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor2_direct && project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor2_90 ) + AnalisatorRotorSensorPBus(WRotorPBus.iqWRotorRaw2, WRotorPBus.iqWRotorRaw3, &count_overfull_discret2, &count_zero_discret2, + &prev_iqTimeRotor2, &discret_out2, project.cds_in[0].read.sbus.enabled_channels.bit.discret, + &WRotorPBus.iqWRotorCalcBeforeRegul2, &WRotorPBus.iqWRotorCalc2, + project.cds_in[0].read.pbus.direction_in.bit.mode_sensor2_direct, project.cds_in[0].read.pbus.direction_in.bit.mode_sensor2_90, + project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor2_direct, project.cds_in[0].read.pbus.direction_in.bit.value_vaild_sensor2_90, + &c_error_pbus_2); +#endif + + + // RotorDirectionFilter(WRotorPBus.RotorDirectionInstant, &WRotorPBus.RotorDirectionSlow); + + + + if (discret_out1==1 || discret_out2==1) + { + project.cds_in[0].write.sbus.enabled_channels.bit.discret = 1; + count_discret_to_1++; + } + else + { + project.cds_in[0].write.sbus.enabled_channels.bit.discret = 0; + count_discret_to_0++; + } + + +} + + + + +#define MAX_COUNT_OVERFULL_DISCRET_2 150 +#pragma CODE_SECTION(RotorMeasure,".fast_run"); +void RotorMeasure(void) +{ + + // 600 Khz clock on every edge +// static long long KoefNorm = 53635601LL;//((600 000/6256/NORMA_WROTOR/2) * ((long)2 << 24)); //15 - NormaWRotor 782*8 = 6256 +// static long long KoefNormMS = 491520000LL;//((600 000/1024/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 +// static long long KoefNormNS = 49152000000LL;//((60 000 000/1024/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + static long long KoefNormMS = 122880000LL;//((600 000/4096/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + static long long KoefNormNS = 12288000000LL;//((60 000 000/4096/NORMA_WROTOR) * ((long)2 << 24)); //20 - NORMA_FROTOR 1024*8 = 8129 + static long long KoefNormImpulses = 838860800000000LL;// (2^24 * 1000000000 / (Impulses(ns)) / NORMA_WROTOR + + static _iq max_value_rotor = _IQ(500.0/60.0/NORMA_FROTOR); + static _iq wrotor_add_ramp = _IQ(0.001/NORMA_FROTOR); + +// volatile float MyVar0 = 0; +// volatile unsigned int MyVar1 = 0; +// volatile unsigned int MyVar2 = 0; + unsigned int MyVar3; + + + inc_sensor.read_sensors(&inc_sensor); + + // flag_not_ready_rotor = 0; + +//************************************************************************************************** +// sensor 1 + + if (inc_sensor.use_sensor1) + { + MyVar3 = inc_sensor.data.CountOne1; +// MyVar3 = (unsigned long) rotation_sensor.in_plane.out.CountOne1; + + if ((MyVar3 < COUNT_DECODER_ZERO_WROTOR) + && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) + { + +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_21_ON; +#endif + + WRotor.iqWRotorRaw0 = MyVar3; + } + else + { + +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_21_OFF; +#endif + + WRotor.iqWRotorRaw0 = 0; + } + MyVar3 = inc_sensor.data.CountZero1; + + if ((MyVar3 < COUNT_DECODER_ZERO_WROTOR) + && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) + { +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_22_ON; +#endif + WRotor.iqWRotorRaw1 = MyVar3; + } + else + { +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_22_OFF; +#endif + WRotor.iqWRotorRaw1 = 0; + } + } + else + { + WRotor.iqWRotorRaw0 = 0; + WRotor.iqWRotorRaw1 = 0; + } + //logpar.uns_log0 = (Uint16)(my_var1); + //logpar.uns_log1 = (Uint16)(my_var2); + + // sensor 2 + if (inc_sensor.use_sensor2) + { + MyVar3 = inc_sensor.data.CountOne2; + + if ((MyVar3 < COUNT_DECODER_ZERO_WROTOR) + && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) + { +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_18_ON; +#endif + WRotor.iqWRotorRaw2 = MyVar3; + } + else + { +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_18_OFF; +#endif + WRotor.iqWRotorRaw2 = 0; + } + + MyVar3 = inc_sensor.data.CountZero2; + + if ((MyVar3 < COUNT_DECODER_ZERO_WROTOR) + && (MyVar3 > COUNT_DECODER_MAX_WROTOR)) + { +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_23_ON; +#endif + WRotor.iqWRotorRaw3 = MyVar3; + } + else + { +#if(_ENABLE_PWM_LINES_FOR_TESTS_ROTOR) + PWM_LINES_TK_23_OFF; +#endif + WRotor.iqWRotorRaw3 = 0; + } + } + else + { + WRotor.iqWRotorRaw2 = 0; + WRotor.iqWRotorRaw3 = 0; + } + +// if (WRotor.iqWRotorRaw0==0 && WRotor.iqWRotorRaw1==0 && WRotor.iqWRotorRaw2==0 && WRotor.iqWRotorRaw3==0) +// flag_not_ready_rotor = 1; + + if (WRotor.iqWRotorRaw0==0) + { + if (WRotor.count_zero_discret0==MAX_COUNT_OVERFULL_DISCRET_2) + { + WRotor.prev_iqWRotorRaw0 = WRotor.iqWRotorRaw0 = 0; + } + else + { + WRotor.iqWRotorRaw0 = WRotor.prev_iqWRotorRaw0; + WRotor.count_zero_discret0++; + } + } + else + { + WRotor.count_zero_discret0 = 0; + WRotor.prev_iqWRotorRaw0 = WRotor.iqWRotorRaw0; + } + + if (WRotor.iqWRotorRaw1==0) + { + if (WRotor.count_zero_discret1==MAX_COUNT_OVERFULL_DISCRET_2) + { + WRotor.prev_iqWRotorRaw1 = WRotor.iqWRotorRaw1 = 0; + } + else + { + WRotor.iqWRotorRaw1 = WRotor.prev_iqWRotorRaw1; + WRotor.count_zero_discret1++; + } + } + else + { + WRotor.count_zero_discret1 = 0; + WRotor.prev_iqWRotorRaw1 = WRotor.iqWRotorRaw1; + } + + if (WRotor.iqWRotorRaw2==0) + { + if (WRotor.count_zero_discret2==MAX_COUNT_OVERFULL_DISCRET_2) + { + WRotor.prev_iqWRotorRaw2 = WRotor.iqWRotorRaw2 = 0; + } + else + { + WRotor.iqWRotorRaw2 = WRotor.prev_iqWRotorRaw2; + WRotor.count_zero_discret2++; + } + } + else + { + WRotor.count_zero_discret2 = 0; + WRotor.prev_iqWRotorRaw2 = WRotor.iqWRotorRaw2; + } + + if (WRotor.iqWRotorRaw3==0) + { + if (WRotor.count_zero_discret3==MAX_COUNT_OVERFULL_DISCRET_2) + { + WRotor.prev_iqWRotorRaw3 = WRotor.iqWRotorRaw3 = 0; + } + else + { + WRotor.iqWRotorRaw3 = WRotor.prev_iqWRotorRaw3; + WRotor.count_zero_discret3++; + } + } + else + { + WRotor.count_zero_discret3 = 0; + WRotor.prev_iqWRotorRaw3 = WRotor.iqWRotorRaw3; + } + + + WRotor.iqTimeSensor1 = WRotor.iqWRotorRaw0 + WRotor.iqWRotorRaw1; + WRotor.iqTimeSensor2 = WRotor.iqWRotorRaw2 + WRotor.iqWRotorRaw3; + + // +// // zero? +// if (flag_not_ready_rotor) +// { +// if (*count_zero_discret0) +// (*count_zero_discret)--; +// } +// +// // real zero? +// if (count_zero_discret==MAX_COUNT_OVERFULL_DISCRET) +// { +// // íîëü áûë ñëèøêîì äîëãî, çíà÷èò òî÷íî íîëü! +// WRotor.iqTimeSensor1 = 0; +// WRotor.prev_iqTimeSensor1 = 0; +// } +// else +// { +// // íîëü åùå íå ñëèøêîì äîëãî, çíà÷èò áåðåì ñòàðîå çíà÷åíèå prev_iqTimeRotor +// if (WRotor.iqTimeSensor1==0) +// WRotor.iqTimeSensor1 = WRotor.prev_iqTimeSensor1; +// } +// WRotor.prev_iqTimeSensor1 = WRotor.iqTimeSensor1; +// +// +// // max OVERFULL +// if (flag_overfull_rotor) +// { +// if (*count_overfull_discret0) +// (*count_overfull_discret)--; +// } +// +// // zero? +// if (flag_not_ready_rotor) +// { +// if (*count_zero_discret0) +// (*count_zero_discret)--; +// } +// +// // real zero? +// if (*count_zero_discret==MAX_COUNT_OVERFULL_DISCRET) +// { +// // íîëü áûë ñëèøêîì äîëãî, çíà÷èò òî÷íî íîëü! +// iqWRotorCalc = 0; +// *prev_iqTimeRotor = 0; +// iqTimeRotor = 0; +// } +// else +// { +// // íîëü åùå íå ñëèøêîì äîëãî, çíà÷èò áåðåì ñòàðîå çíà÷åíèå prev_iqTimeRotor +// if (iqTimeRotor==0) +// iqTimeRotor = *prev_iqTimeRotor; +// } +// *prev_iqTimeRotor = iqTimeRotor; +// +// +// + +/// + if (WRotor.iqTimeSensor1 != 0 && inc_sensor.use_sensor1) + { + if (inc_sensor.pm67regs.read_comand_reg.bit.sampling_time1==0) + WRotor.iqWRotorCalcBeforeRegul1 = KoefNormMS / WRotor.iqTimeSensor1; + if (inc_sensor.pm67regs.read_comand_reg.bit.sampling_time1==1) + WRotor.iqWRotorCalcBeforeRegul1 = KoefNormNS / WRotor.iqTimeSensor1; + + if (WRotor.iqWRotorCalcBeforeRegul1 > max_value_rotor) + { + WRotor.iqWRotorCalc1 = 0; + WRotor.iqWRotorCalcBeforeRegul1 = 0; + } + else + WRotor.iqWRotorCalc1 = exp_regul_iq(koefW, WRotor.iqWRotorCalc1, WRotor.iqWRotorCalcBeforeRegul1); + + ///// + if (WRotor.iqWRotorCalc1) + { + if (WRotor.iqPrevWRotorCalc1 != WRotor.iqWRotorCalc1) + { + WRotor.iqWRotorCalc1Ramp = zad_intensiv_q(wrotor_add_ramp, wrotor_add_ramp, WRotor.iqWRotorCalc1Ramp, WRotor.iqWRotorCalc1); + WRotor.iqPrevWRotorCalc1 = WRotor.iqWRotorCalc1; + } + } + else + { + WRotor.iqPrevWRotorCalc1 = 0; + WRotor.iqWRotorCalc1Ramp = 0; + } + //// + } + else + { + WRotor.iqWRotorCalc1 = 0; + WRotor.iqWRotorCalcBeforeRegul1 = 0; + } +/// + if (WRotor.iqTimeSensor2 != 0 && inc_sensor.use_sensor2) + { + if (inc_sensor.pm67regs.read_comand_reg.bit.sampling_time2==0) + WRotor.iqWRotorCalcBeforeRegul2 = KoefNormMS / WRotor.iqTimeSensor2; + if (inc_sensor.pm67regs.read_comand_reg.bit.sampling_time2==1) + WRotor.iqWRotorCalcBeforeRegul2 = KoefNormNS / WRotor.iqTimeSensor2; + + if (WRotor.iqWRotorCalcBeforeRegul2 > max_value_rotor) + { + WRotor.iqWRotorCalc2 = 0; + WRotor.iqWRotorCalcBeforeRegul2 = 0; + } + else + WRotor.iqWRotorCalc2 = exp_regul_iq(koefW, WRotor.iqWRotorCalc2, WRotor.iqWRotorCalcBeforeRegul2); + + + + ///// + if (WRotor.iqWRotorCalc2) + { + if (WRotor.iqPrevWRotorCalc2 != WRotor.iqWRotorCalc2) + { + WRotor.iqWRotorCalc2Ramp = zad_intensiv_q(wrotor_add_ramp, wrotor_add_ramp, WRotor.iqWRotorCalc2Ramp, WRotor.iqWRotorCalc2); + WRotor.iqPrevWRotorCalc2 = WRotor.iqWRotorCalc2; + } + } + else + { + WRotor.iqPrevWRotorCalc2 = 0; + WRotor.iqWRotorCalc2Ramp = 0; + } + //// + } + else + { + WRotor.iqWRotorCalc2 = 0; + WRotor.iqWRotorCalcBeforeRegul2 = 0; + } +/// + if (inc_sensor.data.TimeCalcFromImpulses1 && inc_sensor.use_sensor1) + WRotor.iqWRotorImpulsesBeforeRegul1 = (long long) KoefNormImpulses / (inc_sensor.data.TimeCalcFromImpulses1 * ROTOR_SENSOR_IMPULSES_PER_ROTATE); + else + WRotor.iqWRotorImpulsesBeforeRegul1 = 0; + + WRotor.iqWRotorImpulses1 = exp_regul_iq(koefW, WRotor.iqWRotorImpulses1, WRotor.iqWRotorImpulsesBeforeRegul1); + + if (inc_sensor.data.TimeCalcFromImpulses2 && inc_sensor.use_sensor2) + WRotor.iqWRotorImpulsesBeforeRegul2 = (long long) KoefNormImpulses / (inc_sensor.data.TimeCalcFromImpulses2 * ROTOR_SENSOR_IMPULSES_PER_ROTATE); + else + WRotor.iqWRotorImpulsesBeforeRegul2 = 0; + + WRotor.iqWRotorImpulses2 = exp_regul_iq(koefW, WRotor.iqWRotorImpulses2, WRotor.iqWRotorImpulsesBeforeRegul2); + + + // WRotor.iqWRotorCalcBeforeRegul = _IQdiv(WRotor.iqWRotorCalcBeforeRegul,IQ_CONST_3); +} + +#define LEVEL_SWITCH_TO_GET_IMPULSES_OBOROTS 50 // Oborot +void select_values_wrotor(void) +{ + static _iq level_switch_to_get_impulses_hz = _IQ(LEVEL_SWITCH_TO_GET_IMPULSES_OBOROTS/60.0/NORMA_FROTOR); + static unsigned int prev_RotorDirectionInstant = 0; + static unsigned int status_RotorRotation = 0; // åñòü âðàùåíèå? + static _iq wrotor_add = _IQ(0.002/NORMA_FROTOR); + + + + + if (WRotor.iqWRotorCalc1>level_switch_to_get_impulses_hz + || WRotor.iqWRotorCalc2>level_switch_to_get_impulses_hz) + { + // óæå áîëüøèå îáîðîòû + if (WRotor.iqWRotorImpulses1 || WRotor.iqWRotorImpulses2) + { + if(WRotor.iqWRotorImpulses1>WRotor.iqWRotorImpulses2) + WRotor.iqWRotorSum = WRotor.iqWRotorImpulsesBeforeRegul1; + else + WRotor.iqWRotorSum = WRotor.iqWRotorImpulsesBeforeRegul2; + } + else + { + if(WRotor.iqWRotorCalc1>WRotor.iqWRotorCalc2) + WRotor.iqWRotorSum = WRotor.iqWRotorCalcBeforeRegul1; + else + WRotor.iqWRotorSum = WRotor.iqWRotorCalcBeforeRegul2; + } + + + } + else + { + if(WRotor.iqWRotorCalc1>WRotor.iqWRotorCalc2) + WRotor.iqWRotorSum = WRotor.iqWRotorCalcBeforeRegul1; + else + WRotor.iqWRotorSum = WRotor.iqWRotorCalcBeforeRegul2; + + } + + + // ïðîïàëî íàïðàâëåíèå +// if (prev_prev_RotorDirectionInstant && WRotorPBus.RotorDirectionSlow) +// if (WRotor.iqWRotorSum) +// { +// inc_sensor.break_direction = 1; +// } +// prev_prev_RotorDirectionInstant = WRotorPBus.RotorDirectionSlow; + + + +//// îøèáêà íàïðàâëåíèÿ!!! +// if (WRotorPBus.RotorDirectionSlow==0) +// { +// if (WRotor.iqWRotorSum) +// inc_sensor.break_direction = 1; +// } +// else +// inc_sensor.break_direction = 0; + + +// if (WRotorPBus.RotorDirectionSlow==0) +// { +// // ãîíèì â 0 îáîðîòû !!! îøèáêà íàïðàâëåíèÿ!!! +// WRotor.iqWRotorSumFilter = exp_regul_iq(koefW, WRotor.iqWRotorSumFilter, 0); +// } +// else + + + WRotor.iqWRotorSumFilter = exp_regul_iq(koefW, WRotor.iqWRotorSumFilter, WRotor.iqWRotorSum*WRotorPBus.RotorDirectionSlow); + + WRotor.iqWRotorSumRamp = zad_intensiv_q(wrotor_add, wrotor_add, WRotor.iqWRotorSumRamp, WRotor.iqWRotorSumFilter); + + + WRotor.iqWRotorSumFilter2 = exp_regul_iq(koefW2, WRotor.iqWRotorSumFilter2, WRotor.iqWRotorSumFilter); + WRotor.iqWRotorSumFilter3 = exp_regul_iq(koefW3, WRotor.iqWRotorSumFilter3, WRotor.iqWRotorSumFilter); + +} + + + +#pragma CODE_SECTION(RotorMeasure,".fast_run"); +void RotorMeasureDetectDirection(void) +{ + int direction1, direction2, sum_direct; + + direction1 = project.cds_in[0].read.pbus.direction_in.bit.dir_sens_1 == ROTOR_SENSOR_CODE_CLOCKWISE ? 1 : + project.cds_in[0].read.pbus.direction_in.bit.dir_sens_1 == ROTOR_SENSOR_CODE_COUNTERCLOCKWISE ? -1 : + 0; + + direction2 = project.cds_in[0].read.pbus.direction_in.bit.dir_sens_2 == ROTOR_SENSOR_CODE_COUNTERCLOCKWISE ? 1 : + project.cds_in[0].read.pbus.direction_in.bit.dir_sens_2 == ROTOR_SENSOR_CODE_CLOCKWISE ? -1 : + 0; + + sum_direct = (direction1 + direction2) > 0 ? 1 : + (direction1 + direction2) < 0 ? -1 : + 0; + + WRotorPBus.RotorDirectionInstant = sum_direct; + +} + + +/////////////////////////////////////////////////////////////// + +#endif + + + +/////////////////////////////////////////////////////////////// + +#pragma CODE_SECTION(update_rot_sensors,".fast_run"); +void update_rot_sensors(void) +{ + inc_sensor.update_sensors(&inc_sensor); +} +/////////////////////////////////////////////////////////////// diff --git a/Inu/Src/main_matlab/IQmathLib.h b/Inu/Src/main_matlab/IQmathLib.h index 4b20f9e..5e27d84 100644 --- a/Inu/Src/main_matlab/IQmathLib.h +++ b/Inu/Src/main_matlab/IQmathLib.h @@ -622,6 +622,7 @@ long exp_fixedN(long x, unsigned int n); #define _IQdiv(A,B) divide(A,B) #define _IQ19div(A,B) divide19(A,B) #define _IQ18div(A,B) divideN(A,B,18) +#define _IQ22div(A,B) divideN(A,B,22) #define _IQsin(A) sin_fixed(A) #define _IQcos(A) cos_fixed(A) #define _IQsinPU(A) sin_fixed(A) diff --git a/Inu/Src/main_matlab/IQmathLib_matlab.c b/Inu/Src/main_matlab/IQmathLib_matlab.c index f77984b..aac0c57 100644 --- a/Inu/Src/main_matlab/IQmathLib_matlab.c +++ b/Inu/Src/main_matlab/IQmathLib_matlab.c @@ -40,6 +40,8 @@ long long multiply_fixed_base_select(long long x, long long y, int base) long divide(long num, long den) { + if (den == 0) + return 0; long long numLong = (long long)num; long long quotient = (numLong << GLOBAL_Q) / den; return (long)quotient; @@ -47,6 +49,8 @@ long divide(long num, long den) long divide19(long num, long den) { + if (den == 0) + return 0; long long numLong = (long long)num; long long quotient = (numLong << 19) / den; return (long)quotient; @@ -54,6 +58,8 @@ long divide19(long num, long den) long divideN(long num, long den, unsigned int d) { + if (den == 0) + return 0; long long numLong = (long long)num; long long quotient = (numLong << d) / den; return (long)quotient; @@ -61,6 +67,8 @@ long divideN(long num, long den, unsigned int d) // static inline long long divide_fixed_base_select(long long num, long long den, int base) { + if (den == 0) + return 0; long long quotient = ((long long)num << base) / den; return quotient; } diff --git a/Inu/Src/main_matlab/init28335.c b/Inu/Src/main_matlab/init28335.c new file mode 100644 index 0000000..ed2e47a --- /dev/null +++ b/Inu/Src/main_matlab/init28335.c @@ -0,0 +1,67 @@ +/************************************************************************** + Description: Ïîñëå çàãðóçêè ïðîöåññîðà ôóíêöèÿ âûçûâàåòñÿ îäèí ðàç + è èíèöèàëèçèðóåò óïðàâëÿþùèå ðåãèñòðû ïðîöåññîðà + TMS320F28335/TMS320F28379D. + + Àâòîð: Óëèòîâñêèé Ä.È. + Äàòà ïîñëåäíåãî îáíîâëåíèÿ: 2021.10.04 +**************************************************************************/ + + +#include "def.h" +#include "init28335.h" + +#define FREQ_TIMER_3 (FREQ_PWM*2) + +void init28335(void) { + + edrk.flag_second_PCH = 0; + + edrk_init_variables_matlab(); + init_global_time_struct(FREQ_TIMER_3); + + +} //void init28335(void) + +void edrk_init_variables_matlab(void) +{ + + initVectorControl(); + InitXPWM(FREQ_PWM); + InitPWM_Variables(edrk.flag_second_PCH); + +//#if(SENSOR_ALG==SENSOR_ALG_23550) +// rotorInit(); +//#endif +//#if(SENSOR_ALG==SENSOR_ALG_22220) +// // 22220 +// rotorInit_22220(); +//#endif + + control_station.clear(&control_station); + + edrk_init_matlab(); + + + init_ramp_all_zadanie(); + init_all_limit_koeffs(); +} + +void edrk_init_matlab(void) +{ + + edrk.Uzad_max = _IQ(K_STATOR_MAX); // ìàêñ àìïëèòóäà â Êì äëÿ ìèíèìàëüíîãî èìïóëüñà = DEF_PERIOD_MIN_MKS + edrk.iq_bpsi_normal = _IQ(BPSI_NORMAL / NORMA_FROTOR); + // edrk.iq_bpsi_max = _IQ(BPSI_MAXIMAL/NORMA_FROTOR); + // edrk.iq_f_provorot = _IQ(F_PROVOROT/NORMA_FROTOR); + + edrk.flag_enable_update_hmi = 1; + + + edrk.zadanie.ZadanieU_Charge = NOMINAL_U_ZARYAD; + edrk.zadanie.iq_ZadanieU_Charge = _IQ(NOMINAL_U_ZARYAD / NORMA_ACP); + + edrk.zadanie.iq_set_break_level = _IQ(NOMINAL_U_BREAK_LEVEL / NORMA_ACP); + + control_station.setup_time_detect_active[CONTROL_STATION_TERMINAL_RS232] = 50; +} \ No newline at end of file diff --git a/Inu/Src/main_matlab/init28335.h b/Inu/Src/main_matlab/init28335.h new file mode 100644 index 0000000..f6abce1 --- /dev/null +++ b/Inu/Src/main_matlab/init28335.h @@ -0,0 +1,10 @@ +#ifndef INIT28335 +#define INIT28335 + +#include "controller.h" + +void init28335(void); + +void edrk_init_matlab(void); +void edrk_init_variables_matlab(void); +#endif //INIT28335 diff --git a/Inu/Src/main_matlab/main_matlab.c b/Inu/Src/main_matlab/main_matlab.c index 0bb5ff0..6b22dcd 100644 --- a/Inu/Src/main_matlab/main_matlab.c +++ b/Inu/Src/main_matlab/main_matlab.c @@ -9,6 +9,7 @@ #include "edrk_main.h" #include "vector.h" #include "vector_control.h" +#include "v_rotor.h" T_project project = {0}; @@ -17,6 +18,7 @@ WINDING a; EDRK edrk = EDRK_DEFAULT; FLAG f = FLAG_DEFAULTS; +WRotorValues WRotor = WRotorValues_DEFAULTS; void project_read_all_pbus2() { @@ -93,6 +95,11 @@ _iq break_result_4 = 0; // } +void update_uom(void) +{ + +} + void inc_RS_timeout_cicle(void) { diff --git a/Inu/Src/main_matlab/main_matlab.h b/Inu/Src/main_matlab/main_matlab.h index fe79cab..f44848b 100644 --- a/Inu/Src/main_matlab/main_matlab.h +++ b/Inu/Src/main_matlab/main_matlab.h @@ -3,16 +3,6 @@ #include "vector.h" #include "edrk_main.h" -typedef union { - //unsigned int all; - int all; -// struct MODBUS_BITS_STRUCT bit; -// struct MODBUS_WORD_STRUCT byte; -} MODBUS_REG_STRUCT; - - -//extern MODBUS_REG_STRUCT modbus_table_in[1024]; -//extern MODBUS_REG_STRUCT modbus_table_out[1024]; void init_flag_a(void); diff --git a/Inu/controller.c b/Inu/controller.c index bdbf105..cc5f471 100644 --- a/Inu/controller.c +++ b/Inu/controller.c @@ -10,12 +10,8 @@ #include "simstruc.h" -#include "wrapper_inu.h" -#include "def.h" #include "controller.h" -#include "edrk_main.h" -#include "vector.h" -#include "vector_control.h" +#include "init28335.h" extern UMotorMeasure motor; @@ -146,156 +142,13 @@ void processSFunctionIfChanged(SimStruct *S, int_T *iW) { } void initialisationOnStart(int_T *iW) { -//// êîå-÷òî âûïîëíÿåì îäèí ðàç ïðè çàïóñêå ìîäåëè -// if ( iW[1] == 1 ) { -// iW[1] = 0; -// -// timers_adc = 0; -// timers_pwm = 0; -// -// // èíèöèàëèçàöèÿ ïðîöåññîðà -// init28335(); -// -// init_DQ_pid(); -// -// // èìèòàöèÿ ñ÷èòûâàíèÿ ïàðàìåòðîâ èç EEPROM -// // ... ïàðàìåòðû èç ìîäåëè (ñì. áëîê "Parameters") -// for ( j = FIRST_WRITE_PAR_NUM; j < paramNo; j++ ) { -// param[j] = paramNew[j]; -// } -// // ... ïàðàìåòðû èç ôàéëà -// param[180] = 930;//rf.PsiZ, %*10 îò PSI_BAZ -// -// param[200] = 2048;//offset.Ia1, åä. ÀÖÏ -// param[201] = 2048;//offset.Ib1, åä. ÀÖÏ -// param[202] = 2048;//offset.Ic1, åä. ÀÖÏ -// param[203] = 2048;//offset.Udc1, åä. ÀÖÏ -// param[206] = 2048;//offset.Ia2, åä. ÀÖÏ -// param[207] = 2048;//offset.Ib2, åä. ÀÖÏ -// param[208] = 2048;//offset.Ic2, åä. ÀÖÏ -// param[209] = 2048;//offset.Udc2, åä. ÀÖÏ -// -// param[210] = 100;//cc.Kp, % -// param[211] = 100;//cc.Ki, % -// param[212] = 100;//cf.Kp, % -// param[213] = 100;//cf.Ki, % -// param[214] = 100;//csp.Kp, % -// param[215] = 100;//csp.Ki, % -// -// param[220] = 99;//protect.IacMax, % îò IAC_SENS_MAX -// param[221] = 130;//protect.UdcMax, % îò U_NOM -// param[222] = 110;//IzLim, % îò I_BAZ (ä.á. áîëüøå cf.IdLim) -// param[223] = 105;//cf.IdLim, % îò I_BAZ (ä.á. ìåíüøå IzLim) -// param[224] = 105;//csp.IqLim, % îò I_BAZ -// param[225] = 97;//protect.UdcMin, % îò U_NOM -// param[226] = 115;//protect.WmMax, % îò N_NOM -// param[228] = 103;//rf.WmNomPsi, % îò N_NOM -// param[229] = 97;//rf.YlimPsi, % îò Y_LIM -// param[231] = 300;//protect.TudcMin, ìñ -// param[233] = 1000;//protect.TwmMax, ìñ -// -// param[244] = 26000;//rs.WlimIncr, ìñ -// param[245] = 2000;//csp.IlimIncr, ìñ -// param[248] = 6000;//rp.PlimIncr, ìñ -// -// param[269] = 9964;//9700;//KmeCorr, %*100 -// -// param[285] = 10;//Kudc, ìñ*10 -// param[286] = 700;//Kwm, ìñ*10 -// param[288] = 250;//rs.Kwmz, ìñ -// param[289] = 50;//rf.Kpsiz, ìñ -// param[290] = 40;//Kme, ìñ -// param[292] = 80;//rp.Kpmz, ìñ -// -// param[303] = (unsigned short)(19200.);//sgmPar.Rs, ìêÎì -// param[304] = (unsigned short)(19364.);//sgmPar.Lls, ìêÃí*10 -// param[305] = (unsigned short)(8500.);//sgmPar.Rr, ìêÎì -// param[306] = (unsigned short)(10212.);//sgmPar.Llr, ìêÃí*10 -// param[307] = (unsigned short)(35810.);//sgmPar.Lm, ìêÃí -// -// // èíèöèàëèçàöèÿ ïðîãðàììû -// detcoeff(); -// -// // äëÿ ìîäåëèðîâàíèÿ òàéìåðîâ -// T1Pr = (double)EPwm1Regs.TBPRD; -// T2Pr = (double)EPwm2Regs.TBPRD; -// T3Pr = (double)EPwm3Regs.TBPRD; -// T4Pr = (double)EPwm4Regs.TBPRD; -// T5Pr = (double)EPwm5Regs.TBPRD; -// T6Pr = (double)EPwm6Regs.TBPRD; -// T7Pr = (double)EPwm7Regs.TBPRD; -// T8Pr = (double)EPwm8Regs.TBPRD; -// T9Pr = (double)EPwm9Regs.TBPRD; -// T10Pr = (double)EPwm10Regs.TBPRD; -// T11Pr = (double)EPwm11Regs.TBPRD; -// T12Pr = (double)EPwm12Regs.TBPRD; -// t1cntAux = (double)EPwm1Regs.TBCTR; -// t2cntAux = (double)EPwm2Regs.TBCTR; -// t3cntAux = (double)EPwm3Regs.TBCTR; -// t4cntAux = (double)EPwm4Regs.TBCTR; -// t5cntAux = (double)EPwm5Regs.TBCTR; -// t6cntAux = (double)EPwm6Regs.TBCTR; -// t7cntAux = (double)EPwm7Regs.TBCTR; -// t8cntAux = (double)EPwm8Regs.TBCTR; -// t9cntAux = (double)EPwm9Regs.TBCTR; -// t10cntAux = (double)EPwm10Regs.TBCTR; -// t11cntAux = (double)EPwm11Regs.TBCTR; -// t12cntAux = (double)EPwm12Regs.TBCTR; -// // ... ïðèðàùåíèå ñ÷¸ò÷èêîâ òàéìåðîâ çà øàã äèñêðåòèçàöèè -// TxCntPlus = FTBCLK*dt; -// -// // äëÿ ìîäåëèðîâàíèÿ eQEP -// Qposmax = (double)EQep2Regs.QPOSMAX; -// qposcnt = 1.;//(double)EQep2Regs.QPOSCNT; -// -// // äëÿ ìîäåëèðîâàíèÿ ÀÖÏ -// // (íà ñ÷¸ò 1e-6 ñì. SetupAdc(), õîòÿ òàì ñêîðåå íå 1.0 ìêñ, à 0.8 ìêñ) -//// Tadc = (int)(1e-6/dt); -// Tadc = (int)(1/FREQ_ADC_TIMER/dt); -// -// // ... íà âñÿêèé ñëó÷àé -// if ( Tadc < 1 ) -// Tadc = 1; -// tAdc = 1; -// // ... ÷òîáû ÀÖÏ æäàë çàïóñêà -// nAdc = 0; -// -// // äëÿ ìîäåëèðîâàíèÿ Dead-Band Unit -// CntDt = (int)(DT/dt); -// stateDt1 = stateDt2 = stateDt3 = stateDt4 = stateDt5 = stateDt6 = 1; -// stateDt7 = stateDt8 = stateDt9 = stateDt10 = stateDt11 = stateDt12 = 1; -// cntDt1 = cntDt2 = cntDt3 = cntDt4 = cntDt5 = cntDt6 = 0; -// cntDt7 = cntDt8 = cntDt9 = cntDt10 = cntDt11 = cntDt12 = 0; -// -// // äëÿ çàùèò -// DI_24V_SOURCE_FAULT = 0; -// -// // äëÿ âûâîäà -// inuWork = 0; -// ivc.psi = 0; -// rf.psiZ = 0; -// rs.wmZ = 0; -// csp.wmLimZi = 0; -// pm = 0; -// rp.pmZ = 0; -// csp.pmLimZi = 0; -// id1 = 0; -// iq1 = 0; -// id2 = 0; -// iq2 = 0; -// idZ = 0; -// iqZ = 0; -// cf.idP = 0; -// cf.idFF = 0; -// cf.idI = 0; -// csp.iqP = 0; -// csp.iqFF = 0; -// csp.iqI = 0; -// cc.yd1 = 0; -// cc.yq1 = 0; -// cc.y1 = 0; -// cc.y2 = 0; -// } //if ( iW[1] == 1 ) + + // êîå-÷òî âûïîëíÿåì îäèí ðàç ïðè çàïóñêå ìîäåëè + if ( iW[1] == 1 ) { + iW[1] = 0; + + init28335(); + } //if ( iW[1] == 1 ) } @@ -1338,6 +1191,9 @@ void writeOutputParameters(real_T *xD) { void controller(SimStruct *S, const real_T *u, real_T *xD, real_T *rW, int_T *iW) { + static _iq Uzad1 = 0, Fzad = 0, Uzad2 = 0, Izad_out = 0, Uzad_from_master = 0; + _iq wd; + readInputParameters(u); processSFunctionIfChanged(S, iW); initialisationOnStart(iW); @@ -1357,4 +1213,33 @@ void controller(SimStruct *S, const real_T *u, real_T *xD, real_T *rW, int_T *iW writeOutputParameters(xD); + if (edrk.flag_second_PCH == 0) { + wd = uf_alg.winding_displacement_bs1; + } + else { + wd = uf_alg.winding_displacement_bs2; + } + + vectorControlConstId(edrk.zadanie.iq_power_zad_rmp, edrk.zadanie.iq_oborots_zad_hz_rmp, + WRotor.RotorDirectionSlow, WRotor.iqWRotorSumFilter, + edrk.Mode_ScalarVectorUFConst, + edrk.MasterSlave, edrk.zadanie.iq_Izad, wd, + edrk.master_theta, edrk.master_Iq, edrk.iq_power_kw_another_bs, + &edrk.tetta_to_slave, &edrk.Iq_to_slave, &edrk.P_to_master, + 0, 1); + + test_calc_vect_dq_pwm24_Ing(vect_control.iqTheta, vect_control.iqUdKm, vect_control.iqUqKm, + edrk.disable_alg_u_disbalance, + edrk.zadanie.iq_kplus_u_disbalance_rmp, edrk.zadanie.iq_k_u_disbalance_rmp, + filter.iqU_1_fast, filter.iqU_2_fast, + 0, + edrk.Uzad_max, + edrk.MasterSlave, + edrk.flag_second_PCH, + &edrk.Kplus, &edrk.Uzad_to_slave); + analog.PowerFOC = edrk.P_to_master; + Fzad = vect_control.iqFstator; + Izad_out = edrk.Iq_to_slave; + + } //void controller(SimStruct ... diff --git a/Inu/controller.h b/Inu/controller.h index d59dfce..3db497d 100644 --- a/Inu/controller.h +++ b/Inu/controller.h @@ -1,3 +1,25 @@ +#include "wrapper_inu.h" +#include "def.h" +#include "edrk_main.h" +#include "vector.h" +#include "vector_control.h" +#include "adc_tools.h" +#include "uf_alg_ing.h" +#include "v_rotor.h" +#include "v_rotor_22220.h" +#include "v_pwm24_v2.h" +#include "control_station.h" + +#include +#include +#include +#include +#include +#include + +#ifndef __WRAPPER_CONTROLLER_H +#define __WRAPPER_CONTROLLER_H + // Ìàêñèìàëüíàÿ äëèíà ïàðàìåòðà-âåêòîðà #define LEN_PARAM_MATR 21 @@ -220,3 +242,5 @@ extern struct Ip ip; extern unsigned short param[]; //######################################################################### // Ïåðåìåííûå, êîòîðûå îáúÿâëåíû â controller.c (end) + +#endif //__WRAPPER_CONTROLLER_H \ No newline at end of file diff --git a/Inu/init28335.c b/Inu/init28335.c deleted file mode 100644 index 42dfaa5..0000000 --- a/Inu/init28335.c +++ /dev/null @@ -1,1621 +0,0 @@ -/************************************************************************** - Description: Ïîñëå çàãðóçêè ïðîöåññîðà ôóíêöèÿ âûçûâàåòñÿ îäèí ðàç - è èíèöèàëèçèðóåò óïðàâëÿþùèå ðåãèñòðû ïðîöåññîðà - TMS320F28335/TMS320F28379D. - - Àâòîð: Óëèòîâñêèé Ä.È. - Äàòà ïîñëåäíåãî îáíîâëåíèÿ: 2021.10.04 -**************************************************************************/ - - -#include "def.h" -#include "init28335.h" - - -#ifndef ML -extern void InitPll(Uint16 val, Uint16 divsel); -extern void InitPieCtrl(void); -extern void InitPieVectTable(void); -extern void ADC_cal(void); -extern void MemCopy(Uint16 *SourceAddr, Uint16* SourceEndAddr, Uint16* DestAddr); -extern void InitFlash(void); -extern short CsmUnlock(void); -void InitPeripheralClocks(void); -void SetupGpio(void); -extern interrupt void isr(void); -#endif //ML -void SetupAdc(void); -void SetupEpwm(void); -void SetupEqep(void); - - -void init28335(void) { -#ifndef ML - // Global Disable all Interrupts - DINT; - // Disable CPU interrupts - IER = 0x0000; - // Clear all CPU interrupt flags - IFR = 0x0000; - - // Initialize the PLL control: PLLCR[DIV] and PLLSTS[DIVSEL] - InitPll(PLLCR_DIV, PLLSTS_DIVSEL); - - // Initialize interrupt controller and Vector Table - // to defaults for now. Application ISR mapping done later. - InitPieCtrl(); - InitPieVectTable(); - - // Initialize the peripheral clocks - InitPeripheralClocks(); - - // Ulock the CSM - csmSuccess = CsmUnlock(); - - /* Copy time critical code and Flash setup code to RAM - (the RamfuncsLoadStart, RamfuncsLoadEnd, RamfuncsRunStart, - RamfuncsLoadStart2, RamfuncsLoadEnd2 and RamfuncsRunStart2 - symbols are created by the linker) */ - MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart); - MemCopy(&RamfuncsLoadStart2, &RamfuncsLoadEnd2, &RamfuncsRunStart2); - /* Copy the .switch section */ - // (the SwitchLoadStart, SwitchLoadEnd and SwitchRunStart - // symbols are created by the linker) - MemCopy(&SwitchLoadStart, &SwitchLoadEnd, &SwitchRunStart); - /* Copy the .econst section */ - // (the EconstLoadStart, EconstLoadEnd and EconstRunStart - // symbols are created by the linker) - MemCopy(&EconstLoadStart, &EconstLoadEnd, &EconstRunStart); - // Call Flash Initialization to setup flash waitstates - // (this function must reside in RAM) - InitFlash(); -#endif //ML - - // Setup ePWM - SetupEpwm(); - // Setup ADC - SetupAdc(); - // Setup eQEP - SetupEqep(); - -#ifndef ML - // Setup GPIO - SetupGpio(); - - // Reassign ISR - EALLOW; - PieVectTable.ADCINT = &isr; - EDIS; -#endif //ML -} //void init28335(void) - - - -#ifndef ML -/* This function initializes the clocks to the peripheral modules. -First the high and low clock prescalers are set -Second the clocks are enabled to each peripheral. -To reduce power, leave clocks to unused peripherals disabled - -Note: If a peripherals clock is not enabled then you cannot -read or write to the registers for that peripheral */ -void InitPeripheralClocks(void) { - EALLOW; - - // HISPCP/LOSPCP prescale register settings, normally it will be set - // to default values - // High speed clock = FSYSCLKOUT/2 - SysCtrlRegs.HISPCP.all = 0x0001; - // Low speed clock = FSYSCLKOUT/4 - SysCtrlRegs.LOSPCP.all = 0x0002; - - /* Peripheral clock enables set for the selected peripherals. - If you are not using a peripheral leave the clock off - to save on power. - - This function is not written to be an example of efficient code */ - - SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC - - /* IMPORTANT - The ADC_cal function, which copies the ADC calibration values from - TI reserved OTP into the ADCREFSEL and ADCOFFTRIM registers, occurs - automatically in the Boot ROM. If the boot ROM code is bypassed - during the debug process, the following function MUST be called for - the ADC to function according to specification. The clocks to the - ADC MUST be enabled before calling this function. - See the device data manual and/or the ADC Reference - Manual for more information */ - ADC_cal(); - - SysCtrlRegs.PCLKCR0.bit.I2CAENCLK = 0; // I2C - SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 0; // SCI-A - SysCtrlRegs.PCLKCR0.bit.SCIBENCLK = 0; // SCI-B - SysCtrlRegs.PCLKCR0.bit.SCICENCLK = 0; // SCI-C - SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 0; // SPI-A - SysCtrlRegs.PCLKCR0.bit.MCBSPAENCLK = 0;// McBSP-A - SysCtrlRegs.PCLKCR0.bit.MCBSPBENCLK = 0;// McBSP-B - SysCtrlRegs.PCLKCR0.bit.ECANAENCLK = 0; // eCAN-A - SysCtrlRegs.PCLKCR0.bit.ECANBENCLK = 0; // eCAN-B - - SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the ePWM - SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // ePWM1 - SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1; // ePWM2 - SysCtrlRegs.PCLKCR1.bit.EPWM3ENCLK = 1; // ePWM3 - SysCtrlRegs.PCLKCR1.bit.EPWM4ENCLK = 1; // ePWM4 - SysCtrlRegs.PCLKCR1.bit.EPWM5ENCLK = 1; // ePWM5 - SysCtrlRegs.PCLKCR1.bit.EPWM6ENCLK = 1; // ePWM6 - SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK within the ePWM - - SysCtrlRegs.PCLKCR1.bit.ECAP3ENCLK = 0; // eCAP3 - SysCtrlRegs.PCLKCR1.bit.ECAP4ENCLK = 0; // eCAP4 - SysCtrlRegs.PCLKCR1.bit.ECAP5ENCLK = 0; // eCAP5 - SysCtrlRegs.PCLKCR1.bit.ECAP6ENCLK = 0; // eCAP6 - SysCtrlRegs.PCLKCR1.bit.ECAP1ENCLK = 0; // eCAP1 - SysCtrlRegs.PCLKCR1.bit.ECAP2ENCLK = 0; // eCAP2 - SysCtrlRegs.PCLKCR1.bit.EQEP1ENCLK = 0; // eQEP1 - SysCtrlRegs.PCLKCR1.bit.EQEP2ENCLK = 1; // eQEP2 - - SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 0; // CPU Timer 0 - SysCtrlRegs.PCLKCR3.bit.CPUTIMER1ENCLK = 0; // CPU Timer 1 - SysCtrlRegs.PCLKCR3.bit.CPUTIMER2ENCLK = 0; // CPU Timer 2 - - SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 0; // DMA Clock - SysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1; // XTIMCLK - SysCtrlRegs.PCLKCR3.bit.GPIOINENCLK = 1; // GPIO input clock - - EDIS; -} //void InitPeripheralClocks(void) - - - -// Íàñòðàèâàåò GPIO -void SetupGpio(void) { - EALLOW; - // GPIO and Peripheral Multiplexing - // GPIO0 ... GPIO15 - GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;//EPWM1A (INU) - GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;//EPWM1B (INU) - GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1;//EPWM2A (INU) - GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1;//EPWM2B (INU) - GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 1;//EPWM3A (INU) - GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 1;//EPWM3B (INU) - GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 1;//EPWM4A (INU) - GpioCtrlRegs.GPAMUX1.bit.GPIO7 = 1;//EPWM4B (INU) - GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 1;//EPWM5A (INU) - GpioCtrlRegs.GPAMUX1.bit.GPIO9 = 1;//EPWM5B (INU) - GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 1;//EPWM6A (INU) - GpioCtrlRegs.GPAMUX1.bit.GPIO11 = 1;//EPWM6B (INU) - GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 0;//DI - GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 0;//DO - GpioCtrlRegs.GPAMUX1.bit.GPIO14 = 0;//DI - GpioCtrlRegs.GPAMUX1.bit.GPIO15 = 0;//DO - // GPIO16 ... GPIO31 - GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 0;//DI - GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 0;//DO - GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 0;//DI - GpioCtrlRegs.GPAMUX2.bit.GPIO19 = 0;//DO - GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 0;//DO - GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 0;//DI - GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 3;//SCITXDB - GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 3;//SCIRXDB - GpioCtrlRegs.GPAMUX2.bit.GPIO24 = 2;//EQEP2A - GpioCtrlRegs.GPAMUX2.bit.GPIO25 = 2;//EQEP2B - GpioCtrlRegs.GPAMUX2.bit.GPIO26 = 2;//EQEP2I - GpioCtrlRegs.GPAMUX2.bit.GPIO27 = 0;//DI - GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1;//SCIRXDA - GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 1;//SCITXDA - GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 0;//DO - GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 3;//XA17 - // GPIO32 ... GPIO47 - GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 2;//EPWMSYNCI - GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 2;//EPWMSYNCO - GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;//DO - GpioCtrlRegs.GPBMUX1.bit.GPIO35 = 0;//DO - GpioCtrlRegs.GPBMUX1.bit.GPIO36 = 3;//XZCS0 - GpioCtrlRegs.GPBMUX1.bit.GPIO37 = 3;//XZCS7 - GpioCtrlRegs.GPBMUX1.bit.GPIO38 = 3;//XWE0 - GpioCtrlRegs.GPBMUX1.bit.GPIO39 = 3;//XA16 - GpioCtrlRegs.GPBMUX1.bit.GPIO40 = 3;//XA0/XWE1 - GpioCtrlRegs.GPBMUX1.bit.GPIO41 = 3;//XA1 - GpioCtrlRegs.GPBMUX1.bit.GPIO42 = 3;//XA2 - GpioCtrlRegs.GPBMUX1.bit.GPIO43 = 3;//XA3 - GpioCtrlRegs.GPBMUX1.bit.GPIO44 = 3;//XA4 - GpioCtrlRegs.GPBMUX1.bit.GPIO45 = 3;//XA5 - GpioCtrlRegs.GPBMUX1.bit.GPIO46 = 3;//XA6 - GpioCtrlRegs.GPBMUX1.bit.GPIO47 = 3;//XA7 - // GPIO48 ... GPIO63 - GpioCtrlRegs.GPBMUX2.bit.GPIO48 = 0;//DO - GpioCtrlRegs.GPBMUX2.bit.GPIO49 = 0;//DO - GpioCtrlRegs.GPBMUX2.bit.GPIO50 = 0;//DI (íåèñïðàâíîñòü èñòî÷íèêà ïèòàíèÿ +24 Â) - GpioCtrlRegs.GPBMUX2.bit.GPIO51 = 0;//DI - GpioCtrlRegs.GPBMUX2.bit.GPIO52 = 0;//DI - GpioCtrlRegs.GPBMUX2.bit.GPIO53 = 0;//DI - GpioCtrlRegs.GPBMUX2.bit.GPIO54 = 1;//SPISIMOA - GpioCtrlRegs.GPBMUX2.bit.GPIO55 = 1;//SPISOMIA - GpioCtrlRegs.GPBMUX2.bit.GPIO56 = 1;//SPICLKA - GpioCtrlRegs.GPBMUX2.bit.GPIO57 = 0;//DO - GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 0;//DO - GpioCtrlRegs.GPBMUX2.bit.GPIO59 = 0;//DO (çåëåíûé ñâåòîäèîä "Ãîòîâíîñòü") - GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 0;//DO (çåëåíûé ñâåòîäèîä "Ðàáîòà") - GpioCtrlRegs.GPBMUX2.bit.GPIO61 = 0;//DO (êðàñíûé ñâåòîäèîä "Àâàðèÿ") - GpioCtrlRegs.GPBMUX2.bit.GPIO62 = 1;//SCIRXDC - GpioCtrlRegs.GPBMUX2.bit.GPIO63 = 1;//SCITXDC - // GPIO64 ... GPIO79 - GpioCtrlRegs.GPCMUX1.bit.GPIO64 = 3;//XD15 - GpioCtrlRegs.GPCMUX1.bit.GPIO65 = 3;//XD14 - GpioCtrlRegs.GPCMUX1.bit.GPIO66 = 3;//XD13 - GpioCtrlRegs.GPCMUX1.bit.GPIO67 = 3;//XD12 - GpioCtrlRegs.GPCMUX1.bit.GPIO68 = 3;//XD11 - GpioCtrlRegs.GPCMUX1.bit.GPIO69 = 3;//XD10 - GpioCtrlRegs.GPCMUX1.bit.GPIO70 = 3;//XD9 - GpioCtrlRegs.GPCMUX1.bit.GPIO71 = 3;//XD8 - GpioCtrlRegs.GPCMUX1.bit.GPIO72 = 3;//XD7 - GpioCtrlRegs.GPCMUX1.bit.GPIO73 = 3;//XD6 - GpioCtrlRegs.GPCMUX1.bit.GPIO74 = 3;//XD5 - GpioCtrlRegs.GPCMUX1.bit.GPIO75 = 3;//XD4 - GpioCtrlRegs.GPCMUX1.bit.GPIO76 = 3;//XD3 - GpioCtrlRegs.GPCMUX1.bit.GPIO77 = 3;//XD2 - GpioCtrlRegs.GPCMUX1.bit.GPIO78 = 3;//XD1 - GpioCtrlRegs.GPCMUX1.bit.GPIO79 = 3;//XD0 - // GPIO80 ... GPIO87 - GpioCtrlRegs.GPCMUX2.bit.GPIO80 = 3;//XA8 - GpioCtrlRegs.GPCMUX2.bit.GPIO81 = 3;//XA9 - GpioCtrlRegs.GPCMUX2.bit.GPIO82 = 3;//XA10 - GpioCtrlRegs.GPCMUX2.bit.GPIO83 = 3;//XA11 - GpioCtrlRegs.GPCMUX2.bit.GPIO84 = 3;//XA12 - GpioCtrlRegs.GPCMUX2.bit.GPIO85 = 3;//XA13 - GpioCtrlRegs.GPCMUX2.bit.GPIO86 = 3;//XA14 - GpioCtrlRegs.GPCMUX2.bit.GPIO87 = 3;//XA15 - - // âûáèðàåì ñîñòîÿíèå öèôðîâûõ âûõîäîâ - DO_GPIO019_CLEAR; - DO_GPIO020_CLEAR; - DO_GPIO022_CLEAR; - // ... ñâåòîäèîäû âûêëþ÷àåì - LED_GREEN1_OFF; - LED_GREEN2_OFF; - LED_RED_OFF; - DO_GPIO63_CLEAR; - - // Select the direction of the GPIO pins - // GPIO0 ... GPIO31 - GpioCtrlRegs.GPADIR.bit.GPIO0 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO1 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO2 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO3 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO4 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO5 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO6 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO7 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO8 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO9 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO10 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO11 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO12 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO13 = 1; - GpioCtrlRegs.GPADIR.bit.GPIO14 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO15 = 1; - GpioCtrlRegs.GPADIR.bit.GPIO16 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO17 = 1; - GpioCtrlRegs.GPADIR.bit.GPIO18 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO19 = 1; - GpioCtrlRegs.GPADIR.bit.GPIO20 = 1; - GpioCtrlRegs.GPADIR.bit.GPIO21 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO22 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO23 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO24 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO25 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO26 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO27 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO28 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO29 = 0; - GpioCtrlRegs.GPADIR.bit.GPIO30 = 1; - GpioCtrlRegs.GPADIR.bit.GPIO31 = 0; - // GPIO32 ... GPIO63 - GpioCtrlRegs.GPBDIR.bit.GPIO32 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO33 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; - GpioCtrlRegs.GPBDIR.bit.GPIO35 = 1; - GpioCtrlRegs.GPBDIR.bit.GPIO36 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO37 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO38 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO39 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO40 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO41 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO42 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO43 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO44 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO45 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO46 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO47 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO48 = 1; - GpioCtrlRegs.GPBDIR.bit.GPIO49 = 1; - GpioCtrlRegs.GPBDIR.bit.GPIO50 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO51 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO52 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO53 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO54 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO55 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO56 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO57 = 1; - GpioCtrlRegs.GPBDIR.bit.GPIO58 = 1; - GpioCtrlRegs.GPBDIR.bit.GPIO59 = 1; - GpioCtrlRegs.GPBDIR.bit.GPIO60 = 1; - GpioCtrlRegs.GPBDIR.bit.GPIO61 = 1; - GpioCtrlRegs.GPBDIR.bit.GPIO62 = 0; - GpioCtrlRegs.GPBDIR.bit.GPIO63 = 1; - // GPIO64 ... GPIO87 - GpioCtrlRegs.GPCDIR.bit.GPIO64 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO65 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO66 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO67 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO68 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO69 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO70 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO71 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO72 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO73 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO74 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO75 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO76 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO77 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO78 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO79 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO80 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO81 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO82 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO83 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO84 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO85 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO86 = 0; - GpioCtrlRegs.GPCDIR.bit.GPIO87 = 0; - - // Each input can have different qualification: - // 0 - Synchronize to FSYSCLKOUT only; - // 1 - Qualification using 3 samples; - // 2 - Qualification using 6 samples; - // 3 - Asynchronous. - // GPIO0 ... GPIO15 - GpioCtrlRegs.GPAQSEL1.bit.GPIO0 = 0; - GpioCtrlRegs.GPAQSEL1.bit.GPIO1 = 0; - GpioCtrlRegs.GPAQSEL1.bit.GPIO2 = 0; - GpioCtrlRegs.GPAQSEL1.bit.GPIO3 = 0; - GpioCtrlRegs.GPAQSEL1.bit.GPIO4 = 0; - GpioCtrlRegs.GPAQSEL1.bit.GPIO5 = 0; - GpioCtrlRegs.GPAQSEL1.bit.GPIO6 = 0; - GpioCtrlRegs.GPAQSEL1.bit.GPIO7 = 0; - GpioCtrlRegs.GPAQSEL1.bit.GPIO8 = 0; - GpioCtrlRegs.GPAQSEL1.bit.GPIO9 = 0; - GpioCtrlRegs.GPAQSEL1.bit.GPIO10 = 0; - GpioCtrlRegs.GPAQSEL1.bit.GPIO11 = 0; - GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 2; - GpioCtrlRegs.GPAQSEL1.bit.GPIO13 = 0; - GpioCtrlRegs.GPAQSEL1.bit.GPIO14 = 2; - GpioCtrlRegs.GPAQSEL1.bit.GPIO15 = 0; - // GPIO16 ... GPIO31 - GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 2; - GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 0; - GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 2; - GpioCtrlRegs.GPAQSEL2.bit.GPIO19 = 0; - GpioCtrlRegs.GPAQSEL2.bit.GPIO20 = 0; - GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 2; - GpioCtrlRegs.GPAQSEL2.bit.GPIO22 = 3; - GpioCtrlRegs.GPAQSEL2.bit.GPIO23 = 3; - GpioCtrlRegs.GPAQSEL2.bit.GPIO24 = 0; - GpioCtrlRegs.GPAQSEL2.bit.GPIO25 = 0; - GpioCtrlRegs.GPAQSEL2.bit.GPIO26 = 0; - GpioCtrlRegs.GPAQSEL2.bit.GPIO27 = 2; - GpioCtrlRegs.GPAQSEL2.bit.GPIO28 = 3; - GpioCtrlRegs.GPAQSEL2.bit.GPIO29 = 3; - GpioCtrlRegs.GPAQSEL2.bit.GPIO30 = 0; - GpioCtrlRegs.GPAQSEL2.bit.GPIO31 = 0; - // GPIO32 ... GPIO47 - GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 0; - GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 0; - GpioCtrlRegs.GPBQSEL1.bit.GPIO34 = 0; - GpioCtrlRegs.GPBQSEL1.bit.GPIO35 = 0; - GpioCtrlRegs.GPBQSEL1.bit.GPIO36 = 0; - GpioCtrlRegs.GPBQSEL1.bit.GPIO37 = 0; - GpioCtrlRegs.GPBQSEL1.bit.GPIO38 = 0; - GpioCtrlRegs.GPBQSEL1.bit.GPIO39 = 0; - GpioCtrlRegs.GPBQSEL1.bit.GPIO40 = 0; - GpioCtrlRegs.GPBQSEL1.bit.GPIO41 = 0; - GpioCtrlRegs.GPBQSEL1.bit.GPIO42 = 0; - GpioCtrlRegs.GPBQSEL1.bit.GPIO43 = 0; - GpioCtrlRegs.GPBQSEL1.bit.GPIO44 = 0; - GpioCtrlRegs.GPBQSEL1.bit.GPIO45 = 0; - GpioCtrlRegs.GPBQSEL1.bit.GPIO46 = 0; - GpioCtrlRegs.GPBQSEL1.bit.GPIO47 = 0; - // GPIO48 ... GPIO63 - GpioCtrlRegs.GPBQSEL2.bit.GPIO48 = 0; - GpioCtrlRegs.GPBQSEL2.bit.GPIO49 = 0; - GpioCtrlRegs.GPBQSEL2.bit.GPIO50 = 2; - GpioCtrlRegs.GPBQSEL2.bit.GPIO51 = 2; - GpioCtrlRegs.GPBQSEL2.bit.GPIO52 = 2; - GpioCtrlRegs.GPBQSEL2.bit.GPIO53 = 2; - GpioCtrlRegs.GPBQSEL2.bit.GPIO54 = 3; - GpioCtrlRegs.GPBQSEL2.bit.GPIO55 = 3; - GpioCtrlRegs.GPBQSEL2.bit.GPIO56 = 3; - GpioCtrlRegs.GPBQSEL2.bit.GPIO57 = 3; - GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 0; - GpioCtrlRegs.GPBQSEL2.bit.GPIO59 = 0; - GpioCtrlRegs.GPBQSEL2.bit.GPIO60 = 0; - GpioCtrlRegs.GPBQSEL2.bit.GPIO61 = 0; - GpioCtrlRegs.GPBQSEL2.bit.GPIO62 = 2; - GpioCtrlRegs.GPBQSEL2.bit.GPIO63 = 0; - - // Qualification Control (sampling period = (1/FSYSCLKOUT)*QUALPRDx*2) - // ( (1/150e6)*255*2 = 3.4 ìêñ ) - // Port A - GpioCtrlRegs.GPACTRL.bit.QUALPRD0 = 255;//GPIO0 ... GPIO7 - GpioCtrlRegs.GPACTRL.bit.QUALPRD1 = 255;//GPIO8 ... GPIO15 - GpioCtrlRegs.GPACTRL.bit.QUALPRD2 = 255;//GPIO16 ... GPIO23 - GpioCtrlRegs.GPACTRL.bit.QUALPRD3 = 255;//GPIO24 ... GPIO31 - // Port B - GpioCtrlRegs.GPBCTRL.bit.QUALPRD0 = 255;//GPIO32 ... GPIO39 - GpioCtrlRegs.GPBCTRL.bit.QUALPRD1 = 255;//GPIO40 ... GPIO47 - GpioCtrlRegs.GPBCTRL.bit.QUALPRD2 = 255;//GPIO48 ... GPIO55 - GpioCtrlRegs.GPBCTRL.bit.QUALPRD3 = 255;//GPIO56 ... GPIO63 - - // Pull-ups (the internal pullup çàïðåù¸í äëÿ ØÈÌ-âûõîäîâ) - // GPIO0 ... GPIO31 - GpioCtrlRegs.GPAPUD.all = 0x00000FFF; - // GPIO32 ... GPIO63 - GpioCtrlRegs.GPBPUD.all = 0x00000000; - // GPIO64 ... GPIO87 - GpioCtrlRegs.GPCPUD.all = 0x00000000; - EDIS; -} //void SetupGpio(void) -#endif //ML - - - -// Íàñòðàèâàåò ePWM -void SetupEpwm(void) { - // ePWM1 - // #################################################################### - // Time-Base (TB) Submodule - // -------------------------------------------------------------------- - // Time-Base Control Register - EPwm1Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement - EPwm1Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event - EPwm1Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm1Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm1Regs.TBCTL.bit.SYNCOSEL = 1;//TBCTR==0 -> EPWMxSYNCO - EPwm1Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register - EPwm1Regs.TBCTL.bit.PHSEN = 0;//do not load TBCTR from TBPHS - EPwm1Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation - // Time-Base Period Register - EPwm1Regs.TBPRD = (unsigned short)T1_PRD; - // Time-Base Phase Register - EPwm1Regs.TBPHS.half.TBPHS = 0; - // Time-Base Counter Register - EPwm1Regs.TBCTR = 1; - // Counter-Compare (CC) Submodule - // -------------------------------------------------------------------- - // Counter-Compare A Register - EPwm1Regs.CMPA.half.CMPA = 0; - // Counter-Compare B Register - EPwm1Regs.CMPB = 0; - // Counter-Compare Control Register - EPwm1Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow - EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow - EPwm1Regs.CMPCTL.bit.LOADBMODE = 0;//active CMPB load from shadow - load on CTR = Zero - EPwm1Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD - // Action-Qualifier (AQ) Submodule - // -------------------------------------------------------------------- - // Action-Qualifier Output A Control Register - EPwm1Regs.AQCTLA.bit.CBD = 0;//do nothing - EPwm1Regs.AQCTLA.bit.CBU = 0;//do nothing - EPwm1Regs.AQCTLA.bit.CAD = 2;//set - force EPWMxA output high - EPwm1Regs.AQCTLA.bit.CAU = 1;//clear - force EPWMxA output low - EPwm1Regs.AQCTLA.bit.PRD = 0;//do nothing - EPwm1Regs.AQCTLA.bit.ZRO = 0;//do nothing - // Action-Qualifier Output B Control Register - EPwm1Regs.AQCTLB.bit.CBD = 0;//do nothing - EPwm1Regs.AQCTLB.bit.CBU = 0;//do nothing - EPwm1Regs.AQCTLB.bit.CAD = 0;//do nothing - EPwm1Regs.AQCTLB.bit.CAU = 0;//do nothing - EPwm1Regs.AQCTLB.bit.PRD = 0;//do nothing - EPwm1Regs.AQCTLB.bit.ZRO = 0;//do nothing - // Action-Qualifier Software Force Register - EPwm1Regs.AQSFRC.all = 0; - // Action-Qualifier Continuous Software Force Register - EPwm1Regs.AQCSFRC.all = 0; - // Dead-Band Generator (DB) Submodule - // -------------------------------------------------------------------- - // Dead-Band Generator Control Register - EPwm1Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay - EPwm1Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode - EPwm1Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB - // Dead-Band Generator Rising Edge Delay Register - EPwm1Regs.DBRED = (unsigned short)(FTBCLK*DT); - // Dead-Band Generator Falling Edge Delay Register - EPwm1Regs.DBFED = (unsigned short)(FTBCLK*DT); - // PWM-Chopper (PC) Submodule - // -------------------------------------------------------------------- - // PWM-Chopper Control Register - EPwm1Regs.PCCTL.all = 0; - // Trip-Zone (TZ) Submodule - // -------------------------------------------------------------------- - EALLOW; - // Trip-Zone Select Register - EPwm1Regs.TZSEL.all = 0; - // Trip-Zone Control Register - EPwm1Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state - EPwm1Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state - // Trip-Zone Enable Interrupt Register - EPwm1Regs.TZEINT.all = 0; - // Trip-Zone Force Register - EPwm1Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit - EDIS; - // Event-Trigger (ET) Submodule - // -------------------------------------------------------------------- - // Event-Trigger Selection Register - EPwm1Regs.ETSEL.bit.SOCBEN = 1;//enable EPWMxSOCB pulse - EPwm1Regs.ETSEL.bit.SOCBSEL = 1;//EPWMxSOCB selection - enable event CTR == 0 - EPwm1Regs.ETSEL.bit.SOCAEN = 1;//enable EPWMxSOCA pulse - EPwm1Regs.ETSEL.bit.SOCASEL = 2;//EPWMxSOCA selection - enable event CTR == PRD - EPwm1Regs.ETSEL.bit.INTEN = 0;//disable EPWMx_INT generation - EPwm1Regs.ETSEL.bit.INTSEL = 0;//reserved - // Event-Trigger Prescale Register - EPwm1Regs.ETPS.bit.SOCBPRD = 1;//generate the EPWMxSOCB pulse on the first event - EPwm1Regs.ETPS.bit.SOCAPRD = 1;//generate the EPWMxSOCA pulse on the first event - EPwm1Regs.ETPS.bit.INTPRD = 0;//disable the interrupt event counter (no interrupt will be generated) - - // ePWM2 - // #################################################################### - // Time-Base (TB) Submodule - // -------------------------------------------------------------------- - // Time-Base Control Register - EPwm2Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement - EPwm2Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event - EPwm2Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm2Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm2Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI - EPwm2Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register - EPwm2Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs - EPwm2Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation - // Time-Base Period Register - EPwm2Regs.TBPRD = (unsigned short)T1_PRD; - // Time-Base Phase Register - EPwm2Regs.TBPHS.half.TBPHS = 2; - // Time-Base Counter Register - EPwm2Regs.TBCTR = 1; - // Counter-Compare (CC) Submodule - // -------------------------------------------------------------------- - // Counter-Compare A Register - EPwm2Regs.CMPA.half.CMPA = 0; - // Counter-Compare B Register - EPwm2Regs.CMPB = 0; - // Counter-Compare Control Register - EPwm2Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow - EPwm2Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow - EPwm2Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode - EPwm2Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD - // Action-Qualifier (AQ) Submodule - // -------------------------------------------------------------------- - // Action-Qualifier Output A Control Register - EPwm2Regs.AQCTLA.bit.CBD = 0;//do nothing - EPwm2Regs.AQCTLA.bit.CBU = 0;//do nothing - EPwm2Regs.AQCTLA.bit.CAD = 1;//clear - force EPWMxA output low - EPwm2Regs.AQCTLA.bit.CAU = 2;//set - force EPWMxA output high - EPwm2Regs.AQCTLA.bit.PRD = 0;//do nothing - EPwm2Regs.AQCTLA.bit.ZRO = 0;//do nothing - // Action-Qualifier Output B Control Register - EPwm2Regs.AQCTLB.bit.CBD = 0;//do nothing - EPwm2Regs.AQCTLB.bit.CBU = 0;//do nothing - EPwm2Regs.AQCTLB.bit.CAD = 0;//do nothing - EPwm2Regs.AQCTLB.bit.CAU = 0;//do nothing - EPwm2Regs.AQCTLB.bit.PRD = 0;//do nothing - EPwm2Regs.AQCTLB.bit.ZRO = 0;//do nothing - // Action-Qualifier Software Force Register - EPwm2Regs.AQSFRC.all = 0; - // Action-Qualifier Continuous Software Force Register - EPwm2Regs.AQCSFRC.all = 0; - // Dead-Band Generator (DB) Submodule - // -------------------------------------------------------------------- - // Dead-Band Generator Control Register - EPwm2Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay - EPwm2Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode - EPwm2Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB - // Dead-Band Generator Rising Edge Delay Register - EPwm2Regs.DBRED = (unsigned short)(FTBCLK*DT); - // Dead-Band Generator Falling Edge Delay Register - EPwm2Regs.DBFED = (unsigned short)(FTBCLK*DT); - // PWM-Chopper (PC) Submodule - // -------------------------------------------------------------------- - // PWM-Chopper Control Register - EPwm2Regs.PCCTL.all = 0; - // Trip-Zone (TZ) Submodule - // -------------------------------------------------------------------- - EALLOW; - // Trip-Zone Select Register - EPwm2Regs.TZSEL.all = 0; - // Trip-Zone Control Register - EPwm2Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state - EPwm2Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state - // Trip-Zone Enable Interrupt Register - EPwm2Regs.TZEINT.all = 0; - // Trip-Zone Force Register - EPwm2Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit - EDIS; - // Event-Trigger (ET) Submodule - // -------------------------------------------------------------------- - // Event-Trigger Selection Register - EPwm2Regs.ETSEL.all = 0; - // Event-Trigger Prescale Register - EPwm2Regs.ETPS.all = 0; - - // ePWM3 - // #################################################################### - // Time-Base (TB) Submodule - // -------------------------------------------------------------------- - // Time-Base Control Register - EPwm3Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement - EPwm3Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event - EPwm3Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm3Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm3Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI - EPwm3Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register - EPwm3Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs - EPwm3Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation - // Time-Base Period Register - EPwm3Regs.TBPRD = (unsigned short)T1_PRD; - // Time-Base Phase Register - EPwm3Regs.TBPHS.half.TBPHS = 2; - // Time-Base Counter Register - EPwm3Regs.TBCTR = 1; - // Counter-Compare (CC) Submodule - // -------------------------------------------------------------------- - // Counter-Compare A Register - EPwm3Regs.CMPA.half.CMPA = 0; - // Counter-Compare B Register - EPwm3Regs.CMPB = 0; - // Counter-Compare Control Register - EPwm3Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow - EPwm3Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow - EPwm3Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode - EPwm3Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD - // Action-Qualifier (AQ) Submodule - // -------------------------------------------------------------------- - // Action-Qualifier Output A Control Register - EPwm3Regs.AQCTLA.bit.CBD = 0;//do nothing - EPwm3Regs.AQCTLA.bit.CBU = 0;//do nothing - EPwm3Regs.AQCTLA.bit.CAD = 2;//set - force EPWMxA output high - EPwm3Regs.AQCTLA.bit.CAU = 1;//clear - force EPWMxA output low - EPwm3Regs.AQCTLA.bit.PRD = 0;//do nothing - EPwm3Regs.AQCTLA.bit.ZRO = 0;//do nothing - // Action-Qualifier Output B Control Register - EPwm3Regs.AQCTLB.bit.CBD = 0;//do nothing - EPwm3Regs.AQCTLB.bit.CBU = 0;//do nothing - EPwm3Regs.AQCTLB.bit.CAD = 0;//do nothing - EPwm3Regs.AQCTLB.bit.CAU = 0;//do nothing - EPwm3Regs.AQCTLB.bit.PRD = 0;//do nothing - EPwm3Regs.AQCTLB.bit.ZRO = 0;//do nothing - // Action-Qualifier Software Force Register - EPwm3Regs.AQSFRC.all = 0; - // Action-Qualifier Continuous Software Force Register - EPwm3Regs.AQCSFRC.all = 0; - // Dead-Band Generator (DB) Submodule - // -------------------------------------------------------------------- - // Dead-Band Generator Control Register - EPwm3Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay - EPwm3Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode - EPwm3Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB - // Dead-Band Generator Rising Edge Delay Register - EPwm3Regs.DBRED = (unsigned short)(FTBCLK*DT); - // Dead-Band Generator Falling Edge Delay Register - EPwm3Regs.DBFED = (unsigned short)(FTBCLK*DT); - // PWM-Chopper (PC) Submodule - // -------------------------------------------------------------------- - // PWM-Chopper Control Register - EPwm3Regs.PCCTL.all = 0; - // Trip-Zone (TZ) Submodule - // -------------------------------------------------------------------- - EALLOW; - // Trip-Zone Select Register - EPwm3Regs.TZSEL.all = 0; - // Trip-Zone Control Register - EPwm3Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state - EPwm3Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state - // Trip-Zone Enable Interrupt Register - EPwm3Regs.TZEINT.all = 0; - // Trip-Zone Force Register - EPwm3Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit - EDIS; - // Event-Trigger (ET) Submodule - // -------------------------------------------------------------------- - // Event-Trigger Selection Register - EPwm3Regs.ETSEL.all = 0; - // Event-Trigger Prescale Register - EPwm3Regs.ETPS.all = 0; - - // ePWM4 - // #################################################################### - // Time-Base (TB) Submodule - // -------------------------------------------------------------------- - // Time-Base Control Register - EPwm4Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement - EPwm4Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event - EPwm4Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm4Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm4Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI - EPwm4Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register - EPwm4Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs - EPwm4Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation - // Time-Base Period Register - EPwm4Regs.TBPRD = (unsigned short)T1_PRD; - // Time-Base Phase Register - EPwm4Regs.TBPHS.half.TBPHS = 2; - // Time-Base Counter Register - EPwm4Regs.TBCTR = 1; - // Counter-Compare (CC) Submodule - // -------------------------------------------------------------------- - // Counter-Compare A Register - EPwm4Regs.CMPA.half.CMPA = 0; - // Counter-Compare B Register - EPwm4Regs.CMPB = 0; - // Counter-Compare Control Register - EPwm4Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow - EPwm4Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow - EPwm4Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode - EPwm4Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD - // Action-Qualifier (AQ) Submodule - // -------------------------------------------------------------------- - // Action-Qualifier Output A Control Register - EPwm4Regs.AQCTLA.bit.CBD = 0;//do nothing - EPwm4Regs.AQCTLA.bit.CBU = 0;//do nothing - EPwm4Regs.AQCTLA.bit.CAD = 1;//clear - force EPWMxA output low - EPwm4Regs.AQCTLA.bit.CAU = 2;//set - force EPWMxA output high - EPwm4Regs.AQCTLA.bit.PRD = 0;//do nothing - EPwm4Regs.AQCTLA.bit.ZRO = 0;//do nothing - // Action-Qualifier Output B Control Register - EPwm4Regs.AQCTLB.bit.CBD = 0;//do nothing - EPwm4Regs.AQCTLB.bit.CBU = 0;//do nothing - EPwm4Regs.AQCTLB.bit.CAD = 0;//do nothing - EPwm4Regs.AQCTLB.bit.CAU = 0;//do nothing - EPwm4Regs.AQCTLB.bit.PRD = 0;//do nothing - EPwm4Regs.AQCTLB.bit.ZRO = 0;//do nothing - // Action-Qualifier Software Force Register - EPwm4Regs.AQSFRC.all = 0; - // Action-Qualifier Continuous Software Force Register - EPwm4Regs.AQCSFRC.all = 0; - // Dead-Band Generator (DB) Submodule - // -------------------------------------------------------------------- - // Dead-Band Generator Control Register - EPwm4Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay - EPwm4Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode - EPwm4Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB - // Dead-Band Generator Rising Edge Delay Register - EPwm4Regs.DBRED = (unsigned short)(FTBCLK*DT); - // Dead-Band Generator Falling Edge Delay Register - EPwm4Regs.DBFED = (unsigned short)(FTBCLK*DT); - // PWM-Chopper (PC) Submodule - // -------------------------------------------------------------------- - // PWM-Chopper Control Register - EPwm4Regs.PCCTL.all = 0; - // Trip-Zone (TZ) Submodule - // -------------------------------------------------------------------- - EALLOW; - // Trip-Zone Select Register - EPwm4Regs.TZSEL.all = 0; - // Trip-Zone Control Register - EPwm4Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state - EPwm4Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state - // Trip-Zone Enable Interrupt Register - EPwm4Regs.TZEINT.all = 0; - // Trip-Zone Force Register - EPwm4Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit - EDIS; - // Event-Trigger (ET) Submodule - // -------------------------------------------------------------------- - // Event-Trigger Selection Register - EPwm4Regs.ETSEL.all = 0; - // Event-Trigger Prescale Register - EPwm4Regs.ETPS.all = 0; - - // ePWM5 - // #################################################################### - // Time-Base (TB) Submodule - // -------------------------------------------------------------------- - // Time-Base Control Register - EPwm5Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement - EPwm5Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event - EPwm5Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm5Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm5Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI - EPwm5Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register - EPwm5Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs - EPwm5Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation - // Time-Base Period Register - EPwm5Regs.TBPRD = (unsigned short)T1_PRD; - // Time-Base Phase Register - EPwm5Regs.TBPHS.half.TBPHS = 2; - // Time-Base Counter Register - EPwm5Regs.TBCTR = 1; - // Counter-Compare (CC) Submodule - // -------------------------------------------------------------------- - // Counter-Compare A Register - EPwm5Regs.CMPA.half.CMPA = 0; - // Counter-Compare B Register - EPwm5Regs.CMPB = 0; - // Counter-Compare Control Register - EPwm5Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow - EPwm5Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow - EPwm5Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode - EPwm5Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD - // Action-Qualifier (AQ) Submodule - // -------------------------------------------------------------------- - // Action-Qualifier Output A Control Register - EPwm5Regs.AQCTLA.bit.CBD = 0;//do nothing - EPwm5Regs.AQCTLA.bit.CBU = 0;//do nothing - EPwm5Regs.AQCTLA.bit.CAD = 2;//set - force EPWMxA output high - EPwm5Regs.AQCTLA.bit.CAU = 1;//clear - force EPWMxA output low - EPwm5Regs.AQCTLA.bit.PRD = 0;//do nothing - EPwm5Regs.AQCTLA.bit.ZRO = 0;//do nothing - // Action-Qualifier Output B Control Register - EPwm5Regs.AQCTLB.bit.CBD = 0;//do nothing - EPwm5Regs.AQCTLB.bit.CBU = 0;//do nothing - EPwm5Regs.AQCTLB.bit.CAD = 0;//do nothing - EPwm5Regs.AQCTLB.bit.CAU = 0;//do nothing - EPwm5Regs.AQCTLB.bit.PRD = 0;//do nothing - EPwm5Regs.AQCTLB.bit.ZRO = 0;//do nothing - // Action-Qualifier Software Force Register - EPwm5Regs.AQSFRC.all = 0; - // Action-Qualifier Continuous Software Force Register - EPwm5Regs.AQCSFRC.all = 0; - // Dead-Band Generator (DB) Submodule - // -------------------------------------------------------------------- - // Dead-Band Generator Control Register - EPwm5Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay - EPwm5Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode - EPwm5Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB - // Dead-Band Generator Rising Edge Delay Register - EPwm5Regs.DBRED = (unsigned short)(FTBCLK*DT); - // Dead-Band Generator Falling Edge Delay Register - EPwm5Regs.DBFED = (unsigned short)(FTBCLK*DT); - // PWM-Chopper (PC) Submodule - // -------------------------------------------------------------------- - // PWM-Chopper Control Register - EPwm5Regs.PCCTL.all = 0; - // Trip-Zone (TZ) Submodule - // -------------------------------------------------------------------- - EALLOW; - // Trip-Zone Select Register - EPwm5Regs.TZSEL.all = 0; - // Trip-Zone Control Register - EPwm5Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state - EPwm5Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state - // Trip-Zone Enable Interrupt Register - EPwm5Regs.TZEINT.all = 0; - // Trip-Zone Force Register - EPwm5Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit - EDIS; - // Event-Trigger (ET) Submodule - // -------------------------------------------------------------------- - // Event-Trigger Selection Register - EPwm5Regs.ETSEL.all = 0; - // Event-Trigger Prescale Register - EPwm5Regs.ETPS.all = 0; - - // ePWM6 - // #################################################################### - // Time-Base (TB) Submodule - // -------------------------------------------------------------------- - // Time-Base Control Register - EPwm6Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement - EPwm6Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event - EPwm6Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm6Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm6Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI - EPwm6Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register - EPwm6Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs - EPwm6Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation - // Time-Base Period Register - EPwm6Regs.TBPRD = (unsigned short)T1_PRD; - // Time-Base Phase Register - EPwm6Regs.TBPHS.half.TBPHS = 2; - // Time-Base Counter Register - EPwm6Regs.TBCTR = 1; - // Counter-Compare (CC) Submodule - // -------------------------------------------------------------------- - // Counter-Compare A Register - EPwm6Regs.CMPA.half.CMPA = 0; - // Counter-Compare B Register - EPwm6Regs.CMPB = 0; - // Counter-Compare Control Register - EPwm6Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow - EPwm6Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow - EPwm6Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode - EPwm6Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD - // Action-Qualifier (AQ) Submodule - // -------------------------------------------------------------------- - // Action-Qualifier Output A Control Register - EPwm6Regs.AQCTLA.bit.CBD = 0;//do nothing - EPwm6Regs.AQCTLA.bit.CBU = 0;//do nothing - EPwm6Regs.AQCTLA.bit.CAD = 1;//clear - force EPWMxA output low - EPwm6Regs.AQCTLA.bit.CAU = 2;//set - force EPWMxA output high - EPwm6Regs.AQCTLA.bit.PRD = 0;//do nothing - EPwm6Regs.AQCTLA.bit.ZRO = 0;//do nothing - // Action-Qualifier Output B Control Register - EPwm6Regs.AQCTLB.bit.CBD = 0;//do nothing - EPwm6Regs.AQCTLB.bit.CBU = 0;//do nothing - EPwm6Regs.AQCTLB.bit.CAD = 0;//do nothing - EPwm6Regs.AQCTLB.bit.CAU = 0;//do nothing - EPwm6Regs.AQCTLB.bit.PRD = 0;//do nothing - EPwm6Regs.AQCTLB.bit.ZRO = 0;//do nothing - // Action-Qualifier Software Force Register - EPwm6Regs.AQSFRC.all = 0; - // Action-Qualifier Continuous Software Force Register - EPwm6Regs.AQCSFRC.all = 0; - // Dead-Band Generator (DB) Submodule - // -------------------------------------------------------------------- - // Dead-Band Generator Control Register - EPwm6Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay - EPwm6Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode - EPwm6Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB - // Dead-Band Generator Rising Edge Delay Register - EPwm6Regs.DBRED = (unsigned short)(FTBCLK*DT); - // Dead-Band Generator Falling Edge Delay Register - EPwm6Regs.DBFED = (unsigned short)(FTBCLK*DT); - // PWM-Chopper (PC) Submodule - // -------------------------------------------------------------------- - // PWM-Chopper Control Register - EPwm6Regs.PCCTL.all = 0; - // Trip-Zone (TZ) Submodule - // -------------------------------------------------------------------- - EALLOW; - // Trip-Zone Select Register - EPwm6Regs.TZSEL.all = 0; - // Trip-Zone Control Register - EPwm6Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state - EPwm6Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state - // Trip-Zone Enable Interrupt Register - EPwm6Regs.TZEINT.all = 0; - // Trip-Zone Force Register - EPwm6Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit - EDIS; - // Event-Trigger (ET) Submodule - // -------------------------------------------------------------------- - // Event-Trigger Selection Register - EPwm6Regs.ETSEL.all = 0; - // Event-Trigger Prescale Register - EPwm6Regs.ETPS.all = 0; - -#ifdef ML - // ePWM7 - // #################################################################### - // Time-Base (TB) Submodule - // -------------------------------------------------------------------- - // Time-Base Control Register - EPwm7Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement - EPwm7Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event - EPwm7Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm7Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm7Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI - EPwm7Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register - EPwm7Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs - EPwm7Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation - // Time-Base Period Register - EPwm7Regs.TBPRD = (unsigned short)T1_PRD; - // Time-Base Phase Register - EPwm7Regs.TBPHS.half.TBPHS = 2; - // Time-Base Counter Register - EPwm7Regs.TBCTR = 1; - // Counter-Compare (CC) Submodule - // -------------------------------------------------------------------- - // Counter-Compare A Register - EPwm7Regs.CMPA.half.CMPA = 0; - // Counter-Compare B Register - EPwm7Regs.CMPB = 0; - // Counter-Compare Control Register - EPwm7Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow - EPwm7Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow - EPwm7Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode - EPwm7Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD - // Action-Qualifier (AQ) Submodule - // -------------------------------------------------------------------- - // Action-Qualifier Output A Control Register - EPwm7Regs.AQCTLA.bit.CBD = 0;//do nothing - EPwm7Regs.AQCTLA.bit.CBU = 0;//do nothing - EPwm7Regs.AQCTLA.bit.CAD = 2;//set - force EPWMxA output high - EPwm7Regs.AQCTLA.bit.CAU = 1;//clear - force EPWMxA output low - EPwm7Regs.AQCTLA.bit.PRD = 0;//do nothing - EPwm7Regs.AQCTLA.bit.ZRO = 0;//do nothing - // Action-Qualifier Output B Control Register - EPwm7Regs.AQCTLB.bit.CBD = 0;//do nothing - EPwm7Regs.AQCTLB.bit.CBU = 0;//do nothing - EPwm7Regs.AQCTLB.bit.CAD = 0;//do nothing - EPwm7Regs.AQCTLB.bit.CAU = 0;//do nothing - EPwm7Regs.AQCTLB.bit.PRD = 0;//do nothing - EPwm7Regs.AQCTLB.bit.ZRO = 0;//do nothing - // Action-Qualifier Software Force Register - EPwm7Regs.AQSFRC.all = 0; - // Action-Qualifier Continuous Software Force Register - EPwm7Regs.AQCSFRC.all = 0; - // Dead-Band Generator (DB) Submodule - // -------------------------------------------------------------------- - // Dead-Band Generator Control Register - EPwm7Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay - EPwm7Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode - EPwm7Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB - // Dead-Band Generator Rising Edge Delay Register - EPwm7Regs.DBRED = (unsigned short)(FTBCLK*DT); - // Dead-Band Generator Falling Edge Delay Register - EPwm7Regs.DBFED = (unsigned short)(FTBCLK*DT); - // PWM-Chopper (PC) Submodule - // -------------------------------------------------------------------- - // PWM-Chopper Control Register - EPwm7Regs.PCCTL.all = 0; - // Trip-Zone (TZ) Submodule - // -------------------------------------------------------------------- - EALLOW; - // Trip-Zone Select Register - EPwm7Regs.TZSEL.all = 0; - // Trip-Zone Control Register - EPwm7Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state - EPwm7Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state - // Trip-Zone Enable Interrupt Register - EPwm7Regs.TZEINT.all = 0; - // Trip-Zone Force Register - EPwm7Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit - EDIS; - // Event-Trigger (ET) Submodule - // -------------------------------------------------------------------- - // Event-Trigger Selection Register - EPwm7Regs.ETSEL.all = 0; - // Event-Trigger Prescale Register - EPwm7Regs.ETPS.all = 0; - - // ePWM8 - // #################################################################### - // Time-Base (TB) Submodule - // -------------------------------------------------------------------- - // Time-Base Control Register - EPwm8Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement - EPwm8Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event - EPwm8Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm8Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm8Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI - EPwm8Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register - EPwm8Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs - EPwm8Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation - // Time-Base Period Register - EPwm8Regs.TBPRD = (unsigned short)T1_PRD; - // Time-Base Phase Register - EPwm8Regs.TBPHS.half.TBPHS = 2; - // Time-Base Counter Register - EPwm8Regs.TBCTR = 1; - // Counter-Compare (CC) Submodule - // -------------------------------------------------------------------- - // Counter-Compare A Register - EPwm8Regs.CMPA.half.CMPA = 0; - // Counter-Compare B Register - EPwm8Regs.CMPB = 0; - // Counter-Compare Control Register - EPwm8Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow - EPwm8Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow - EPwm8Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode - EPwm8Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD - // Action-Qualifier (AQ) Submodule - // -------------------------------------------------------------------- - // Action-Qualifier Output A Control Register - EPwm8Regs.AQCTLA.bit.CBD = 0;//do nothing - EPwm8Regs.AQCTLA.bit.CBU = 0;//do nothing - EPwm8Regs.AQCTLA.bit.CAD = 1;//clear - force EPWMxA output low - EPwm8Regs.AQCTLA.bit.CAU = 2;//set - force EPWMxA output high - EPwm8Regs.AQCTLA.bit.PRD = 0;//do nothing - EPwm8Regs.AQCTLA.bit.ZRO = 0;//do nothing - // Action-Qualifier Output B Control Register - EPwm8Regs.AQCTLB.bit.CBD = 0;//do nothing - EPwm8Regs.AQCTLB.bit.CBU = 0;//do nothing - EPwm8Regs.AQCTLB.bit.CAD = 0;//do nothing - EPwm8Regs.AQCTLB.bit.CAU = 0;//do nothing - EPwm8Regs.AQCTLB.bit.PRD = 0;//do nothing - EPwm8Regs.AQCTLB.bit.ZRO = 0;//do nothing - // Action-Qualifier Software Force Register - EPwm8Regs.AQSFRC.all = 0; - // Action-Qualifier Continuous Software Force Register - EPwm8Regs.AQCSFRC.all = 0; - // Dead-Band Generator (DB) Submodule - // -------------------------------------------------------------------- - // Dead-Band Generator Control Register - EPwm8Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay - EPwm8Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode - EPwm8Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB - // Dead-Band Generator Rising Edge Delay Register - EPwm8Regs.DBRED = (unsigned short)(FTBCLK*DT); - // Dead-Band Generator Falling Edge Delay Register - EPwm8Regs.DBFED = (unsigned short)(FTBCLK*DT); - // PWM-Chopper (PC) Submodule - // -------------------------------------------------------------------- - // PWM-Chopper Control Register - EPwm8Regs.PCCTL.all = 0; - // Trip-Zone (TZ) Submodule - // -------------------------------------------------------------------- - EALLOW; - // Trip-Zone Select Register - EPwm8Regs.TZSEL.all = 0; - // Trip-Zone Control Register - EPwm8Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state - EPwm8Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state - // Trip-Zone Enable Interrupt Register - EPwm8Regs.TZEINT.all = 0; - // Trip-Zone Force Register - EPwm8Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit - EDIS; - // Event-Trigger (ET) Submodule - // -------------------------------------------------------------------- - // Event-Trigger Selection Register - EPwm8Regs.ETSEL.all = 0; - // Event-Trigger Prescale Register - EPwm8Regs.ETPS.all = 0; - - // ePWM9 - // #################################################################### - // Time-Base (TB) Submodule - // -------------------------------------------------------------------- - // Time-Base Control Register - EPwm9Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement - EPwm9Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event - EPwm9Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm9Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm9Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI - EPwm9Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register - EPwm9Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs - EPwm9Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation - // Time-Base Period Register - EPwm9Regs.TBPRD = (unsigned short)T1_PRD; - // Time-Base Phase Register - EPwm9Regs.TBPHS.half.TBPHS = 2; - // Time-Base Counter Register - EPwm9Regs.TBCTR = 1; - // Counter-Compare (CC) Submodule - // -------------------------------------------------------------------- - // Counter-Compare A Register - EPwm9Regs.CMPA.half.CMPA = 0; - // Counter-Compare B Register - EPwm9Regs.CMPB = 0; - // Counter-Compare Control Register - EPwm9Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow - EPwm9Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow - EPwm9Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode - EPwm9Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD - // Action-Qualifier (AQ) Submodule - // -------------------------------------------------------------------- - // Action-Qualifier Output A Control Register - EPwm9Regs.AQCTLA.bit.CBD = 0;//do nothing - EPwm9Regs.AQCTLA.bit.CBU = 0;//do nothing - EPwm9Regs.AQCTLA.bit.CAD = 2;//set - force EPWMxA output high - EPwm9Regs.AQCTLA.bit.CAU = 1;//clear - force EPWMxA output low - EPwm9Regs.AQCTLA.bit.PRD = 0;//do nothing - EPwm9Regs.AQCTLA.bit.ZRO = 0;//do nothing - // Action-Qualifier Output B Control Register - EPwm9Regs.AQCTLB.bit.CBD = 0;//do nothing - EPwm9Regs.AQCTLB.bit.CBU = 0;//do nothing - EPwm9Regs.AQCTLB.bit.CAD = 0;//do nothing - EPwm9Regs.AQCTLB.bit.CAU = 0;//do nothing - EPwm9Regs.AQCTLB.bit.PRD = 0;//do nothing - EPwm9Regs.AQCTLB.bit.ZRO = 0;//do nothing - // Action-Qualifier Software Force Register - EPwm9Regs.AQSFRC.all = 0; - // Action-Qualifier Continuous Software Force Register - EPwm9Regs.AQCSFRC.all = 0; - // Dead-Band Generator (DB) Submodule - // -------------------------------------------------------------------- - // Dead-Band Generator Control Register - EPwm9Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay - EPwm9Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode - EPwm9Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB - // Dead-Band Generator Rising Edge Delay Register - EPwm9Regs.DBRED = (unsigned short)(FTBCLK*DT); - // Dead-Band Generator Falling Edge Delay Register - EPwm9Regs.DBFED = (unsigned short)(FTBCLK*DT); - // PWM-Chopper (PC) Submodule - // -------------------------------------------------------------------- - // PWM-Chopper Control Register - EPwm9Regs.PCCTL.all = 0; - // Trip-Zone (TZ) Submodule - // -------------------------------------------------------------------- - EALLOW; - // Trip-Zone Select Register - EPwm9Regs.TZSEL.all = 0; - // Trip-Zone Control Register - EPwm9Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state - EPwm9Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state - // Trip-Zone Enable Interrupt Register - EPwm9Regs.TZEINT.all = 0; - // Trip-Zone Force Register - EPwm9Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit - EDIS; - // Event-Trigger (ET) Submodule - // -------------------------------------------------------------------- - // Event-Trigger Selection Register - EPwm9Regs.ETSEL.all = 0; - // Event-Trigger Prescale Register - EPwm9Regs.ETPS.all = 0; - - // ePWM10 - // #################################################################### - // Time-Base (TB) Submodule - // -------------------------------------------------------------------- - // Time-Base Control Register - EPwm10Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement - EPwm10Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event - EPwm10Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm10Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm10Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI - EPwm10Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register - EPwm10Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs - EPwm10Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation - // Time-Base Period Register - EPwm10Regs.TBPRD = (unsigned short)T1_PRD; - // Time-Base Phase Register - EPwm10Regs.TBPHS.half.TBPHS = 2; - // Time-Base Counter Register - EPwm10Regs.TBCTR = 1; - // Counter-Compare (CC) Submodule - // -------------------------------------------------------------------- - // Counter-Compare A Register - EPwm10Regs.CMPA.half.CMPA = 0; - // Counter-Compare B Register - EPwm10Regs.CMPB = 0; - // Counter-Compare Control Register - EPwm10Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow - EPwm10Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow - EPwm10Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode - EPwm10Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD - // Action-Qualifier (AQ) Submodule - // -------------------------------------------------------------------- - // Action-Qualifier Output A Control Register - EPwm10Regs.AQCTLA.bit.CBD = 0;//do nothing - EPwm10Regs.AQCTLA.bit.CBU = 0;//do nothing - EPwm10Regs.AQCTLA.bit.CAD = 1;//clear - force EPWMxA output low - EPwm10Regs.AQCTLA.bit.CAU = 2;//set - force EPWMxA output high - EPwm10Regs.AQCTLA.bit.PRD = 0;//do nothing - EPwm10Regs.AQCTLA.bit.ZRO = 0;//do nothing - // Action-Qualifier Output B Control Register - EPwm10Regs.AQCTLB.bit.CBD = 0;//do nothing - EPwm10Regs.AQCTLB.bit.CBU = 0;//do nothing - EPwm10Regs.AQCTLB.bit.CAD = 0;//do nothing - EPwm10Regs.AQCTLB.bit.CAU = 0;//do nothing - EPwm10Regs.AQCTLB.bit.PRD = 0;//do nothing - EPwm10Regs.AQCTLB.bit.ZRO = 0;//do nothing - // Action-Qualifier Software Force Register - EPwm10Regs.AQSFRC.all = 0; - // Action-Qualifier Continuous Software Force Register - EPwm10Regs.AQCSFRC.all = 0; - // Dead-Band Generator (DB) Submodule - // -------------------------------------------------------------------- - // Dead-Band Generator Control Register - EPwm10Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay - EPwm10Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode - EPwm10Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB - // Dead-Band Generator Rising Edge Delay Register - EPwm10Regs.DBRED = (unsigned short)(FTBCLK*DT); - // Dead-Band Generator Falling Edge Delay Register - EPwm10Regs.DBFED = (unsigned short)(FTBCLK*DT); - // PWM-Chopper (PC) Submodule - // -------------------------------------------------------------------- - // PWM-Chopper Control Register - EPwm10Regs.PCCTL.all = 0; - // Trip-Zone (TZ) Submodule - // -------------------------------------------------------------------- - EALLOW; - // Trip-Zone Select Register - EPwm10Regs.TZSEL.all = 0; - // Trip-Zone Control Register - EPwm10Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state - EPwm10Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state - // Trip-Zone Enable Interrupt Register - EPwm10Regs.TZEINT.all = 0; - // Trip-Zone Force Register - EPwm10Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit - EDIS; - // Event-Trigger (ET) Submodule - // -------------------------------------------------------------------- - // Event-Trigger Selection Register - EPwm10Regs.ETSEL.all = 0; - // Event-Trigger Prescale Register - EPwm10Regs.ETPS.all = 0; - - // ePWM11 - // #################################################################### - // Time-Base (TB) Submodule - // -------------------------------------------------------------------- - // Time-Base Control Register - EPwm11Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement - EPwm11Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event - EPwm11Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm11Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm11Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI - EPwm11Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register - EPwm11Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs - EPwm11Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation - // Time-Base Period Register - EPwm11Regs.TBPRD = (unsigned short)T1_PRD; - // Time-Base Phase Register - EPwm11Regs.TBPHS.half.TBPHS = 2; - // Time-Base Counter Register - EPwm11Regs.TBCTR = 1; - // Counter-Compare (CC) Submodule - // -------------------------------------------------------------------- - // Counter-Compare A Register - EPwm11Regs.CMPA.half.CMPA = 0; - // Counter-Compare B Register - EPwm11Regs.CMPB = 0; - // Counter-Compare Control Register - EPwm11Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow - EPwm11Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow - EPwm11Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode - EPwm11Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD - // Action-Qualifier (AQ) Submodule - // -------------------------------------------------------------------- - // Action-Qualifier Output A Control Register - EPwm11Regs.AQCTLA.bit.CBD = 0;//do nothing - EPwm11Regs.AQCTLA.bit.CBU = 0;//do nothing - EPwm11Regs.AQCTLA.bit.CAD = 2;//set - force EPWMxA output high - EPwm11Regs.AQCTLA.bit.CAU = 1;//clear - force EPWMxA output low - EPwm11Regs.AQCTLA.bit.PRD = 0;//do nothing - EPwm11Regs.AQCTLA.bit.ZRO = 0;//do nothing - // Action-Qualifier Output B Control Register - EPwm11Regs.AQCTLB.bit.CBD = 0;//do nothing - EPwm11Regs.AQCTLB.bit.CBU = 0;//do nothing - EPwm11Regs.AQCTLB.bit.CAD = 0;//do nothing - EPwm11Regs.AQCTLB.bit.CAU = 0;//do nothing - EPwm11Regs.AQCTLB.bit.PRD = 0;//do nothing - EPwm11Regs.AQCTLB.bit.ZRO = 0;//do nothing - // Action-Qualifier Software Force Register - EPwm11Regs.AQSFRC.all = 0; - // Action-Qualifier Continuous Software Force Register - EPwm11Regs.AQCSFRC.all = 0; - // Dead-Band Generator (DB) Submodule - // -------------------------------------------------------------------- - // Dead-Band Generator Control Register - EPwm11Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay - EPwm11Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode - EPwm11Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB - // Dead-Band Generator Rising Edge Delay Register - EPwm11Regs.DBRED = (unsigned short)(FTBCLK*DT); - // Dead-Band Generator Falling Edge Delay Register - EPwm11Regs.DBFED = (unsigned short)(FTBCLK*DT); - // PWM-Chopper (PC) Submodule - // -------------------------------------------------------------------- - // PWM-Chopper Control Register - EPwm11Regs.PCCTL.all = 0; - // Trip-Zone (TZ) Submodule - // -------------------------------------------------------------------- - EALLOW; - // Trip-Zone Select Register - EPwm11Regs.TZSEL.all = 0; - // Trip-Zone Control Register - EPwm11Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state - EPwm11Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state - // Trip-Zone Enable Interrupt Register - EPwm11Regs.TZEINT.all = 0; - // Trip-Zone Force Register - EPwm11Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit - EDIS; - // Event-Trigger (ET) Submodule - // -------------------------------------------------------------------- - // Event-Trigger Selection Register - EPwm11Regs.ETSEL.all = 0; - // Event-Trigger Prescale Register - EPwm11Regs.ETPS.all = 0; - - // ePWM12 - // #################################################################### - // Time-Base (TB) Submodule - // -------------------------------------------------------------------- - // Time-Base Control Register - EPwm12Regs.TBCTL.bit.FREE_SOFT = 0;//emulation mode - stop after the next time-base counter increment or decrement - EPwm12Regs.TBCTL.bit.PHSDIR = 1;//count up after the synchronization event - EPwm12Regs.TBCTL.bit.CLKDIV = 0;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm12Regs.TBCTL.bit.HSPCLKDIV = 2;//TBCLK = SYSCLKOUT/(HSPCLKDIV*CLKDIV) - EPwm12Regs.TBCTL.bit.SYNCOSEL = 0;//SYNCO = SYNCI - EPwm12Regs.TBCTL.bit.PRDLD = 1;//load the TBPRD register immediately without using a shadow register - EPwm12Regs.TBCTL.bit.PHSEN = 1;//load TBCTR with TBPHS when EPWMxSYNCI input signal occurs - EPwm12Regs.TBCTL.bit.CTRMODE = 3;//stop-freeze counter operation - // Time-Base Period Register - EPwm12Regs.TBPRD = (unsigned short)T1_PRD; - // Time-Base Phase Register - EPwm12Regs.TBPHS.half.TBPHS = 2; - // Time-Base Counter Register - EPwm12Regs.TBCTR = 1; - // Counter-Compare (CC) Submodule - // -------------------------------------------------------------------- - // Counter-Compare A Register - EPwm12Regs.CMPA.half.CMPA = 0; - // Counter-Compare B Register - EPwm12Regs.CMPB = 0; - // Counter-Compare Control Register - EPwm12Regs.CMPCTL.bit.SHDWBMODE = 0;//CMPB operating mode - shadow - EPwm12Regs.CMPCTL.bit.SHDWAMODE = 0;//CMPA operating mode - shadow - EPwm12Regs.CMPCTL.bit.LOADBMODE = 0;//has no effect in immediate mode - EPwm12Regs.CMPCTL.bit.LOADAMODE = 2;//active CMPA load from shadow - load on CTR = Zero or CTR = PRD - // Action-Qualifier (AQ) Submodule - // -------------------------------------------------------------------- - // Action-Qualifier Output A Control Register - EPwm12Regs.AQCTLA.bit.CBD = 0;//do nothing - EPwm12Regs.AQCTLA.bit.CBU = 0;//do nothing - EPwm12Regs.AQCTLA.bit.CAD = 1;//clear - force EPWMxA output low - EPwm12Regs.AQCTLA.bit.CAU = 2;//set - force EPWMxA output high - EPwm12Regs.AQCTLA.bit.PRD = 0;//do nothing - EPwm12Regs.AQCTLA.bit.ZRO = 0;//do nothing - // Action-Qualifier Output B Control Register - EPwm12Regs.AQCTLB.bit.CBD = 0;//do nothing - EPwm12Regs.AQCTLB.bit.CBU = 0;//do nothing - EPwm12Regs.AQCTLB.bit.CAD = 0;//do nothing - EPwm12Regs.AQCTLB.bit.CAU = 0;//do nothing - EPwm12Regs.AQCTLB.bit.PRD = 0;//do nothing - EPwm12Regs.AQCTLB.bit.ZRO = 0;//do nothing - // Action-Qualifier Software Force Register - EPwm12Regs.AQSFRC.all = 0; - // Action-Qualifier Continuous Software Force Register - EPwm12Regs.AQCSFRC.all = 0; - // Dead-Band Generator (DB) Submodule - // -------------------------------------------------------------------- - // Dead-Band Generator Control Register - EPwm12Regs.DBCTL.bit.IN_MODE = 0;//EPWMxA In (from the action-qualifier) is the source for both falling-edge and rising-edge delay - EPwm12Regs.DBCTL.bit.POLSEL = 2;//active high complementary (AHC) mode - EPwm12Regs.DBCTL.bit.OUT_MODE = 3;//dead-band is fully enabled for both rising-edge delay on output EPWMxA and falling-edge delay on output EPWMxB - // Dead-Band Generator Rising Edge Delay Register - EPwm12Regs.DBRED = (unsigned short)(FTBCLK*DT); - // Dead-Band Generator Falling Edge Delay Register - EPwm12Regs.DBFED = (unsigned short)(FTBCLK*DT); - // PWM-Chopper (PC) Submodule - // -------------------------------------------------------------------- - // PWM-Chopper Control Register - EPwm12Regs.PCCTL.all = 0; - // Trip-Zone (TZ) Submodule - // -------------------------------------------------------------------- - EALLOW; - // Trip-Zone Select Register - EPwm12Regs.TZSEL.all = 0; - // Trip-Zone Control Register - EPwm12Regs.TZCTL.bit.TZB = 2;//when a trip event occurs the following action is taken on output EPWMxB - force EPWMxB to a low state - EPwm12Regs.TZCTL.bit.TZA = 2;//when a trip event occurs the following action is taken on output EPWMxA - force EPWMxA to a low state - // Trip-Zone Enable Interrupt Register - EPwm12Regs.TZEINT.all = 0; - // Trip-Zone Force Register - EPwm12Regs.TZFRC.all = 0x0004;//forces a one-shot trip event via software and sets the TZFLG[OST] bit - EDIS; - // Event-Trigger (ET) Submodule - // -------------------------------------------------------------------- - // Event-Trigger Selection Register - EPwm12Regs.ETSEL.all = 0; - // Event-Trigger Prescale Register - EPwm12Regs.ETPS.all = 0; -#endif //ML -} //void SetupEpwm(void) - - - -// Íàñòðàèâàåò ADC -void SetupAdc(void) { -#ifndef ML - unsigned short i; - - // ADC Control Register 1 - AdcRegs.ADCTRL1.bit.SUSMOD = 0;//emulation suspend is ignored - AdcRegs.ADCTRL1.bit.ACQ_PS = 3;//width of SOC pulse is (ACQ_PS+1) times the ADCLK period - AdcRegs.ADCTRL1.bit.CPS = 0;//ADCCLK = HSPCLK/(2*ADCCLKPS*(CPS+1)) - AdcRegs.ADCTRL1.bit.CONT_RUN = 0;//start-stop mode - AdcRegs.ADCTRL1.bit.SEQ_OVRD = 0;//sequencer override disabled - AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;//cascaded mode - - // ADC Control Register 2 - AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ = 1;//allows SEQ to be started by ePWMx SOCB trigger - AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 0;//clears a pending SOC trigger - AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;//interrupt request by INT_SEQ1 is enabled - AdcRegs.ADCTRL2.bit.INT_MOD_SEQ1 = 0;//INT_SEQ1 is set at the end of every SEQ1 sequence - AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1;//allows SEQ1/SEQ to be started by ePWMx SOCA trigger - AdcRegs.ADCTRL2.bit.EXT_SOC_SEQ1 = 0;//disables an ADC autoconversion sequence to be started by a signal from a GPIO Port A pin - AdcRegs.ADCTRL2.bit.SOC_SEQ2 = 0;//clears a pending SOC trigger - AdcRegs.ADCTRL2.bit.INT_ENA_SEQ2 = 0;//interrupt request by INT_SEQ2 is disabled - AdcRegs.ADCTRL2.bit.INT_MOD_SEQ2 = 0;//INT_SEQ2 is set at the end of every SEQ2 sequence - AdcRegs.ADCTRL2.bit.EPWM_SOCB_SEQ2 = 0;//SEQ2 cannot be started by ePWMx SOCB trigger - - /* The ADC resets to the ADC off state. When powering up the ADC, use - the following sequence: - 1. If external reference is desired, enable this mode using bits - 15-14 in the ADCREFSEL Register. This mode must be enabled before - band gap is powered; - 2. Power up the reference, bandgap, and analog circuits together by - setting bits 7-5 (ADCBGRFDN[1:0], ADCPWDN) in the ADCTRL3 register; - 3. Before performing the first conversion, a delay of 5 ms is required */ - - // ADC Reference Select Register - AdcRegs.ADCREFSEL.bit.REF_SEL = 1;//external reference, 2.048 V on ADCREFIN - - // ADC Control Register 3 - AdcRegs.ADCTRL3.all = 0x00E0;//power up the reference, bandgap, and analog circuits together - AdcRegs.ADCTRL3.bit.ADCCLKPS = 5;//ADCCLK = HSPCLK/(2*ADCCLKPS*(CPS+1)) -> ADCCLK = 75e6/(2*5*(0+1)) = 7.5e6 Ãö - AdcRegs.ADCTRL3.bit.SMODE_SEL = 1;//simultaneous sampling mode - - // Delay before converting ADC channels - for ( i = 0; i < 65500; i++ ) - ; -#endif //ML - - // Maximum Conversion Channels Register - AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 5;//6 double conv's (12 total) - // ADC Input Channel Select Sequencing Control Registers - AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0; - AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 1; - AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 2; - AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 3; - AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 4; - AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 5; - AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 6; - AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 7; - AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0; - AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0; - AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0; - AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0; - AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0; - AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0; - AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0; - AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 0; -} //void SetupAdc(void) - - - -// Íàñòðàèâàåò eQEP -void SetupEqep(void) { - // eQEP Decoder Control Register - EQep2Regs.QDECCTL.bit.QSRC = 0;//Position-counter source selection: Quadrature count mode (QCLK = iCLK, QDIR = iDIR) - EQep2Regs.QDECCTL.bit.SOEN = 0;//Sync output-enable: Disable position-compare sync output - EQep2Regs.QDECCTL.bit.SPSEL = 0;//Sync output pin selection: Index pin is used for sync output - EQep2Regs.QDECCTL.bit.XCR = 0;//External clock rate: 2x resolution: Count the rising/falling edge - EQep2Regs.QDECCTL.bit.SWAP = 0;//Swap quadrature clock inputs: Quadrature-clock inputs are not swapped - EQep2Regs.QDECCTL.bit.IGATE = 0;//Index pulse gating option: Disable gating of Index pulse - EQep2Regs.QDECCTL.bit.QAP = 0;//QEPA input polarity: No effect - EQep2Regs.QDECCTL.bit.QBP = 0;//QEPB input polarity: No effect - EQep2Regs.QDECCTL.bit.QIP = 0;//QEPI input polarity: No effect - EQep2Regs.QDECCTL.bit.QSP = 0;//QEPS input polarity: No effect - // eQEP Control Register - EQep2Regs.QEPCTL.bit.FREE_SOFT = 0;//Emulation Control Bits: all stops immediately - EQep2Regs.QEPCTL.bit.PCRM = 1;//Position counter reset mode: position counter reset on the maximum position - EQep2Regs.QEPCTL.bit.SEI = 0;//Strobe event initialization of position counter: does nothing (action disabled) - EQep2Regs.QEPCTL.bit.IEI = 0;//Index event initialization of position counter: do nothing (action disabled) - EQep2Regs.QEPCTL.bit.SWI = 0;//Software initialization of position counter: do nothing (action disabled) - EQep2Regs.QEPCTL.bit.SEL = 0;//Strobe event latch of position counter: the position counter is latched on the rising edge of QEPS strobe - EQep2Regs.QEPCTL.bit.IEL = 1;//Index event latch of position counter (software index marker): latches position counter on rising edge of the index signal - EQep2Regs.QEPCTL.bit.QPEN = 1;//Quadrature position counter enable/software reset: eQEP position counter is enabled - EQep2Regs.QEPCTL.bit.QCLM = 0;//eQEP capture latch mode: latch on position counter read by CPU - EQep2Regs.QEPCTL.bit.UTE = 1;//eQEP unit timer enable: Enable unit timer - EQep2Regs.QEPCTL.bit.WDE = 0;//eQEP watchdog enable: disable the eQEP watchdog timer - // eQEP Position-compare Control Register - EQep2Regs.QPOSCTL.bit.PCSHDW = 0;//Position-compare shadow enable: Shadow disabled, load Immediate - EQep2Regs.QPOSCTL.bit.PCLOAD = 0;//Position-compare shadow load mode: Load on QPOSCNT = 0 - EQep2Regs.QPOSCTL.bit.PCPOL = 0;//Polarity of sync output: Active HIGH pulse output - EQep2Regs.QPOSCTL.bit.PCE = 0;//Position-compare enable/disable: Disable position compare unit - EQep2Regs.QPOSCTL.bit.PCSPW = 0;//Select-position-compare sync output pulse width: 1 * 4 * SYSCLKOUT cycles - // eQEP Capture Control Register - EQep2Regs.QCAPCTL.bit.CEN = 1;//Enable eQEP capture: eQEP capture unit is enabled - EQep2Regs.QCAPCTL.bit.CCPS = 2;//eQEP capture timer clock prescaler: CAPCLK = SYSCLKOUT/4 - EQep2Regs.QCAPCTL.bit.UPPS = 0;//Unit position event prescaler: UPEVNT = QCLK/1 - // eQEP Position Counter Register - EQep2Regs.QPOSCNT = 0x00000000; - // eQEP Maximum Position Count Register Register - EQep2Regs.QPOSMAX = 0x7FFF; - // eQEP Position-compare Register - EQep2Regs.QPOSCMP = 0x00000000; - // eQEP Unit Timer Register - EQep2Regs.QUTMR = 0x00000000; - // eQEP Register Unit Period Register - EQep2Regs.QUPRD = 0x00000000; - // eQEP Watchdog Timer Register - EQep2Regs.QWDTMR = 0x0000; - // eQEP Watchdog Period Register - EQep2Regs.QWDPRD = 0x0000; - // eQEP Interrupt Enable Register - EQep2Regs.QEINT.all = 0x0000; - // eQEP Capture Timer Register - EQep2Regs.QCTMR = 0x0000; - // eQEP Capture Period Register - EQep2Regs.QCPRD = 0x0000; -} //void SetupEqep(void) diff --git a/Inu/init28335.h b/Inu/init28335.h deleted file mode 100644 index d75c3cf..0000000 --- a/Inu/init28335.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef INIT28335 -#define INIT28335 - -// Ïåðåìåííûå, êîòîðûå îïðåäåëåíû â init28335.c (begin) -//######################################################################### -//######################################################################### -// Ïåðåìåííûå, êîòîðûå îïðåäåëåíû â init28335.c (end) - - - - -// Ïåðåìåííûå, êîòîðûå îáúÿâëåíû â init28335.c (begin) -//######################################################################### -#ifndef ML -extern Uint16 RamfuncsLoadStart, RamfuncsLoadEnd, RamfuncsRunStart; -extern Uint16 RamfuncsLoadStart2, RamfuncsLoadEnd2, RamfuncsRunStart2; -extern Uint16 SwitchLoadStart, SwitchLoadEnd, SwitchRunStart; -extern Uint16 EconstLoadStart, EconstLoadEnd, EconstRunStart; -extern short csmSuccess; -#endif //ML -//######################################################################### -// Ïåðåìåííûå, êîòîðûå îáúÿâëåíû â init28335.c (end) - -#endif //INIT28335 diff --git a/Inu/wrapper_inu.h b/Inu/wrapper_inu.h index 326ea68..5ee02d5 100644 --- a/Inu/wrapper_inu.h +++ b/Inu/wrapper_inu.h @@ -6,11 +6,11 @@ Äàòà ïîñëåäíåãî îáíîâëåíèÿ: 2021.09.22 **************************************************************************/ +#include "simstruc.h" #ifndef WRAPPER #define WRAPPER - #define INPUT_0_WIDTH 20 //êîë-âî âõîäîâ #define OUTPUT_0_WIDTH 49 //êîë-âî âûõîäîâ #define NPARAMS 1 //êîë-âî ïàðàìåòðîâ (ñêàëÿðîâ è âåêòîðîâ) diff --git a/controller.ilk b/controller.ilk deleted file mode 100644 index 9509811d1f8b999936dfd3f2255687a495133cb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 385240 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ΪPwHZq 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 diff --git a/inu_im_2wnd_3lvl.slx b/inu_im_2wnd_3lvl.slx index e40b9cb4eacb29ba050d3d0ecab51b7e644b466a..a4592efc70993a85454a5d10e39d8c318628ae21 100644 GIT binary patch delta 21123 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