HVBLDC_Sensored.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890
  1. /* ==============================================================================
  2. System Name: HVBLDC_Sensored
  3. File Name: HVBLDC_Sensored.C
  4. Description: Primary system file for the (Trapezoidal) Sensored BLDC Control
  5. Using Hall Effect Sensors
  6. ===================================================================================*/
  7. // Include header files used in the main function
  8. #include "PeripheralHeaderIncludes.h"
  9. #define MATH_TYPE IQ_MATH
  10. #include "IQmathLib.h"
  11. #include "HVBLDC_Sensored.h"
  12. #include "HVBLDC_Sensored-Settings.h"
  13. #include <math.h>
  14. #include "UserCan.h"
  15. #include "lowpass.h"
  16. #include "var.h"
  17. #ifdef FLASH
  18. #pragma CODE_SECTION(MainISR,"ramfuncs");
  19. void MemCopy();
  20. void InitFlash();
  21. #endif
  22. #define TIMER1_S1 60
  23. #define TIMER1_S2 500000
  24. #define TIMER1_PER 30000000
  25. #define MAINLOOPDIV 5 // 主中断40K 40K/MAINLOOPDIV 主循环
  26. // Prototype statements for functions found within this file.
  27. interrupt void MainISR(void);//主中断
  28. interrupt void xint1_isr(void);//FO中断
  29. interrupt void xint2_isr(void);//HALL A中断
  30. interrupt void EPWM1TZint_isr(void);//TZ中断 过流中断
  31. void DeviceInit();
  32. void HVDMC_Protection(void);
  33. void speed_direction(Uint16 hall,Uint16 hall_last);//使用中断计算转速
  34. void speed_cal(void);//使用中断计算转速
  35. void pwmlimit_speed(void);//
  36. void ClosePwm(void);
  37. void bldcpwm_close(void);
  38. void OpenPwm(void);
  39. void mainLoop(void);
  40. // State Machine function prototypes
  41. //------------------------------------
  42. int16 MastIsrTimePercent(void);
  43. void taskfree(void);
  44. void ServiceDog(void);
  45. void EnableDog(void);
  46. // Used for running BackGround in flash, and ISR in RAM
  47. //速度计算相关
  48. int16 t4 = 0;
  49. int16 Xint2Cnt = 0;
  50. int16 hallCmtnTrig = 0;
  51. extern Uint16 *RamfuncsLoadStart, *RamfuncsLoadEnd, *RamfuncsRunStart;
  52. int16 SerialCommsTimer;
  53. // Global variables used in this system
  54. HALL3 hall1 = HALL3_DEFAULTS;
  55. SPEED_MEAS_CAP speed1 = SPEED_MEAS_CAP_DEFAULTS;
  56. PWMGEN pwm1 = PWMGEN_DEFAULTS;
  57. _iq20 kscaler = _IQ20(90*3.3/4096/2.3);
  58. float32 T = 0.001/ISR_FREQUENCY; // Samping period (sec), see parameter.h
  59. Uint16 BackTicker = 0;
  60. Uint16 PreviousState;
  61. Uint16 ClosedFlag = 0;
  62. Uint32 VirtualTimer = 0;
  63. Uint16 ILoopFlag = FALSE;
  64. Uint16 SpeedLoopFlag = FALSE;
  65. int16 DFuncDesired = 0x0300; // Desired duty cycle (Q15)
  66. int16 DfuncTesting = 500;//0x0300;//占空比
  67. int16 Delay30 = 0x3FFF;
  68. int16 DelayFlag = 0;
  69. Uint16 AlignFlag = 0x000F;
  70. Uint16 LoopCount = 0;
  71. Uint16 TripFlagDMC=0; //PWM trip status
  72. #if (BUILDLEVEL<= LEVEL2)
  73. Uint32 CmtnPeriodTarget = 0x00000500;
  74. Uint32 CmtnPeriodSetpt = 0x00002000;//要大于CmtnPeriodTarget才能使用--
  75. Uint32 RampDelay = 10;
  76. #else
  77. Uint32 CmtnPeriodTarget = 0x00000450;
  78. Uint32 CmtnPeriodSetpt = 0x00001500;
  79. Uint32 RampDelay = 10;
  80. #endif
  81. _iq DCbus_current=0;
  82. _iq Speedgd=0;
  83. _iq tempIdc=0;
  84. int32 Rt;
  85. Uint16 ch1=0;
  86. Uint16 ch2=0;
  87. Uint16 ch3=0;
  88. // Used for ADC Configuration
  89. int ChSel[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  90. int TrigSel[16] = {5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5};
  91. int ACQPS[16] = {8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8};
  92. // Instance PI regulator to regulate the DC-bus current and speed
  93. // Instance a PWM driver instance
  94. // Instance a PWM DAC driver instance
  95. PWMDAC pwmdac1 = PWMDAC_DEFAULTS;
  96. // Instance a Hall effect driver
  97. // Instance a ramp controller to smoothly ramp the frequency
  98. // Instance a RAMP2 Module
  99. RMP2 rmp2 = RMP2_DEFAULTS;
  100. // Instance a RAMP3 Module
  101. RMP3 rmp3 = RMP3_DEFAULTS;
  102. // Instance a MOD6 Module
  103. MOD6CNT mod1 = MOD6CNT_DEFAULTS;
  104. // Instance a IMPULSE Module
  105. IMPULSE impl1 = IMPULSE_DEFAULTS;
  106. // Instance a SPEED_PR Module
  107. // Create an instance of DATALOG Module 950:3A 但是只有外界扭矩低于36N才能启动起来
  108. Uint16 pwm_limit_table1[5] = {950,1300,1650,1930,2320};//0 50 100 150 200
  109. //// 0, 100, 200, 300, 400 500 600 700 800 900 1000
  110. /*Uint16 pwm_limit_table2[]= {950,1650,2320,3050,3750,4460,5200,5929,6623,7358,8050,
  111. 8744,9400,10165,10848,11600,12290,12953,13684,14310,15050,
  112. 15760,16434,17054,17750,18493,19134,19830,20507,21260,21926,
  113. 22602,23232,23935,24609,25240};*/
  114. Uint16 pwm_limit_table2[]= {950,1650,2320,2985,3668,4348,5024,5705,6383,7058,7739,
  115. 8449,9122,9800,10480,11163,11826,12499,13181,13860,14515,
  116. 15192,15872,16530,17203,17861,18537,19183,19848,20525,21161,
  117. 21838,22488,23216,23850,24507,24507};
  118. //// 0, 100, 200, 300, 400 500 600 700 800 900 1000
  119. Uint16 pwm_limit_table_neg[]= {950,1616,2272,2961,3641,4305,4983,5659,6326,6994,7670,
  120. 8348,9022,9700,10361,11502,11714,12379,13066,13727,14426,//1100-2000
  121. 15085,15610,16325,17005,17660,18338,19000,19693,20390,21048,
  122. 21706,22428,23104,22823,24434,24434};
  123. /*Uint16 pwm_limit_table_neg[]= {950,1650,2320,3050,3750,4476,5200,5830,6520,7200,7808,
  124. 8500,9206,9800,10510,11200,11930,12579,13229,13892,14540,
  125. 15209,15920,16616,17291,18000,18775,19424,20507,21260,21926,
  126. 22602,23232,23935,24609,25240};*/
  127. int32 pwmlimitrate = 24507;
  128. Uint32 IsrTicker=0;
  129. void main(void)
  130. {
  131. DeviceInit(); // Device Life support & GPIO
  132. InitCan();
  133. // Only used if running from FLASH
  134. // Note that the variable FLASH is defined by the compiler
  135. #ifdef FLASH
  136. // Copy time critical code and Flash setup code to RAM
  137. // The RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart
  138. // symbols are created by the linker. Refer to the linker files.
  139. MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);
  140. // Call Flash Initialization to setup flash waitstates
  141. // This function must reside in RAM
  142. InitFlash(); // Call the flash wrapper init function
  143. #endif //(FLASH)
  144. // Initialize all the Device Peripherals:
  145. // This function is found in DSP280x_CpuTimers.c
  146. InitCpuTimers();
  147. // Configure CPU-Timer 0 to interrupt every ISR Period:
  148. // 60MHz CPU Freq, ISR Period (in uSeconds)
  149. // This function is found in DSP280x_CpuTimers.c
  150. ConfigCpuTimer(&CpuTimer0, 60, 1000/ISR_FREQUENCY);//40K
  151. StartCpuTimer0();
  152. // Configure CPU-Timer 1,2 for background loops
  153. ConfigCpuTimer(&CpuTimer1, TIMER1_S1, TIMER1_S2);//2hz
  154. ConfigCpuTimer(&CpuTimer2, 60, 1000000);//20HZ
  155. StartCpuTimer1();
  156. StartCpuTimer2();
  157. // Reassign ISRs.
  158. // Reassign the PIE vector for TINT0 to point to a different
  159. // ISR then the shell routine found in DSP280x_DefaultIsr.c.
  160. // This is done if the user does not want to use the shell ISR routine
  161. // but instead wants to use their own ISR.
  162. EALLOW; // This is needed to write to EALLOW protected registers
  163. PieVectTable.TINT0 = &MainISR;//40KHZ
  164. PieVectTable.XINT1 = &xint1_isr;
  165. PieVectTable.XINT2 = &xint2_isr;
  166. PieVectTable.EPWM1_TZINT = &EPWM1TZint_isr;
  167. EDIS; // This is needed to disable write to EALLOW protected registers
  168. // Enable PIE group 1 interrupt 7 for TINT0
  169. PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
  170. PieCtrlRegs.PIEIER1.bit.INTx4 = 1; // Enable PIE Gropu 1 INT4 //XINT1
  171. PieCtrlRegs.PIEIER1.bit.INTx5 = 1; // Enable PIE Gropu 1 INT5 //XINT2
  172. // Enable CPU INT1 for TINT0:
  173. IER |= M_INT1;
  174. PieCtrlRegs.PIEIER2.bit.INTx1 = 1;
  175. IER |= M_INT2;
  176. // Enable Global realtime interrupt DBGM
  177. EALLOW;
  178. GpioIntRegs.GPIOXINT1SEL.bit.GPIOSEL = 16; //定位到哪个引脚中断
  179. GpioIntRegs.GPIOXINT2SEL.bit.GPIOSEL = 24; // XINT2 is GPIO24
  180. EDIS;
  181. XIntruptRegs.XINT1CR.bit.POLARITY = 0; // 1为上升沿,0和2为下降沿,3为双边沿
  182. XIntruptRegs.XINT2CR.bit.POLARITY = 3; // 1为上升沿,0和2为下降沿,3为双边沿
  183. //中断配置步骤-----1,开启模块中断使能,
  184. XIntruptRegs.XINT1CR.bit.ENABLE = 1;
  185. XIntruptRegs.XINT2CR.bit.ENABLE = 1; // Enable XINT2
  186. // Enable global Interrupts and higher priority real-time debug events:
  187. EINT; // Enable Global interrupt INTM
  188. ERTM; // Enable Global realtime interrupt DBGM
  189. // Initialize PWM module
  190. pwm1.PeriodMax = (SYSTEM_FREQUENCY/PWM_FREQUENCY)*1000/2; // Asymmetric PWM 20kHZ 3000
  191. pwm1.DutyFunc = 0; // 占空比ALIGN_DUTY/32767 // DutyFunc = Q15
  192. BLDCPWM_INIT_MACRO(1,2,3,&pwm1);
  193. // Initialize PWMDAC module
  194. pwmdac1.PeriodMax = 500; // @60Mhz, 1500->20kHz, 1000-> 30kHz, 500->60kHz
  195. pwmdac1.HalfPerMax = pwmdac1.PeriodMax/2; // Needed to adjust the duty cycle range in the macro
  196. PWMDAC_INIT_MACRO(6,pwmdac1) ; // PWM 6A,6B
  197. PWMDAC_INIT_MACRO(7,pwmdac1) ; // PWM 7A,7B
  198. // Initialize Hall module
  199. hall1.DebounceAmount = 1;
  200. hall1.Revolutions = 1;
  201. HALL3_INIT_MACRO(&hall1);//读hall值 初始化HallGpioBuffer,HallGpioAccepted
  202. // Initialize the SPEED_PR module
  203. speed1.InputSelect = 0;
  204. speed1.BaseRpm = (Uint32)120*BASE_FREQ/POLES;//(Uint32)120*BASE_FREQ/POLES/6;//// 使用一个换相周期//额定转速 = 60*(基频/(极数/2)) = 60*f/极对数
  205. speed1.SpeedScaler = (Uint32)((Uint32)ISR_FREQUENCY*10000/BASE_FREQ);//保留一位小数//40000/f
  206. // For the kits < Rev 1.1 -------------------------------------------------
  207. ChSel[0]=15; // Dummy meas. avoid 1st sample issue Rev0 Picollo
  208. ChSel[1]=2; // ChSelect: ADC B7-> Phase A Voltage
  209. ChSel[2]=3; // ChSelect: ADC B6-> Phase B Voltage
  210. ChSel[3]=4; // ChSelect: ADC B4-> Phase C Voltage
  211. ChSel[4]=7; // ChSelect: ADC A2-> DC Bus vol
  212. ChSel[5]=6; // DC current 放大20倍 Imeasure = I*5mΩ*20
  213. ChSel[6]=5; // NTC
  214. ChSel[7]=1; // VOT
  215. //-------------------------------------------------------------------------
  216. ADC_MACRO_INIT(ChSel,TrigSel,ACQPS);
  217. // Initialize RMP2 module
  218. rmp2.Out = (int32)0;
  219. rmp2.Ramp2Delay = 0x00000001;
  220. rmp2.Ramp2Max = 32767/2;
  221. rmp2.Ramp2Min = -32768/2;
  222. // Initialize RMP3 module
  223. rmp3.DesiredInput = CmtnPeriodTarget;
  224. rmp3.Ramp3Delay = RampDelay;
  225. rmp3.Out = CmtnPeriodSetpt;
  226. rmp3.Ramp3Min = 0x00000010;
  227. InitVar();
  228. //Call HVDMC Protection function
  229. HVDMC_Protection();
  230. EnableDog();
  231. // IDLE loop. Just sit and loop forever:
  232. for(;;) //infinite loop
  233. {
  234. if(IsrTicker%MAINLOOPDIV ==0)
  235. {//8Khz
  236. mainLoop();
  237. }
  238. }
  239. } //END MAIN CODE
  240. //=================================================================================
  241. // STATE-MACHINE SEQUENCING AND SYNCRONIZATION FOR SLOW BACKGROUND TASKS
  242. //=================================================================================
  243. // ==============================================================================
  244. // =============================== MAIN ISR =====================================
  245. // ==============================================================================
  246. interrupt void MainISR(void)
  247. {
  248. //--------------------------------------------------------------------------------------
  249. // Verifying the ISR
  250. IsrTicker++;
  251. IsrTicker = (IsrTicker>20000)? 0 : IsrTicker;
  252. VirtualTimer++;
  253. VirtualTimer &= 0x00007FFF;
  254. HALL3_READ_MACRO(&hall1);
  255. ClosedFlag = TRUE;
  256. if (ClosedFlag==TRUE)
  257. {
  258. if (hall1.CmtnTrigHall==0x7FFF)
  259. {
  260. hallCmtnTrig = 1;
  261. speed_direction(hall1.HallGpioAccepted,PreviousState);
  262. if (hall1.HallGpioAccepted==5)
  263. {
  264. pwm1.CmtnPointerIn = 5;
  265. }
  266. else if (hall1.HallGpioAccepted==1)
  267. { pwm1.CmtnPointerIn = 0;
  268. }
  269. else if (hall1.HallGpioAccepted==3)
  270. { pwm1.CmtnPointerIn = 1;
  271. }
  272. else if (hall1.HallGpioAccepted==2)
  273. { pwm1.CmtnPointerIn = 2;
  274. }
  275. else if (hall1.HallGpioAccepted==6)
  276. { pwm1.CmtnPointerIn = 3;
  277. }
  278. else if (hall1.HallGpioAccepted==4)
  279. {
  280. pwm1.CmtnPointerIn = 4;
  281. }
  282. PreviousState = hall1.HallGpioAccepted;
  283. } // delay
  284. } // ClosedFlag==TRUE
  285. if(Enable_ALLOW == 0 && pwm1.DutyFunc==0){
  286. bldcpwm_close();
  287. }else{
  288. BLDCPWM_MACRO(1,2,3,&pwm1);
  289. }
  290. // Acknowledge interrupt to recieve more interrupts from PIE group 1
  291. CpuTimer0.RegsAddr->TCR.bit.TIF=1;
  292. PieCtrlRegs.PIEACK.bit.ACK1 = 1;
  293. //PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
  294. }// ISR Ends Here
  295. /**********************************************************/
  296. /***************Protection Configuration*******************/
  297. /**********************************************************/
  298. void HVDMC_Protection(void)
  299. {
  300. // Configure Trip Mechanism for the Motor control software
  301. // -Cycle by cycle trip on CPU halt
  302. // -One shot IPM trip zone trip
  303. // These trips need to be repeated for EPWM1 ,2 & 3
  304. //===========================================================================
  305. //Motor Control Trip Config, EPwm1,2,3
  306. //===========================================================================
  307. EALLOW;
  308. // CPU Halt Trip 使能TZ6周期触发,周期触发可以自动清零 但是一次触发不能自动清零
  309. // EPwm1Regs.TZSEL.bit.CBC6=0x1;//Enable TZ6 as a CBC trip source for this ePWM module
  310. // EPwm2Regs.TZSEL.bit.CBC6=0x1;
  311. // EPwm3Regs.TZSEL.bit.CBC6=0x1;
  312. //使能故障的单次触发
  313. EPwm1Regs.TZSEL.bit.OSHT1 = 1; //enable TZ1 for OSHT
  314. EPwm2Regs.TZSEL.bit.OSHT1 = 1; //enable TZ1 for OSHT
  315. EPwm3Regs.TZSEL.bit.OSHT1 = 1; //enable TZ1 for OSHT
  316. EPwm1Regs.TZEINT.bit.OST = 1;
  317. // What do we want the OST/CBC events to do?
  318. // TZA events can force EPWMxA
  319. // TZB events can force EPWMxB
  320. //故障发生时的输出状态为低
  321. EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWMxA will go low
  322. EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // EPWMxB will go low
  323. EPwm2Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWMxA will go low
  324. EPwm2Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // EPWMxB will go low
  325. EPwm3Regs.TZCTL.bit.TZA = TZ_FORCE_LO; // EPWMxA will go low
  326. EPwm3Regs.TZCTL.bit.TZB = TZ_FORCE_LO; // EPWMxB will go low
  327. EDIS;
  328. // Clear any spurious OV trip 清除标志位
  329. EPwm1Regs.TZCLR.bit.OST = 1;
  330. EPwm2Regs.TZCLR.bit.OST = 1;
  331. EPwm3Regs.TZCLR.bit.OST = 1;
  332. //************************** End of Prot. Conf. ***************************//
  333. }
  334. //速度计算中断
  335. interrupt void xint2_isr(void)
  336. {
  337. static int32 last_XintTime = TIMER1_PER;
  338. static Uint32 last_hall = 0;
  339. Uint32 temp = 0;
  340. if(CpuTimer1.RegsAddr->TCR.bit.TIF == 1){
  341. // 速度为0
  342. XintTime = (int32)TIMER1_PER;
  343. CpuTimer1.RegsAddr->TCR.bit.TIF = 1;//写1清中断标志位
  344. }else{
  345. XintTime = (int32)TIMER1_PER - CpuTimer1.RegsAddr->TIM.all;
  346. }
  347. XintTime = (int32)TIMER1_PER - CpuTimer1.RegsAddr->TIM.all;
  348. temp = (GpioDataRegs.GPADAT.all>>24)&0x00000007; /* read all three GPIOs at once*/
  349. if(_IQabs(XintTime)<30000 || temp == last_hall ){
  350. //filter 防抖
  351. XintTime = last_XintTime;
  352. PieCtrlRegs.PIEACK.bit.ACK1 =1;
  353. return ;
  354. }
  355. if(Direction == -1){
  356. XintTime = -XintTime;
  357. }
  358. Xint2Cnt = 1;
  359. last_XintTime = XintTime;
  360. last_hall = temp;
  361. CpuTimer1.RegsAddr->TCR.bit.TRB = 1; //重新装载
  362. CpuTimer1.RegsAddr->TCR.bit.TSS = 0;//定时器restart
  363. PieCtrlRegs.PIEACK.bit.ACK1 =1;
  364. }
  365. interrupt void xint1_isr(void)
  366. {
  367. FaultFlag.bit.Ipmfault = 1;
  368. PieCtrlRegs.PIEACK.bit.ACK1 =1;
  369. // PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
  370. }
  371. interrupt void EPWM1TZint_isr(void)
  372. {
  373. //過流
  374. FaultFlag.bit.OverCurFlag = 1;
  375. EALLOW;
  376. // EPwm1Regs.TZCLR.bit.OST = 1;
  377. // EPwm1Regs.TZCLR.bit.INT = 1;
  378. EDIS;
  379. PieCtrlRegs.PIEACK.bit.ACK2 = 1;//PIEACK_GROUP2;
  380. }
  381. void ServiceDog(void)
  382. {
  383. EALLOW;
  384. SysCtrlRegs.WDKEY = 0x0055;
  385. SysCtrlRegs.WDKEY = 0x00AA;
  386. EDIS;
  387. }
  388. //---------------------------------------------------------------------------
  389. // Example: DisableDog:
  390. //---------------------------------------------------------------------------
  391. // This function disables the watchdog timer.
  392. //---------------------------------------------------------------------------
  393. // 使能看门狗
  394. //---------------------------------------------------------------------------
  395. void EnableDog(void)
  396. {
  397. EALLOW;
  398. SysCtrlRegs.WDCR= 0x0028;
  399. EDIS;
  400. }
  401. void OpenPwm(void)
  402. {
  403. EALLOW;
  404. EPwm1Regs.TZCLR.bit.OST = 1; //EnablePWM1
  405. EPwm2Regs.TZCLR.bit.OST = 1; //EnablePWM2
  406. EPwm3Regs.TZCLR.bit.OST = 1; //EnablePWM3
  407. EPwm1Regs.TZCLR.bit.INT = 1;
  408. EDIS;
  409. }
  410. void ClosePwm(void)
  411. {
  412. EALLOW;
  413. EPwm1Regs.TZFRC.bit.OST = 0x1; //disabPWMl
  414. EPwm2Regs.TZFRC.bit.OST = 0x1; //disabPWM2
  415. EPwm3Regs.TZFRC.bit.OST = 0x1; //disabPWM3
  416. EDIS;
  417. }
  418. void speed_direction(Uint16 hall,Uint16 hall_last){
  419. //防抖
  420. static int16 i = 0;
  421. static int16 j=0;
  422. 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)
  423. {
  424. i++;
  425. j--;
  426. if(j<0){
  427. j=0;
  428. }
  429. if(i>5){
  430. i = 6;
  431. Direction = 1;
  432. }
  433. }
  434. 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)
  435. {
  436. i--;
  437. if(i<0){
  438. i=0;
  439. }
  440. j++;
  441. if(j>5){
  442. j= 6;
  443. Direction = -1;
  444. }
  445. }
  446. }
  447. void speed_cal_filter(void){
  448. int32 RotarRPMNew = 0;
  449. int32 RotarrpmOut = 0;
  450. static int32 last_speed = 0;
  451. static int32 last_RotarRPMNew = 0;
  452. Uint16 Halltemp = (Uint16)((GpioDataRegs.GPADAT.all>>24)&0x00000007); /* read all three GPIOs at once*/
  453. static Uint16 Hall_1 = 0;
  454. //static Uint16 Hall_2 = 0;
  455. static int32 Hall_2_cnt = 0;
  456. int16 directiontemp = 0;
  457. if(CpuTimer1.RegsAddr->TCR.bit.TIF == 1){
  458. // 速度为0
  459. XintTime = TIMER1_PER;
  460. Xint2Cnt = 1;
  461. RotarRPMNew =0;
  462. last_speed = 0;
  463. CpuTimer1.RegsAddr->TCR.bit.TIF = 1;//写1清零
  464. }else{
  465. if(Halltemp == hall1.HallGpioAccepted){
  466. Hall_2_cnt++;
  467. if(Hall_2_cnt>MAINLOOPFREQ/2){//0.5s
  468. Hall_2_cnt = MAINLOOPFREQ/2+1;
  469. }
  470. }else{
  471. Hall_2_cnt = 0;
  472. }
  473. if(XintTime == TIMER1_PER || Hall_2_cnt>=5000){
  474. RotarRPMNew = 0;
  475. last_speed = 0;
  476. }else{
  477. RotarRPMNew =(int32)360000000/XintTime;
  478. }
  479. }
  480. test2 = RotarRPMNew;
  481. if(Xint2Cnt == 1){
  482. //防止突然反向
  483. Xint2Cnt = 0;
  484. 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)
  485. {
  486. directiontemp = 1;
  487. }
  488. 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)
  489. {
  490. directiontemp = -1;
  491. }
  492. if((Direction ==1 && directiontemp == -1 )||(Direction == -1 && directiontemp == 1 )){
  493. //说明在振动
  494. RotarRPMNew = 0;
  495. last_speed = 0;
  496. }
  497. Hall_1 = Halltemp;
  498. test4 = Halltemp;
  499. }
  500. if(_IQabs(RotarRPMNew - last_RotarRPMNew)>1500 &&(_IQabs(RotarRPMNew)<300 ||_IQabs(last_RotarRPMNew)<300) ){
  501. //在0转速附近有大的阶跃
  502. test3 = RotarRPMNew;
  503. RotarRPMNew = 0;
  504. last_speed = 0;
  505. }
  506. /* if(RotarRPMNew - last_RotarRPMNew>500){
  507. RotarRPMNew = last_RotarRPMNew+4;
  508. }else if(RotarRPMNew - last_RotarRPMNew<-500){
  509. RotarRPMNew = last_RotarRPMNew-4;
  510. }*/
  511. last_RotarRPMNew = RotarRPMNew;
  512. RotarrpmOut = lowpassfilter(last_speed,RotarRPMNew,_IQ12(0.1),_IQ12(0.125));
  513. last_speed = RotarrpmOut;
  514. speed1.Speed = _IQdiv(RotarrpmOut,speed1.BaseRpm);
  515. speed1.SpeedRpm = RotarrpmOut;
  516. // }
  517. }
  518. void speed_cal(void){
  519. int32 RotarRPMNew = 0;
  520. int32 RotarrpmOut = 0;
  521. static int32 RotarrpmSum = 0;
  522. static int32 RotarrpmArr[8] = {0,0,0,0,0,0,0,0};
  523. static int16 k = 0;
  524. if(CpuTimer1.RegsAddr->TCR.bit.TIF == 1){
  525. // 速度为0
  526. XintTime = TIMER1_PER;
  527. Xint2Cnt = 1;
  528. CpuTimer1.RegsAddr->TCR.bit.TIF = 1;//写1清零
  529. int count = 0;
  530. for(count = 0;count<8;count++){
  531. RotarrpmArr[count] = 0;
  532. }
  533. RotarrpmSum = 0;
  534. RotarRPMNew =0;
  535. }else{
  536. RotarRPMNew =(int32)360000000/XintTime;
  537. }
  538. if(Xint2Cnt == 1){
  539. Xint2Cnt = 0;
  540. RotarrpmArr[k] = RotarRPMNew;
  541. RotarrpmSum += RotarrpmArr[k];
  542. RotarrpmOut = RotarrpmSum>>3;
  543. k++;
  544. if (k >= 8)
  545. {
  546. k = 0;
  547. }
  548. RotarrpmSum -= RotarrpmArr[k];
  549. speed1.Speed = _IQdiv(RotarrpmOut,speed1.BaseRpm);
  550. speed1.SpeedRpm = RotarrpmOut;
  551. }
  552. }
  553. void pwmlimit_speed(void){
  554. if(_IQabs(speed1.SpeedRpm)< 200){
  555. Uint16 index = _IQabs(speed1.SpeedRpm)/50;
  556. pwmlimit = (Uint32)(_IQabs(speed1.SpeedRpm)-index*50)*(pwm_limit_table1[index+1] - pwm_limit_table1[index])/50+pwm_limit_table1[index];
  557. }else if(_IQabs(speed1.SpeedRpm)< 3500){
  558. Uint16 index = _IQabs(speed1.SpeedRpm)/100;
  559. if(speed1.SpeedRpm>0){
  560. pwmlimit = (Uint32)(_IQabs(speed1.SpeedRpm)-index*100)*(pwm_limit_table2[index+1] - pwm_limit_table2[index])/100+pwm_limit_table2[index];
  561. }else{
  562. pwmlimit = (Uint32)(_IQabs(speed1.SpeedRpm)-index*100)*(pwm_limit_table_neg[index+1] - pwm_limit_table_neg[index])/100+pwm_limit_table_neg[index];
  563. }
  564. }else{
  565. if(speed1.SpeedRpm>0){
  566. pwmlimit = pwm_limit_table2[36];//最大值
  567. }else{
  568. pwmlimit = pwm_limit_table_neg[36];//最大值
  569. }
  570. }
  571. }
  572. void taskfree(void){
  573. if(SerialCommsTimer>(MAINLOOPFREQ/4)){
  574. GpioDataRegs.GPATOGGLE.bit.GPIO22 = 1;
  575. SerialCommsTimer = 0;
  576. DCbus_voltage = AdcResult.ADCRESULT4/10;// U = Uadc * 0.099964
  577. _iq20 kb = _IQ20(18.26);
  578. Tvot = ((Uint32)AdcResult.ADCRESULT7 *kscaler - kb)>>20;
  579. int32 R = 10000;//分压电阻
  580. int32 Rtadc = AdcResult.ADCRESULT6;
  581. Rt= Rtadc*R/(4096-Rtadc);
  582. if(Rt>32116){
  583. Tmotor = 0;
  584. }
  585. else if(Rt>15652){
  586. Tmotor = (_IQ12(-0.901)*Rt/1000 + _IQ12(28.381))>>12;
  587. }else if(Rt>6523){
  588. Tmotor = (_IQ12(-2.5013)*Rt/1000 + _IQ12(50.657))>>12;
  589. }else if(Rt>2968){
  590. Tmotor = (_IQ12(-6.3342)*Rt/1000 + _IQ12(73.203))>>12;
  591. }else if(Rt>1228){
  592. Tmotor = (_IQ12(-16.002)*Rt/1000 + _IQ12(98.576))>>12;
  593. }else if(Rt > 657){
  594. Tmotor = (_IQ12(-38.551)*Rt/1000 + _IQ12(124.83))>>12;
  595. }else if(Rt > 324){
  596. Tmotor = (_IQ12(-81.812)*Rt/1000 + _IQ12(150.67))>>12;
  597. }else{
  598. Tmotor = 125;
  599. }
  600. }
  601. }
  602. int16 MastIsrTimePercent(void)
  603. {
  604. Uint32 T1 = 0;
  605. int16 MasterIsrT =0;
  606. static int32 T1_L = 60000000;
  607. T1 = CpuTimer2.RegsAddr->TIM.all;
  608. if(T1_L < T1){
  609. MasterIsrT = (Uint32)(T1_L +CpuTimer2.RegsAddr->PRD.all -T1)* 100 /9000;
  610. }else{
  611. MasterIsrT = (Uint32)(T1_L-T1)* 100 /9000;
  612. }
  613. T1_L = T1;
  614. // MasterIsrT = (Uint32)MasterIsrT* 100 /3000;
  615. return MasterIsrT;
  616. }
  617. void mainLoop(void){
  618. Uint32 T1 = 0;
  619. Uint32 T2 = 0;
  620. T1 = CpuTimer2.RegsAddr->TIM.all;
  621. CanMaster();
  622. SerialCommsTimer++;
  623. if(SerialCommsTimer>0x3FFF){
  624. SerialCommsTimer = 0x3FFF;
  625. }
  626. ServiceDog();
  627. //speed_cal();
  628. speed_cal_filter();
  629. pwmlimit_speed();
  630. taskfree();
  631. FaultTreat();
  632. // =============================== LEVEL 4 ======================================
  633. // Level 4 verifies the closed current loop and current PI controller.
  634. // ==============================================================================
  635. //-------------平均电流和can-------------------------------
  636. static _iq last_DC_current=0;
  637. static Uint16 DC_Current_cnt = 0;
  638. //static int32 DC_Current_sum = 0;
  639. static int32 DC_Current_sum_filter = 0;
  640. int32 dt = _IQ12(0.1);
  641. int32 cutoff = _IQ12(1);
  642. DC_current_real = (Uint32)AdcResult.ADCRESULT5*33;//Q12 I真实 = adc * 3.3 / 4096 /0.1
  643. DC_current_filer = lowpassfilter(last_DC_current,DC_current_real,cutoff,dt);
  644. last_DC_current = DC_current_filer;
  645. DC_Current_sum_filter += DC_current_filer*pwm1.DutyFunc>>15;
  646. DC_Current_cnt++;//由于stall最多16384/20K秒 所以最多0.819715秒计算一次平均值
  647. if(hallCmtnTrig==1){
  648. hallCmtnTrig = 0;
  649. DC_current_filter_avr = DC_Current_sum_filter/DC_Current_cnt;
  650. DC_Current_sum_filter =0;
  651. DC_Current_cnt = 0;
  652. }
  653. carveData1();
  654. CanCurve();
  655. UserCANprocess();
  656. #if (BUILDLEVEL==LEVEL5)
  657. // ------------------------------------------------------------------------------
  658. // ADC conversion and offset adjustment (observing back-emfs is optinal for this prj.)
  659. // ------------------------------------------------------------------------------
  660. BemfA = AdcResult.ADCRESULT1;
  661. BemfB = AdcResult.ADCRESULT2;
  662. BemfC = AdcResult.ADCRESULT3;
  663. pid1_spd.Ref = SpeedRef;//rc1.SetpointValue;
  664. pid1_spd.Fbk = speed1.Speed;
  665. if(EnableFlag == 0 || FaultFlag.all !=0){
  666. Enable_ALLOW = FALSE;
  667. }else{
  668. Enable_ALLOW = TRUE;
  669. }
  670. if(Enable_ALLOW == FALSE){
  671. resetPI(&pid1_spd);
  672. rmp2.DesiredInput = 0;
  673. RC2_MACRO(&rmp2);
  674. pwm1.DutyFuncIn = (int16)_IQtoIQ15(rmp2.Out); // controlled speed duty-cycle
  675. }else{
  676. pid1_spd.Umax = _IQ((float)pwmlimit/32767);
  677. pid1_spd.Umin = _IQ((float)(-pwmlimit)/32767);
  678. PI_MACRO(&pid1_spd);
  679. int16 pwmtmp =(int16)_IQtoIQ15(pid1_spd.Out);
  680. //pwmtmp = test;//上位机开环控制
  681. pwm1.DutyFuncIn = ((int32)pwmtmp*LimitMotCtrTemp(600000))>>15;//1分钟降一次
  682. if(pwm1.DutyFuncIn>pwmlimit){
  683. pwm1.DutyFuncIn = pwmlimit; // controlled speed duty-cycle
  684. }else if(pwm1.DutyFuncIn<-pwmlimit){
  685. pwm1.DutyFuncIn = -pwmlimit; // controlled speed duty-cycle
  686. }
  687. rmp2.Out = pwm1.DutyFuncIn;
  688. }
  689. #endif // (BUILDLEVEL==LEVEL5)
  690. //程序占用率
  691. //IsrTime = MastIsrTimePercent();
  692. T2 = CpuTimer2.RegsAddr->TIM.all;
  693. if(T1 < T2){
  694. IsrTime = (Uint32)(T1 +CpuTimer2.RegsAddr->PRD.all -T2)* 100 /7500;
  695. }else{
  696. IsrTime = (Uint32)(T1-T2)* 100 /7500;
  697. }
  698. }
  699. void bldcpwm_close(void){
  700. EPwm1Regs.AQCSFRC.bit.CSFA = 1; /* Forcing a continuous Low on output A of EPWM3 */
  701. EPwm1Regs.AQCSFRC.bit.CSFB = 1; /* Forcing a continuous Low on output B of EPWM3 */
  702. EPwm2Regs.AQCSFRC.bit.CSFA = 1; /* Forcing a continuous Low on output A of EPWM3 */
  703. EPwm2Regs.AQCSFRC.bit.CSFB = 1; /* Forcing a continuous Low on output B of EPWM3 */
  704. EPwm3Regs.AQCSFRC.bit.CSFA = 1; /* Forcing a continuous Low on output A of EPWM3 */
  705. EPwm3Regs.AQCSFRC.bit.CSFB = 1; /* Forcing a continuous Low on output B of EPWM3 */
  706. }