123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890 |
- /* ==============================================================================
- System Name: HVBLDC_Sensored
- File Name: HVBLDC_Sensored.C
- Description: Primary system file for the (Trapezoidal) Sensored BLDC Control
- Using Hall Effect Sensors
- ===================================================================================*/
- // Include header files used in the main function
- #include "PeripheralHeaderIncludes.h"
- #define MATH_TYPE IQ_MATH
- #include "IQmathLib.h"
- #include "HVBLDC_Sensored.h"
- #include "HVBLDC_Sensored-Settings.h"
- #include <math.h>
- #include "UserCan.h"
- #include "lowpass.h"
- #include "var.h"
- #ifdef FLASH
- #pragma CODE_SECTION(MainISR,"ramfuncs");
- void MemCopy();
- void InitFlash();
- #endif
- #define TIMER1_S1 60
- #define TIMER1_S2 500000
- #define TIMER1_PER 30000000
- #define MAINLOOPDIV 5 // 主中断40K 40K/MAINLOOPDIV 主循环
- // Prototype statements for functions found within this file.
- interrupt void MainISR(void);//主中断
- interrupt void xint1_isr(void);//FO中断
- interrupt void xint2_isr(void);//HALL A中断
- interrupt void EPWM1TZint_isr(void);//TZ中断 过流中断
- void DeviceInit();
- void HVDMC_Protection(void);
- void speed_direction(Uint16 hall,Uint16 hall_last);//使用中断计算转速
- void speed_cal(void);//使用中断计算转速
- void pwmlimit_speed(void);//
- void ClosePwm(void);
- void bldcpwm_close(void);
- void OpenPwm(void);
- void mainLoop(void);
- // State Machine function prototypes
- //------------------------------------
- int16 MastIsrTimePercent(void);
- void taskfree(void);
- void ServiceDog(void);
- void EnableDog(void);
- // Used for running BackGround in flash, and ISR in RAM
- //速度计算相关
- int16 t4 = 0;
- int16 Xint2Cnt = 0;
- int16 hallCmtnTrig = 0;
- extern Uint16 *RamfuncsLoadStart, *RamfuncsLoadEnd, *RamfuncsRunStart;
- int16 SerialCommsTimer;
- // Global variables used in this system
- HALL3 hall1 = HALL3_DEFAULTS;
- SPEED_MEAS_CAP speed1 = SPEED_MEAS_CAP_DEFAULTS;
- PWMGEN pwm1 = PWMGEN_DEFAULTS;
- _iq20 kscaler = _IQ20(90*3.3/4096/2.3);
- float32 T = 0.001/ISR_FREQUENCY; // Samping period (sec), see parameter.h
- Uint16 BackTicker = 0;
- Uint16 PreviousState;
- Uint16 ClosedFlag = 0;
- Uint32 VirtualTimer = 0;
- Uint16 ILoopFlag = FALSE;
- Uint16 SpeedLoopFlag = FALSE;
- int16 DFuncDesired = 0x0300; // Desired duty cycle (Q15)
- int16 DfuncTesting = 500;//0x0300;//占空比
- int16 Delay30 = 0x3FFF;
- int16 DelayFlag = 0;
- Uint16 AlignFlag = 0x000F;
- Uint16 LoopCount = 0;
- Uint16 TripFlagDMC=0; //PWM trip status
- #if (BUILDLEVEL<= LEVEL2)
- Uint32 CmtnPeriodTarget = 0x00000500;
- Uint32 CmtnPeriodSetpt = 0x00002000;//要大于CmtnPeriodTarget才能使用--
- Uint32 RampDelay = 10;
- #else
- Uint32 CmtnPeriodTarget = 0x00000450;
- Uint32 CmtnPeriodSetpt = 0x00001500;
- Uint32 RampDelay = 10;
- #endif
- _iq DCbus_current=0;
- _iq Speedgd=0;
- _iq tempIdc=0;
- int32 Rt;
- Uint16 ch1=0;
- Uint16 ch2=0;
- Uint16 ch3=0;
- // Used for ADC Configuration
- int ChSel[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
- int TrigSel[16] = {5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5};
- int ACQPS[16] = {8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8};
- // Instance PI regulator to regulate the DC-bus current and speed
- // Instance a PWM driver instance
- // Instance a PWM DAC driver instance
- PWMDAC pwmdac1 = PWMDAC_DEFAULTS;
- // Instance a Hall effect driver
- // Instance a ramp controller to smoothly ramp the frequency
- // Instance a RAMP2 Module
- RMP2 rmp2 = RMP2_DEFAULTS;
- // Instance a RAMP3 Module
- RMP3 rmp3 = RMP3_DEFAULTS;
- // Instance a MOD6 Module
- MOD6CNT mod1 = MOD6CNT_DEFAULTS;
- // Instance a IMPULSE Module
- IMPULSE impl1 = IMPULSE_DEFAULTS;
- // Instance a SPEED_PR Module
- // Create an instance of DATALOG Module 950:3A 但是只有外界扭矩低于36N才能启动起来
- Uint16 pwm_limit_table1[5] = {950,1300,1650,1930,2320};//0 50 100 150 200
- //// 0, 100, 200, 300, 400 500 600 700 800 900 1000
- /*Uint16 pwm_limit_table2[]= {950,1650,2320,3050,3750,4460,5200,5929,6623,7358,8050,
- 8744,9400,10165,10848,11600,12290,12953,13684,14310,15050,
- 15760,16434,17054,17750,18493,19134,19830,20507,21260,21926,
- 22602,23232,23935,24609,25240};*/
- Uint16 pwm_limit_table2[]= {950,1650,2320,2985,3668,4348,5024,5705,6383,7058,7739,
- 8449,9122,9800,10480,11163,11826,12499,13181,13860,14515,
- 15192,15872,16530,17203,17861,18537,19183,19848,20525,21161,
- 21838,22488,23216,23850,24507,24507};
- //// 0, 100, 200, 300, 400 500 600 700 800 900 1000
- Uint16 pwm_limit_table_neg[]= {950,1616,2272,2961,3641,4305,4983,5659,6326,6994,7670,
- 8348,9022,9700,10361,11502,11714,12379,13066,13727,14426,//1100-2000
- 15085,15610,16325,17005,17660,18338,19000,19693,20390,21048,
- 21706,22428,23104,22823,24434,24434};
- /*Uint16 pwm_limit_table_neg[]= {950,1650,2320,3050,3750,4476,5200,5830,6520,7200,7808,
- 8500,9206,9800,10510,11200,11930,12579,13229,13892,14540,
- 15209,15920,16616,17291,18000,18775,19424,20507,21260,21926,
- 22602,23232,23935,24609,25240};*/
- int32 pwmlimitrate = 24507;
- Uint32 IsrTicker=0;
- void main(void)
- {
-
- DeviceInit(); // Device Life support & GPIO
- InitCan();
- // Only used if running from FLASH
- // Note that the variable FLASH is defined by the compiler
- #ifdef FLASH
- // Copy time critical code and Flash setup code to RAM
- // The RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart
- // symbols are created by the linker. Refer to the linker files.
- MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
- // Call Flash Initialization to setup flash waitstates
- // This function must reside in RAM
- InitFlash(); // Call the flash wrapper init function
- #endif //(FLASH)
- // Initialize all the Device Peripherals:
- // This function is found in DSP280x_CpuTimers.c
- InitCpuTimers();
-
- // Configure CPU-Timer 0 to interrupt every ISR Period:
- // 60MHz CPU Freq, ISR Period (in uSeconds)
- // This function is found in DSP280x_CpuTimers.c
- ConfigCpuTimer(&CpuTimer0, 60, 1000/ISR_FREQUENCY);//40K
- StartCpuTimer0();
- // Configure CPU-Timer 1,2 for background loops
- ConfigCpuTimer(&CpuTimer1, TIMER1_S1, TIMER1_S2);//2hz
- ConfigCpuTimer(&CpuTimer2, 60, 1000000);//20HZ
- StartCpuTimer1();
- StartCpuTimer2();
-
- // Reassign ISRs.
- // Reassign the PIE vector for TINT0 to point to a different
- // ISR then the shell routine found in DSP280x_DefaultIsr.c.
- // This is done if the user does not want to use the shell ISR routine
- // but instead wants to use their own ISR.
- EALLOW; // This is needed to write to EALLOW protected registers
- PieVectTable.TINT0 = &MainISR;//40KHZ
- PieVectTable.XINT1 = &xint1_isr;
- PieVectTable.XINT2 = &xint2_isr;
- PieVectTable.EPWM1_TZINT = &EPWM1TZint_isr;
- EDIS; // This is needed to disable write to EALLOW protected registers
- // Enable PIE group 1 interrupt 7 for TINT0
- PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
- PieCtrlRegs.PIEIER1.bit.INTx4 = 1; // Enable PIE Gropu 1 INT4 //XINT1
- PieCtrlRegs.PIEIER1.bit.INTx5 = 1; // Enable PIE Gropu 1 INT5 //XINT2
- // Enable CPU INT1 for TINT0:
- IER |= M_INT1;
- PieCtrlRegs.PIEIER2.bit.INTx1 = 1;
- IER |= M_INT2;
- // Enable Global realtime interrupt DBGM
- EALLOW;
- GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 16; //定位到哪个引脚中断
- GpioIntRegs.GPIOXINT2SEL.bit.GPIOSEL = 24; // XINT2 is GPIO24
- EDIS;
- XIntruptRegs.XINT1CR.bit.POLARITY = 0; // 1为上升沿,0和2为下降沿,3为双边沿
- XIntruptRegs.XINT2CR.bit.POLARITY = 3; // 1为上升沿,0和2为下降沿,3为双边沿
- //中断配置步骤-----1,开启模块中断使能,
- XIntruptRegs.XINT1CR.bit.ENABLE = 1;
- XIntruptRegs.XINT2CR.bit.ENABLE = 1; // Enable XINT2
- // Enable global Interrupts and higher priority real-time debug events:
- EINT; // Enable Global interrupt INTM
- ERTM; // Enable Global realtime interrupt DBGM
-
-
- // Initialize PWM module
- pwm1.PeriodMax = (SYSTEM_FREQUENCY/PWM_FREQUENCY)*1000/2; // Asymmetric PWM 20kHZ 3000
- pwm1.DutyFunc = 0; // 占空比ALIGN_DUTY/32767 // DutyFunc = Q15
- BLDCPWM_INIT_MACRO(1,2,3,&pwm1);
- // Initialize PWMDAC module
- pwmdac1.PeriodMax = 500; // @60Mhz, 1500->20kHz, 1000-> 30kHz, 500->60kHz
- pwmdac1.HalfPerMax = pwmdac1.PeriodMax/2; // Needed to adjust the duty cycle range in the macro
- PWMDAC_INIT_MACRO(6,pwmdac1) ; // PWM 6A,6B
- PWMDAC_INIT_MACRO(7,pwmdac1) ; // PWM 7A,7B
- // Initialize Hall module
- hall1.DebounceAmount = 1;
- hall1.Revolutions = 1;
- HALL3_INIT_MACRO(&hall1);//读hall值 初始化HallGpioBuffer,HallGpioAccepted
- // Initialize the SPEED_PR module
- speed1.InputSelect = 0;
- speed1.BaseRpm = (Uint32)120*BASE_FREQ/POLES;//(Uint32)120*BASE_FREQ/POLES/6;//// 使用一个换相周期//额定转速 = 60*(基频/(极数/2)) = 60*f/极对数
- speed1.SpeedScaler = (Uint32)((Uint32)ISR_FREQUENCY*10000/BASE_FREQ);//保留一位小数//40000/f
-
- // For the kits < Rev 1.1 -------------------------------------------------
- ChSel[0]=15; // Dummy meas. avoid 1st sample issue Rev0 Picollo
- ChSel[1]=2; // ChSelect: ADC B7-> Phase A Voltage
- ChSel[2]=3; // ChSelect: ADC B6-> Phase B Voltage
- ChSel[3]=4; // ChSelect: ADC B4-> Phase C Voltage
- ChSel[4]=7; // ChSelect: ADC A2-> DC Bus vol
- ChSel[5]=6; // DC current 放大20倍 Imeasure = I*5mΩ*20
- ChSel[6]=5; // NTC
- ChSel[7]=1; // VOT
- //-------------------------------------------------------------------------
-
- ADC_MACRO_INIT(ChSel,TrigSel,ACQPS);
-
- // Initialize RMP2 module
- rmp2.Out = (int32)0;
- rmp2.Ramp2Delay = 0x00000001;
- rmp2.Ramp2Max = 32767/2;
- rmp2.Ramp2Min = -32768/2;
- // Initialize RMP3 module
- rmp3.DesiredInput = CmtnPeriodTarget;
- rmp3.Ramp3Delay = RampDelay;
- rmp3.Out = CmtnPeriodSetpt;
- rmp3.Ramp3Min = 0x00000010;
- InitVar();
- //Call HVDMC Protection function
- HVDMC_Protection();
- EnableDog();
- // IDLE loop. Just sit and loop forever:
- for(;;) //infinite loop
- {
- if(IsrTicker%MAINLOOPDIV ==0)
- {//8Khz
- mainLoop();
- }
- }
- } //END MAIN CODE
- //=================================================================================
- // STATE-MACHINE SEQUENCING AND SYNCRONIZATION FOR SLOW BACKGROUND TASKS
- //=================================================================================
- // ==============================================================================
- // =============================== MAIN ISR =====================================
- // ==============================================================================
- interrupt void MainISR(void)
- {
- //--------------------------------------------------------------------------------------
- // Verifying the ISR
- IsrTicker++;
- IsrTicker = (IsrTicker>20000)? 0 : IsrTicker;
- VirtualTimer++;
- VirtualTimer &= 0x00007FFF;
- HALL3_READ_MACRO(&hall1);
- ClosedFlag = TRUE;
- if (ClosedFlag==TRUE)
- {
- if (hall1.CmtnTrigHall==0x7FFF)
- {
- hallCmtnTrig = 1;
- speed_direction(hall1.HallGpioAccepted,PreviousState);
- if (hall1.HallGpioAccepted==5)
- {
- pwm1.CmtnPointerIn = 5;
- }
- else if (hall1.HallGpioAccepted==1)
- { pwm1.CmtnPointerIn = 0;
- }
- else if (hall1.HallGpioAccepted==3)
- { pwm1.CmtnPointerIn = 1;
- }
- else if (hall1.HallGpioAccepted==2)
- { pwm1.CmtnPointerIn = 2;
- }
- else if (hall1.HallGpioAccepted==6)
- { pwm1.CmtnPointerIn = 3;
- }
- else if (hall1.HallGpioAccepted==4)
- {
- pwm1.CmtnPointerIn = 4;
- }
- PreviousState = hall1.HallGpioAccepted;
- } // delay
- } // ClosedFlag==TRUE
- if(Enable_ALLOW == 0 && pwm1.DutyFunc==0){
- bldcpwm_close();
- }else{
- BLDCPWM_MACRO(1,2,3,&pwm1);
- }
- // Acknowledge interrupt to recieve more interrupts from PIE group 1
- CpuTimer0.RegsAddr->TCR.bit.TIF=1;
- PieCtrlRegs.PIEACK.bit.ACK1 = 1;
- //PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
- }// ISR Ends Here
- /**********************************************************/
- /***************Protection Configuration*******************/
- /**********************************************************/
- void HVDMC_Protection(void)
- {
- // Configure Trip Mechanism for the Motor control software
- // -Cycle by cycle trip on CPU halt
- // -One shot IPM trip zone trip
- // These trips need to be repeated for EPWM1 ,2 & 3
- //===========================================================================
- //Motor Control Trip Config, EPwm1,2,3
- //===========================================================================
- EALLOW;
- // CPU Halt Trip 使能TZ6周期触发,周期触发可以自动清零 但是一次触发不能自动清零
- // EPwm1Regs.TZSEL.bit.CBC6=0x1;//Enable TZ6 as a CBC trip source for this ePWM module
- // EPwm2Regs.TZSEL.bit.CBC6=0x1;
- // EPwm3Regs.TZSEL.bit.CBC6=0x1;
-
- //使能故障的单次触发
- EPwm1Regs.TZSEL.bit.OSHT1 = 1; //enable TZ1 for OSHT
- EPwm2Regs.TZSEL.bit.OSHT1 = 1; //enable TZ1 for OSHT
- EPwm3Regs.TZSEL.bit.OSHT1 = 1; //enable TZ1 for OSHT
- EPwm1Regs.TZEINT.bit.OST = 1;
- // What do we want the OST/CBC events to do?
- // TZA events can force EPWMxA
- // TZB events can force EPWMxB
- //故障发生时的输出状态为低
- EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWMxA will go low
- EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // EPWMxB will go low
-
- EPwm2Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWMxA will go low
- EPwm2Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // EPWMxB will go low
-
- EPwm3Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWMxA will go low
- EPwm3Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // EPWMxB will go low
-
-
- EDIS;
- // Clear any spurious OV trip 清除标志位
- EPwm1Regs.TZCLR.bit.OST = 1;
- EPwm2Regs.TZCLR.bit.OST = 1;
- EPwm3Regs.TZCLR.bit.OST = 1;
-
- //************************** End of Prot. Conf. ***************************//
- }
- //速度计算中断
- interrupt void xint2_isr(void)
- {
- static int32 last_XintTime = TIMER1_PER;
- static Uint32 last_hall = 0;
- Uint32 temp = 0;
- if(CpuTimer1.RegsAddr->TCR.bit.TIF == 1){
- // 速度为0
- XintTime = (int32)TIMER1_PER;
- CpuTimer1.RegsAddr->TCR.bit.TIF = 1;//写1清中断标志位
- }else{
- XintTime = (int32)TIMER1_PER - CpuTimer1.RegsAddr->TIM.all;
- }
- XintTime = (int32)TIMER1_PER - CpuTimer1.RegsAddr->TIM.all;
- temp = (GpioDataRegs.GPADAT.all>>24)&0x00000007; /* read all three GPIOs at once*/
- if(_IQabs(XintTime)<30000 || temp == last_hall ){
- //filter 防抖
- XintTime = last_XintTime;
- PieCtrlRegs.PIEACK.bit.ACK1 =1;
- return ;
- }
- if(Direction == -1){
- XintTime = -XintTime;
- }
- Xint2Cnt = 1;
- last_XintTime = XintTime;
- last_hall = temp;
- CpuTimer1.RegsAddr->TCR.bit.TRB = 1; //重新装载
- CpuTimer1.RegsAddr->TCR.bit.TSS = 0;//定时器restart
- PieCtrlRegs.PIEACK.bit.ACK1 =1;
- }
- interrupt void xint1_isr(void)
- {
- FaultFlag.bit.Ipmfault = 1;
- PieCtrlRegs.PIEACK.bit.ACK1 =1;
- // PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
- }
- interrupt void EPWM1TZint_isr(void)
- {
- //過流
- FaultFlag.bit.OverCurFlag = 1;
- EALLOW;
- // EPwm1Regs.TZCLR.bit.OST = 1;
- // EPwm1Regs.TZCLR.bit.INT = 1;
- EDIS;
- PieCtrlRegs.PIEACK.bit.ACK2 = 1;//PIEACK_GROUP2;
- }
- void ServiceDog(void)
- {
- EALLOW;
- SysCtrlRegs.WDKEY = 0x0055;
- SysCtrlRegs.WDKEY = 0x00AA;
- EDIS;
- }
- //---------------------------------------------------------------------------
- // Example: DisableDog:
- //---------------------------------------------------------------------------
- // This function disables the watchdog timer.
- //---------------------------------------------------------------------------
- // 使能看门狗
- //---------------------------------------------------------------------------
- void EnableDog(void)
- {
- EALLOW;
- SysCtrlRegs.WDCR= 0x0028;
- EDIS;
- }
- void OpenPwm(void)
- {
- EALLOW;
- EPwm1Regs.TZCLR.bit.OST = 1; //EnablePWM1
- EPwm2Regs.TZCLR.bit.OST = 1; //EnablePWM2
- EPwm3Regs.TZCLR.bit.OST = 1; //EnablePWM3
- EPwm1Regs.TZCLR.bit.INT = 1;
- EDIS;
- }
- void ClosePwm(void)
- {
- EALLOW;
- EPwm1Regs.TZFRC.bit.OST = 0x1; //disabPWMl
- EPwm2Regs.TZFRC.bit.OST = 0x1; //disabPWM2
- EPwm3Regs.TZFRC.bit.OST = 0x1; //disabPWM3
- EDIS;
- }
- void speed_direction(Uint16 hall,Uint16 hall_last){
- //防抖
- static int16 i = 0;
- static int16 j=0;
- if(hall_last == 2 && hall == 6 || hall_last == 6 && hall == 4 ||hall_last == 4 && hall == 5 ||hall_last == 5 && hall == 1||hall_last == 1 && hall == 3||hall_last == 3 && hall == 2)
- {
- i++;
- j--;
- if(j<0){
- j=0;
- }
- if(i>5){
- i = 6;
- Direction = 1;
- }
- }
- else if(hall_last == 4 && hall == 6 || hall_last == 6 && hall == 2 ||hall_last == 2 && hall == 3 ||hall_last == 3 && hall == 1||hall_last == 1 && hall == 5|| hall_last == 5 && hall == 4)
- {
- i--;
- if(i<0){
- i=0;
- }
- j++;
- if(j>5){
- j= 6;
- Direction = -1;
- }
- }
- }
- void speed_cal_filter(void){
- int32 RotarRPMNew = 0;
- int32 RotarrpmOut = 0;
- static int32 last_speed = 0;
- static int32 last_RotarRPMNew = 0;
- Uint16 Halltemp = (Uint16)((GpioDataRegs.GPADAT.all>>24)&0x00000007); /* read all three GPIOs at once*/
- static Uint16 Hall_1 = 0;
- //static Uint16 Hall_2 = 0;
- static int32 Hall_2_cnt = 0;
- int16 directiontemp = 0;
- if(CpuTimer1.RegsAddr->TCR.bit.TIF == 1){
- // 速度为0
- XintTime = TIMER1_PER;
- Xint2Cnt = 1;
- RotarRPMNew =0;
- last_speed = 0;
- CpuTimer1.RegsAddr->TCR.bit.TIF = 1;//写1清零
- }else{
- if(Halltemp == hall1.HallGpioAccepted){
- Hall_2_cnt++;
- if(Hall_2_cnt>MAINLOOPFREQ/2){//0.5s
- Hall_2_cnt = MAINLOOPFREQ/2+1;
- }
- }else{
- Hall_2_cnt = 0;
- }
- if(XintTime == TIMER1_PER || Hall_2_cnt>=5000){
- RotarRPMNew = 0;
- last_speed = 0;
- }else{
- RotarRPMNew =(int32)360000000/XintTime;
- }
- }
- test2 = RotarRPMNew;
- if(Xint2Cnt == 1){
- //防止突然反向
- Xint2Cnt = 0;
- if(Hall_1 == 2 && Halltemp == 6 || Hall_1 == 6 && Halltemp == 4 ||Hall_1 == 4 && Halltemp == 5 ||Hall_1 == 5 && Halltemp == 1||Hall_1 == 1 && Halltemp == 3||Hall_1 == 3 && Halltemp == 2)
- {
- directiontemp = 1;
- }
- else if(Hall_1 == 4 && Halltemp == 6 || Hall_1 == 6 && Halltemp == 2 ||Hall_1 == 2 && Halltemp == 3 ||Hall_1 == 3 && Halltemp == 1||Hall_1 == 1 && Halltemp == 5|| Hall_1 == 5 && Halltemp == 4)
- {
- directiontemp = -1;
- }
- if((Direction ==1 && directiontemp == -1 )||(Direction == -1 && directiontemp == 1 )){
- //说明在振动
- RotarRPMNew = 0;
- last_speed = 0;
- }
- Hall_1 = Halltemp;
- test4 = Halltemp;
- }
- if(_IQabs(RotarRPMNew - last_RotarRPMNew)>1500 &&(_IQabs(RotarRPMNew)<300 ||_IQabs(last_RotarRPMNew)<300) ){
- //在0转速附近有大的阶跃
- test3 = RotarRPMNew;
- RotarRPMNew = 0;
- last_speed = 0;
- }
- /* if(RotarRPMNew - last_RotarRPMNew>500){
- RotarRPMNew = last_RotarRPMNew+4;
- }else if(RotarRPMNew - last_RotarRPMNew<-500){
- RotarRPMNew = last_RotarRPMNew-4;
- }*/
- last_RotarRPMNew = RotarRPMNew;
- RotarrpmOut = lowpassfilter(last_speed,RotarRPMNew,_IQ12(0.1),_IQ12(0.125));
- last_speed = RotarrpmOut;
- speed1.Speed = _IQdiv(RotarrpmOut,speed1.BaseRpm);
- speed1.SpeedRpm = RotarrpmOut;
- // }
- }
- void speed_cal(void){
- int32 RotarRPMNew = 0;
- int32 RotarrpmOut = 0;
- static int32 RotarrpmSum = 0;
- static int32 RotarrpmArr[8] = {0,0,0,0,0,0,0,0};
- static int16 k = 0;
- if(CpuTimer1.RegsAddr->TCR.bit.TIF == 1){
- // 速度为0
- XintTime = TIMER1_PER;
- Xint2Cnt = 1;
- CpuTimer1.RegsAddr->TCR.bit.TIF = 1;//写1清零
- int count = 0;
- for(count = 0;count<8;count++){
- RotarrpmArr[count] = 0;
- }
- RotarrpmSum = 0;
- RotarRPMNew =0;
- }else{
- RotarRPMNew =(int32)360000000/XintTime;
- }
- if(Xint2Cnt == 1){
- Xint2Cnt = 0;
- RotarrpmArr[k] = RotarRPMNew;
- RotarrpmSum += RotarrpmArr[k];
- RotarrpmOut = RotarrpmSum>>3;
- k++;
- if (k >= 8)
- {
- k = 0;
- }
- RotarrpmSum -= RotarrpmArr[k];
- speed1.Speed = _IQdiv(RotarrpmOut,speed1.BaseRpm);
- speed1.SpeedRpm = RotarrpmOut;
- }
- }
- void pwmlimit_speed(void){
- if(_IQabs(speed1.SpeedRpm)< 200){
- Uint16 index = _IQabs(speed1.SpeedRpm)/50;
- pwmlimit = (Uint32)(_IQabs(speed1.SpeedRpm)-index*50)*(pwm_limit_table1[index+1] - pwm_limit_table1[index])/50+pwm_limit_table1[index];
- }else if(_IQabs(speed1.SpeedRpm)< 3500){
- Uint16 index = _IQabs(speed1.SpeedRpm)/100;
- if(speed1.SpeedRpm>0){
- pwmlimit = (Uint32)(_IQabs(speed1.SpeedRpm)-index*100)*(pwm_limit_table2[index+1] - pwm_limit_table2[index])/100+pwm_limit_table2[index];
- }else{
- pwmlimit = (Uint32)(_IQabs(speed1.SpeedRpm)-index*100)*(pwm_limit_table_neg[index+1] - pwm_limit_table_neg[index])/100+pwm_limit_table_neg[index];
- }
- }else{
- if(speed1.SpeedRpm>0){
- pwmlimit = pwm_limit_table2[36];//最大值
- }else{
- pwmlimit = pwm_limit_table_neg[36];//最大值
- }
- }
- }
- void taskfree(void){
- if(SerialCommsTimer>(MAINLOOPFREQ/4)){
- GpioDataRegs.GPATOGGLE.bit.GPIO22 = 1;
- SerialCommsTimer = 0;
- DCbus_voltage = AdcResult.ADCRESULT4/10;// U = Uadc * 0.099964
- _iq20 kb = _IQ20(18.26);
- Tvot = ((Uint32)AdcResult.ADCRESULT7 *kscaler - kb)>>20;
- int32 R = 10000;//分压电阻
- int32 Rtadc = AdcResult.ADCRESULT6;
- Rt= Rtadc*R/(4096-Rtadc);
- if(Rt>32116){
- Tmotor = 0;
- }
- else if(Rt>15652){
- Tmotor = (_IQ12(-0.901)*Rt/1000 + _IQ12(28.381))>>12;
- }else if(Rt>6523){
- Tmotor = (_IQ12(-2.5013)*Rt/1000 + _IQ12(50.657))>>12;
- }else if(Rt>2968){
- Tmotor = (_IQ12(-6.3342)*Rt/1000 + _IQ12(73.203))>>12;
- }else if(Rt>1228){
- Tmotor = (_IQ12(-16.002)*Rt/1000 + _IQ12(98.576))>>12;
- }else if(Rt > 657){
- Tmotor = (_IQ12(-38.551)*Rt/1000 + _IQ12(124.83))>>12;
- }else if(Rt > 324){
- Tmotor = (_IQ12(-81.812)*Rt/1000 + _IQ12(150.67))>>12;
- }else{
- Tmotor = 125;
- }
- }
- }
- int16 MastIsrTimePercent(void)
- {
- Uint32 T1 = 0;
- int16 MasterIsrT =0;
- static int32 T1_L = 60000000;
- T1 = CpuTimer2.RegsAddr->TIM.all;
- if(T1_L < T1){
- MasterIsrT = (Uint32)(T1_L +CpuTimer2.RegsAddr->PRD.all -T1)* 100 /9000;
- }else{
- MasterIsrT = (Uint32)(T1_L-T1)* 100 /9000;
- }
- T1_L = T1;
- // MasterIsrT = (Uint32)MasterIsrT* 100 /3000;
- return MasterIsrT;
- }
- void mainLoop(void){
- Uint32 T1 = 0;
- Uint32 T2 = 0;
- T1 = CpuTimer2.RegsAddr->TIM.all;
- CanMaster();
- SerialCommsTimer++;
- if(SerialCommsTimer>0x3FFF){
- SerialCommsTimer = 0x3FFF;
- }
- ServiceDog();
- //speed_cal();
- speed_cal_filter();
- pwmlimit_speed();
- taskfree();
- FaultTreat();
- // =============================== LEVEL 4 ======================================
- // Level 4 verifies the closed current loop and current PI controller.
- // ==============================================================================
- //-------------平均电流和can-------------------------------
- static _iq last_DC_current=0;
- static Uint16 DC_Current_cnt = 0;
- //static int32 DC_Current_sum = 0;
- static int32 DC_Current_sum_filter = 0;
- int32 dt = _IQ12(0.1);
- int32 cutoff = _IQ12(1);
- DC_current_real = (Uint32)AdcResult.ADCRESULT5*33;//Q12 I真实 = adc * 3.3 / 4096 /0.1
- DC_current_filer = lowpassfilter(last_DC_current,DC_current_real,cutoff,dt);
- last_DC_current = DC_current_filer;
- DC_Current_sum_filter += DC_current_filer*pwm1.DutyFunc>>15;
- DC_Current_cnt++;//由于stall最多16384/20K秒 所以最多0.819715秒计算一次平均值
- if(hallCmtnTrig==1){
- hallCmtnTrig = 0;
- DC_current_filter_avr = DC_Current_sum_filter/DC_Current_cnt;
- DC_Current_sum_filter =0;
- DC_Current_cnt = 0;
- }
- carveData1();
- CanCurve();
- UserCANprocess();
- #if (BUILDLEVEL==LEVEL5)
- // ------------------------------------------------------------------------------
- // ADC conversion and offset adjustment (observing back-emfs is optinal for this prj.)
- // ------------------------------------------------------------------------------
- BemfA = AdcResult.ADCRESULT1;
- BemfB = AdcResult.ADCRESULT2;
- BemfC = AdcResult.ADCRESULT3;
- pid1_spd.Ref = SpeedRef;//rc1.SetpointValue;
- pid1_spd.Fbk = speed1.Speed;
- if(EnableFlag == 0 || FaultFlag.all !=0){
- Enable_ALLOW = FALSE;
- }else{
- Enable_ALLOW = TRUE;
- }
- if(Enable_ALLOW == FALSE){
- resetPI(&pid1_spd);
- rmp2.DesiredInput = 0;
- RC2_MACRO(&rmp2);
- pwm1.DutyFuncIn = (int16)_IQtoIQ15(rmp2.Out); // controlled speed duty-cycle
- }else{
- pid1_spd.Umax = _IQ((float)pwmlimit/32767);
- pid1_spd.Umin = _IQ((float)(-pwmlimit)/32767);
- PI_MACRO(&pid1_spd);
- int16 pwmtmp =(int16)_IQtoIQ15(pid1_spd.Out);
- //pwmtmp = test;//上位机开环控制
- pwm1.DutyFuncIn = ((int32)pwmtmp*LimitMotCtrTemp(600000))>>15;//1分钟降一次
- if(pwm1.DutyFuncIn>pwmlimit){
- pwm1.DutyFuncIn = pwmlimit; // controlled speed duty-cycle
- }else if(pwm1.DutyFuncIn<-pwmlimit){
- pwm1.DutyFuncIn = -pwmlimit; // controlled speed duty-cycle
- }
- rmp2.Out = pwm1.DutyFuncIn;
- }
- #endif // (BUILDLEVEL==LEVEL5)
- //程序占用率
- //IsrTime = MastIsrTimePercent();
- T2 = CpuTimer2.RegsAddr->TIM.all;
- if(T1 < T2){
- IsrTime = (Uint32)(T1 +CpuTimer2.RegsAddr->PRD.all -T2)* 100 /7500;
- }else{
- IsrTime = (Uint32)(T1-T2)* 100 /7500;
- }
- }
- void bldcpwm_close(void){
- EPwm1Regs.AQCSFRC.bit.CSFA = 1; /* Forcing a continuous Low on output A of EPWM3 */
- EPwm1Regs.AQCSFRC.bit.CSFB = 1; /* Forcing a continuous Low on output B of EPWM3 */
- EPwm2Regs.AQCSFRC.bit.CSFA = 1; /* Forcing a continuous Low on output A of EPWM3 */
- EPwm2Regs.AQCSFRC.bit.CSFB = 1; /* Forcing a continuous Low on output B of EPWM3 */
- EPwm3Regs.AQCSFRC.bit.CSFA = 1; /* Forcing a continuous Low on output A of EPWM3 */
- EPwm3Regs.AQCSFRC.bit.CSFB = 1; /* Forcing a continuous Low on output B of EPWM3 */
- }
|