Advertisement
Guest User

Untitled

a guest
May 23rd, 2019
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 27.37 KB | None | 0 0
  1. // This is code for Local Energy Storage Isolated Full Bridge Converter by Lithium Balance A/S
  2.  
  3. #include "DSP28x_Project.h" // Device Headerfile and Examples Include File
  4.  
  5. // Prototype statements for functions found within this file.
  6. void InitEPwmModules(void);
  7. void InitGpioModules(void);
  8. void UpdateDuty(void);
  9. void InitAdcModules();
  10. __interrupt void adc_isr(void);
  11. void InitOurECan(void);
  12. interrupt void ecan1intB_isr(void);
  13. void ControlLoop(void);
  14. void DisableGateDrivers(void);
  15. void SafetyCheck(void);
  16. void SafeDisable(void);
  17. void TurnLedsOn(void);
  18. void SetupECan(void);
  19. void CheckCan(void);
  20. //void mailbox_read(int16 MBXnbr);
  21. void mailbox_read(void);
  22. void RequestRefChange(float NewRef);
  23.  
  24. Uint16 TurnOnMargin, TurnOffMargin, TurnOnDelay; //Safety margins for syncr. rectification.
  25. Uint16 Wa1, Wb1, Wa2, Wb2; //Duty in clock cycles
  26. Uint16 ConversionCount, ControlCounter, ErrorFlag;
  27. Uint16 ControlCounter2;//Counter to make CAN communicate at a lower rate.
  28. Uint16 FBBMode; //Mode variable to indicate currently used mode
  29. Uint16 Transition; //Transition flag between modes
  30.  
  31. int message[8];
  32.  
  33. float32 Kp;
  34. float32 Vs[4];
  35. // Include current sense
  36.  
  37.  
  38. float32 VsAvg, VRequestAvg;
  39. float32 ISense[4]; // From version 1 - Current sensing
  40.  
  41. // Buck or Boost Mode
  42. int mode; // 1 = BOOST 0 = BUCK
  43.  
  44. Uint16 Wa1Dummy;
  45. float32 ISenseAvg;
  46. float32 VRef;
  47. float32 IRef;
  48. float32 FirstDelay, SecondDelay, ThirdDelay, FirstSum, SecondSum; //Compensator values
  49. float32 DutyFBB;
  50. float32 AntiWindupDelay;
  51. float32 udgang, indgang, indgang_delay, udgang_delay;
  52.  
  53. // For current control (06-05-2019)
  54. float32 y,y1,y2,x,x1,x2;
  55.  
  56. float32 Itest;
  57.  
  58. struct ECAN_REGS ECanbShadow;
  59.  
  60. //The following are given in clock cycles
  61. #define EPWM1_PERIOD 750//500//1000//750
  62. #define DUTY_MAX 375 // 80% duty -> 600 50% duty -> 375 (Changed 03/05-2019)
  63. #define DUTY_FBB_MIN 0
  64. #define DUTY_BOOST_MIN -3000
  65.  
  66. #define DUTY_BUCK_MIN 75 // 10% duty
  67. #define DUTY_BUCK_MAX 675 // 90% duty
  68.  
  69. // Converter Specifics
  70. #define TURNS_RATIO 5
  71.  
  72. // Safety Limits
  73. #define VS_MAX 650
  74. #define V_REQUEST_MIN -100
  75. #define V_REQUEST_MAX 600
  76. #define IREF_MAX 3
  77.  
  78. // Slow PI (working)
  79. //#define A_1 1
  80. //#define B_0 2.379e-1
  81. //#define B_1 2.364e-1
  82.  
  83. // Slow PI-controller by Christian and Anders (03/05-2019)
  84. //#define A_1 1
  85. //#define B_0 0.003504
  86. //#define B_1 0.003447
  87. /*
  88. *
  89. * 0.008096 z - 0.008025
  90. ---------------------
  91. z - 1
  92. *
  93. */
  94.  
  95. /* Current controller for boost
  96. *0.987 - 1.937 z^-1 + 0.9502z^-2
  97. ----------------------------
  98. 1 - 1.519 z^-1 + 0.5186z^-2
  99. *
  100.  
  101. 0.02748 - 0.02728z^-1
  102. -------------------
  103. 1 - z^-1
  104. */
  105. #define A1 1.519
  106. #define A2 0.5186
  107. #define B0 0.987
  108. #define B1 1.937
  109. #define B2 0.9502
  110.  
  111.  
  112. //Anti-windup.
  113. #define AWCoeff 4
  114.  
  115. int32 debugvar = 0;
  116.  
  117. void main(void)
  118. {
  119. //Initialize System Control
  120. InitSysCtrl();
  121.  
  122. //Initialize GPIO:
  123. InitGpio();
  124. //Clear all interrupts and initialize PIE vector table:
  125. // Disable CPU interrupts
  126. DINT;
  127. // Initialize PIE control registers to their default state.
  128. InitPieCtrl();
  129.  
  130. // Disable CPU interrupts and clear all CPU interrupt flags:
  131. IER = 0x0000;
  132. IFR = 0x0000;
  133.  
  134. InitPieVectTable();
  135.  
  136. //GPIO - Fan and Disable pin
  137. InitGpioModules();
  138.  
  139. //ePWM
  140. TurnOffMargin = 0;//Phase offset between ePwm1 and 2 (clock cycles)
  141. TurnOnMargin = 30; // Possible to reduce this to 15
  142.  
  143. TurnOnDelay = TurnOffMargin + TurnOnMargin;
  144. InitEPwmModules();
  145.  
  146. //ADC
  147. InitAdcModules();
  148.  
  149. //CAN
  150. SetupECan();
  151.  
  152. //Initial values stored in delays
  153. VRef = 0;
  154. FirstSum = 0.0;
  155. SecondSum = 0.0;
  156. FirstDelay = 0;
  157. SecondDelay = 0;
  158. ThirdDelay = 0;
  159. AntiWindupDelay = 0;
  160. ControlCounter = 0;
  161. ErrorFlag = 0;
  162. Kp = 1;
  163. Itest = 0;
  164. Wa1Dummy = 0;
  165.  
  166.  
  167.  
  168. // Selecting mode
  169. mode = 1; // BOOST = 1 & BUCK = 0
  170. FBBMode = 1;
  171.  
  172. //Initial duty cycle
  173. DutyFBB = 0.0;
  174. UpdateDuty();
  175.  
  176. udgang = 0.0;
  177. indgang_delay = 0.0;
  178. udgang_delay = 0.0;
  179. indgang = 0.0;
  180.  
  181.  
  182. x = 0.0;
  183. x1 = 0.0;
  184. x2 = 0.0;
  185. y = 0.0;
  186. y1 = 0.0;
  187. y2 = 0.0;
  188. VRef = 1.3; // For current reference
  189.  
  190. for (;;)
  191. {
  192. asm(" NOP");
  193.  
  194. }
  195.  
  196. }
  197.  
  198. void InitAdcModules()
  199. {
  200. //Set ADC clock freq
  201. EALLOW;
  202. #if (CPU_FRQ_150MHZ) // Default - 150 MHz SYSCLKOUT
  203. #define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3) = 25.0 MHz
  204. #endif
  205. #if (CPU_FRQ_100MHZ)
  206. #define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2) = 25.0 MHz
  207. #endif
  208. SysCtrlRegs.HISPCP.all = ADC_MODCLK;
  209. EDIS;
  210.  
  211. //Mapping interrupts to our function
  212. EALLOW;
  213. PieVectTable.ADCINT = &adc_isr;
  214. EDIS;
  215. InitAdc();
  216.  
  217. // Enable ADCINT in PIE
  218. PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
  219. IER |= M_INT1; // Enable CPU Interrupt 1
  220. EINT;
  221. // Enable Global interrupt INTM
  222. ERTM;
  223. // Enable Global realtime interrupt DBGM
  224.  
  225. // Configure ADC
  226. AdcRegs.ADCMAXCONV.all = 0x0005; // Number of conversions = max conv + 1
  227. AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 8; // Setup ADCINB0 as 1st SEQ1 conv.
  228. AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 9; // Setup ADCINB1 as 2nd SEQ1 conv.
  229. AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 10;// B2 -> Vp-
  230. AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 11;// B3 -> Vs+
  231. AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 12;// B4 -> Vs-
  232. AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 13;// B5 -> Iref (not used)
  233. AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1; // Enable SOCA from ePWM to start SEQ1
  234. AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)
  235. }
  236.  
  237. void InitEPwmModules()
  238. {
  239.  
  240.  
  241. // ePWM 1: Primary Side FETs (Low-Side)
  242. EPwm1Regs.TBPRD = EPWM1_PERIOD; // Period
  243. EPwm1Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
  244. EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetrical mode
  245. EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Master module
  246. EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
  247. EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // TBCLK = SYSCLK
  248. EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
  249. EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down-stream module
  250. EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
  251. EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
  252. EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero
  253. EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero
  254.  
  255. // Real swicthing
  256.  
  257. EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // set actions for EPWM1A
  258. EPwm1Regs.AQCTLA.bit.CBD = AQ_CLEAR;
  259. EPwm1Regs.AQCTLB.bit.PRD = AQ_SET; // set actions for EPWM1B
  260. EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR;
  261. /*
  262.  
  263. //Forcing primary low
  264. EPwm1Regs.AQCTLA.bit.ZRO = AQ_CLEAR; // set actions for EPWM1A
  265. EPwm1Regs.AQCTLA.bit.CBD = AQ_CLEAR;
  266. EPwm1Regs.AQCTLB.bit.PRD = AQ_CLEAR; // set actions for EPWM1B
  267. EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR;
  268. */
  269.  
  270.  
  271. // ePWM 2: Secondary Side FETs (High-Side)
  272. EPwm2Regs.TBPRD = EPWM1_PERIOD; // Period
  273. EPwm2Regs.TBPHS.half.TBPHS = EPWM1_PERIOD - TurnOffMargin; // Sync to module1 with a phase delay
  274. EPwm2Regs.TBCTR = 0x0000; //Clear counter
  275. EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetrical mode
  276. EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; //Slave module
  277. EPwm2Regs.TBCTL.bit.PHSDIR = 0; //Count down after sync
  278. EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
  279. EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // TBCLK = SYSCLK
  280. EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
  281. EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down-stream module
  282.  
  283. EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
  284. EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
  285. EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero
  286. EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero
  287.  
  288. // Adding the switching scheme by Christian 07-05-2019
  289. EPwm2Regs.AQCTLB.bit.CBD = AQ_SET; // set actions for EPWM2A // Vi har byttet om på A og B !!!!!!!!!!!!!!!!
  290. EPwm2Regs.AQCTLB.bit.ZRO = AQ_CLEAR;
  291. EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // set actions for EPWM2B
  292. EPwm2Regs.AQCTLA.bit.PRD = AQ_CLEAR;
  293. /*
  294. //Forcing secondary side low:
  295. EPwm2Regs.AQCTLA.bit.CBU = AQ_CLEAR; // set actions for EPWM1A
  296. EPwm2Regs.AQCTLA.bit.PRD = AQ_CLEAR;
  297. EPwm2Regs.AQCTLB.bit.CAD = AQ_CLEAR; // set actions for EPWM1B
  298. EPwm2Regs.AQCTLB.bit.ZRO = AQ_CLEAR;
  299. */
  300.  
  301. // ePWM 3: MORTOR FET ( for boost mode only. not for FBB)
  302. EPwm3Regs.TBPRD = EPWM1_PERIOD; // Period
  303. EPwm3Regs.TBPHS.half.TBPHS = 0; // Sync to module2 with a phase delay , zero delay between module 2 and 3
  304. EPwm3Regs.TBCTR = 0x0000; //Clear counter
  305. EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Sawtooth mode
  306. EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE; //Slave module
  307. EPwm3Regs.TBCTL.bit.PHSDIR = 0; //Count down after sync
  308. EPwm3Regs.TBCTL.bit.PRDLD = TB_SHADOW;
  309. EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down-stream module
  310. EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // TBCLK = SYSCLK
  311. EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;
  312. EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
  313. EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
  314. EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero
  315. EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero
  316. EPwm3Regs.AQCTLA.bit.CBU = AQ_SET; // set actions for EPWM1A
  317. EPwm3Regs.AQCTLA.bit.PRD = AQ_CLEAR;
  318. EPwm3Regs.AQCTLB.bit.CAD = AQ_SET; // set actions for EPWM1B
  319. EPwm3Regs.AQCTLB.bit.ZRO = AQ_CLEAR;
  320.  
  321. //Forcing MORTOR FET low:
  322. EPwm3Regs.AQCTLA.bit.CBU = AQ_CLEAR; // set actions for EPWM1A
  323. EPwm3Regs.AQCTLA.bit.PRD = AQ_CLEAR;
  324. EPwm3Regs.AQCTLB.bit.CAD = AQ_CLEAR; // set actions for EPWM1B
  325. EPwm3Regs.AQCTLB.bit.ZRO = AQ_CLEAR;
  326.  
  327. // Version 2 ADC trigger
  328. //This PWM module triggers ADC_ISR
  329. //EPwm4Regs.TBPRD = EPWM1_PERIOD / 8; // Period, a factor of 8 gives 4 times higher freq
  330. EPwm4Regs.TBPRD = EPWM1_PERIOD / 16; // Period, a factor of 16 gives 8 times higher freq
  331. EPwm4Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
  332. EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetrical mode
  333. EPwm4Regs.TBCTL.bit.PHSEN = TB_DISABLE; //Master module
  334. EPwm4Regs.TBCTL.bit.PRDLD = TB_SHADOW;
  335. EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down-stream module
  336. EPwm4Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // TBCLK = SYSCLK
  337. EPwm4Regs.TBCTL.bit.CLKDIV = TB_DIV1;
  338. EPwm4Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
  339. EPwm4Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
  340. EPwm4Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero
  341. EPwm4Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero
  342.  
  343. //Triggering ADC
  344. EPwm4Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group
  345. EPwm4Regs.ETSEL.bit.SOCASEL = 1; // Select SOC from counter = 0
  346. EPwm4Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on every event
  347.  
  348. /*
  349. //This PWM module triggers ADC_ISR
  350. // samples at every other inductor period
  351. //EPwm4Regs.TBPRD = EPWM1_PERIOD / 8; // Period, a factor of 8 gives 4 times higher freq
  352. EPwm4Regs.TBPRD = EPWM1_PERIOD; // Same period as switching,
  353. EPwm4Regs.TBPHS.half.TBPHS = 0; // Phase is same as ePWM2
  354. EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetrical mode
  355. EPwm4Regs.TBCTL.bit.PHSEN = TB_ENABLE; //Master module
  356. EPwm4Regs.TBCTL.bit.PRDLD = TB_SHADOW;
  357. EPwm4Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; // Sync down-stream module
  358. EPwm4Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // TBCLK = SYSCLK
  359. EPwm4Regs.TBCTL.bit.CLKDIV = TB_DIV1;
  360. EPwm4Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
  361. EPwm4Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
  362. EPwm4Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero
  363. EPwm4Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero
  364.  
  365. //Triggering ADC
  366. EPwm4Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group
  367. EPwm4Regs.ETSEL.bit.SOCASEL = 4; // Starts ADC when pwm counter crosses CMPA (rising)
  368. EPwm4Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on every event
  369. */
  370.  
  371. //Enable pullup
  372. InitEPwm1Gpio();
  373. InitEPwm2Gpio();
  374. InitEPwm3Gpio();
  375. InitEPwm4Gpio();
  376. }
  377.  
  378. void InitGpioModules()
  379. {
  380. EALLOW;
  381.  
  382. //Disable pin on gate drivers
  383. GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0; // Enable pullup
  384. GpioDataRegs.GPASET.bit.GPIO16 = 0; // Set disable low
  385. GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 0;
  386. GpioCtrlRegs.GPADIR.bit.GPIO16 = 1; // Output
  387.  
  388. //Fan
  389. GpioCtrlRegs.GPAPUD.bit.GPIO8 = 0; // Enable pullup
  390. GpioDataRegs.GPASET.bit.GPIO8 = 1; // Turn on fan
  391. GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 0;
  392. GpioCtrlRegs.GPADIR.bit.GPIO8 = 1; // Output
  393.  
  394. //LED2, Green LED on MORTOR PCB
  395. GpioCtrlRegs.GPBPUD.bit.GPIO63 = 0; // Enable pullup
  396. GpioDataRegs.GPBSET.bit.GPIO63 = 1; // 1: Turn on LED
  397. GpioCtrlRegs.GPBMUX2.bit.GPIO63 = 0;
  398. GpioCtrlRegs.GPBDIR.bit.GPIO63 = 1; // Output
  399.  
  400. /*//LED 2
  401. GpioCtrlRegs.GPAPUD.bit.GPIO31 = 0; // Enable pullup
  402. GpioDataRegs.GPASET.bit.GPIO31 = 1; // 1: Turn off LED
  403. GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 0;
  404. GpioCtrlRegs.GPADIR.bit.GPIO31 = 1; // Output
  405.  
  406. //LED 3
  407. GpioCtrlRegs.GPBPUD.bit.GPIO34 = 0; // Enable pullup
  408. GpioDataRegs.GPBSET.bit.GPIO34 = 1; // 1: Turn off LED
  409. GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;
  410. GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // Output
  411. */
  412. EDIS;
  413. }
  414.  
  415. //Triggered by PWM, fastest
  416. __interrupt void adc_isr(void)
  417. {
  418. Vs[ConversionCount] = ((float32) (AdcRegs.ADCRESULT3 >> 4) - (float32) (AdcRegs.ADCRESULT4 >> 4)) * 0.2476 + 3.796;
  419.  
  420. // Isense is from version 1. By tuning I get: 0.025535375. 2. try: 0.025531375
  421. if(mode){
  422. ISense[ConversionCount] = ((float32) (AdcRegs.ADCRESULT0 >> 4)) * 0.025531375 - 51.92982456;
  423. }
  424. else{
  425. ISense[ConversionCount] = ((float32) (AdcRegs.ADCRESULT0 >> 4)) *0.025531375 - 52.32982456;
  426. }
  427.  
  428. //Vs = ((float32) (AdcRegs.ADCRESULT3 >> 4) - (float32) (AdcRegs.ADCRESULT4 >> 4)) * 0.2476 + 3.196;
  429. //ISense = ((float32) (AdcRegs.ADCRESULT0 >> 4)) *0.02569901316 - 51.92982456;
  430. // Reinitialize for next ADC sequence
  431. AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1
  432. AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit
  433. PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
  434.  
  435. if (ConversionCount == 3)
  436. {
  437. ConversionCount = 0;
  438. ControlLoop();
  439. }
  440. else
  441. {
  442. ConversionCount++;
  443. }
  444.  
  445. }
  446.  
  447. //Triggered by adc_isr, slower loop
  448. void ControlLoop(void)
  449. {
  450. int i;
  451. //Averaging the oversampled values
  452.  
  453. VsAvg = 0;
  454. ISenseAvg = 0;
  455. for (i = 0; i < 4; i++){
  456. VsAvg += Vs[i];
  457. ISenseAvg +=ISense[i];
  458. }
  459. VsAvg = VsAvg / 4;
  460. ISenseAvg = - ISenseAvg / 4;
  461. Itest = ISenseAvg;
  462.  
  463.  
  464. // Direct form II current controller:
  465. IRef = VRef; // The current is not equal the voltage, but it is only for the convenience of the eCan
  466.  
  467. if(IRef > IREF_MAX){
  468. IRef = IREF_MAX;
  469. }
  470. /*x = (IRef - ISenseAvg);
  471. y = (B0*x - B1*x1 + B2*x2 + A1*y1 - A2*y2); // PID-Controller
  472. //y = (B0*x - B1*x1 + A1*y1); // PI-controller
  473.  
  474. // Changing delay:
  475.  
  476. x2 = x1;
  477. x1 = x;
  478. y2 = y1;
  479. y1 = y;
  480.  
  481. DutyFBB = y;
  482. */
  483. DutyFBB = VRef; // Open loop test (03/05-2019) and (04/05-2019)
  484. UpdateDuty();
  485.  
  486.  
  487. //MAX code (working) VOltage control
  488.  
  489. //indgang = Kp*(VRef - VsAvg) + AntiWindupDelay;
  490.  
  491. /*
  492. indgang = Kp*(VRef - VsAvg);
  493. udgang = (indgang*B_0 -indgang_delay*B_1 + udgang_delay*A_1);
  494.  
  495. indgang_delay = indgang;
  496. udgang_delay = udgang;
  497. //AntiWindupDelay = (DutyFBB - udgang)/AWCoeff;
  498.  
  499.  
  500. DutyFBB = udgang;
  501. */
  502.  
  503. //Checking for CAN message at a lower rate
  504.  
  505. if(ControlCounter2 == 9999){
  506. ControlCounter2 = 0;
  507. CheckCan();
  508. }
  509. ControlCounter2++;
  510. }
  511.  
  512. //Set DutyFBB right before calling this method
  513. void UpdateDuty(){
  514.  
  515. //DutyFBB = DutyFBB*750; // Only for controls
  516.  
  517. if(mode){
  518. if(DutyFBB > DUTY_MAX){
  519. DutyFBB = DUTY_MAX;
  520. }else if(DutyFBB < DUTY_FBB_MIN){
  521. DutyFBB = DUTY_FBB_MIN;
  522. }
  523. }
  524. else{
  525. if(DutyFBB > DUTY_BUCK_MAX){
  526. // DutyFBB > DUTY_BUCK_MAX;
  527. }else if(DutyFBB < DUTY_BUCK_MIN){
  528. DutyFBB = DUTY_BUCK_MIN;
  529. }
  530. }
  531.  
  532. Wa1 = (Uint16)DutyFBB;
  533. Wb1 = EPWM1_PERIOD - Wa1;
  534. //Wa2 = EPWM1_PERIOD - TurnOnDelay - Wa1;
  535. //Wb2 = EPWM1_PERIOD + TurnOnDelay - Wb1;
  536.  
  537. EPwm1Regs.CMPA.half.CMPA = Wa1; // A duty changed from Wa1 to DUTY_TEST (02-05-2019)
  538. EPwm1Regs.CMPB = Wb1; // B duty changed from Wb1 to DUTY_TEST (02-05-2019)
  539. EPwm2Regs.CMPA.half.CMPA = Wa1;
  540. EPwm2Regs.CMPB = Wb1;
  541.  
  542. }
  543.  
  544. void CheckCan(void)
  545. {
  546. if(ECanbRegs.CANRMP.all != 0x00000000){
  547. ECanbRegs.CANRMP.all = 0x00010000;
  548.  
  549. //Uncommented because interrupts handle this
  550. //mailbox_read();//16);
  551. }
  552. }
  553.  
  554.  
  555. void mailbox_read(void)
  556. {
  557. /*
  558. void mailbox_read(int16 MBXnbr)
  559. volatile struct MBOX *MailboxB;
  560.  
  561. MailboxB = &ECanbMboxes.MBOX0 + MBXnbr;
  562. TestMboxB1 = MailboxB->MDL.all; // = 0x9555AAAn (n is the MBX number)
  563. TestMboxB2 = MailboxB->MDH.all; // = 0x89ABCDEF (a constant)
  564. TestMboxB3 = MailboxB->MSGID.all;// = 0x9555AAAn (n is the MBX number)
  565.  
  566. if(MBXnbr == 16) // mailbox #1 receive message
  567. {
  568. */
  569. message[0]= ECanbMboxes.MBOX16.MDL.byte.BYTE0; // read message
  570. message[1]= ECanbMboxes.MBOX16.MDL.byte.BYTE1;
  571. message[2]= ECanbMboxes.MBOX16.MDL.byte.BYTE2;
  572. message[3]= ECanbMboxes.MBOX16.MDL.byte.BYTE3;
  573. message[4]= ECanbMboxes.MBOX16.MDH.byte.BYTE4;
  574. message[5]= ECanbMboxes.MBOX16.MDH.byte.BYTE5;
  575. message[6]= ECanbMboxes.MBOX16.MDH.byte.BYTE6;
  576. message[7]= ECanbMboxes.MBOX16.MDH.byte.BYTE7;
  577. ECanbRegs.CANRMP.bit.RMP1 = 1;
  578.  
  579. RequestRefChange((float)(message[0]));
  580.  
  581. //}
  582.  
  583.  
  584. }
  585.  
  586. interrupt void ecan1intB_isr(void)
  587. {
  588. /*
  589. unsigned int mailbox_nr;
  590. // struct ECAN_REGS ECanbShadow; // local copy of CANA registers
  591. mailbox_nr = ECanbRegs.CANGIF1.bit.MIV1;
  592. if(mailbox_nr == 16) // mailbox #1 receive message
  593. {
  594. */
  595. message[0]= ECanbMboxes.MBOX16.MDL.byte.BYTE0; // read message
  596. message[1]= ECanbMboxes.MBOX16.MDL.byte.BYTE1;
  597.  
  598.  
  599. message[2]= ECanbMboxes.MBOX16.MDL.byte.BYTE2;
  600. /*
  601. message[3]= ECanbMboxes.MBOX16.MDL.byte.BYTE3;
  602. message[4]= ECanbMboxes.MBOX16.MDH.byte.BYTE4;
  603. message[5]= ECanbMboxes.MBOX16.MDH.byte.BYTE5;
  604. message[6]= ECanbMboxes.MBOX16.MDH.byte.BYTE6;
  605. message[7]= ECanbMboxes.MBOX16.MDH.byte.BYTE7;
  606. */
  607. ECanbRegs.CANRMP.bit.RMP1 = 1;
  608.  
  609. RequestRefChange((float)(message[0]<<8) + (float)(message[1]));
  610. Transition = message[2];
  611. //}
  612. PieCtrlRegs.PIEACK.bit.ACK9 = 1;
  613. }
  614.  
  615. void RequestRefChange(float NewRef)
  616. {
  617. //Setting the reference current
  618. if(NewRef > V_REQUEST_MAX){
  619. VRef = V_REQUEST_MAX;
  620. }else if(NewRef < V_REQUEST_MIN){
  621. VRef = V_REQUEST_MIN;
  622. }else{
  623. VRef = NewRef;
  624. }
  625. GpioDataRegs.GPBTOGGLE.bit.GPIO63 = 1;
  626.  
  627. }
  628.  
  629.  
  630. void DisableGateDrivers()
  631. {
  632. EALLOW;
  633. //Setting the disable pin on gate drivers high
  634. GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0; // Enable pullup
  635. GpioDataRegs.GPASET.bit.GPIO16 = 1; // Set disable high
  636. GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 0;
  637. GpioCtrlRegs.GPADIR.bit.GPIO16 = 1; // GPIO6: output
  638. EDIS;
  639. }
  640.  
  641. void SafetyCheck(void){
  642. if(VsAvg > VS_MAX){
  643. SafeDisable();
  644. }
  645.  
  646.  
  647.  
  648. }
  649.  
  650. void SafeDisable(void)
  651. {
  652. //Force ePWM duty to 0, (each switch is still on 50% of the time)
  653. ErrorFlag = 1;
  654.  
  655. //Force ePWM2 entirely off
  656. //EPwm2Regs.AQCTLA.bit.CBU = AQ_CLEAR; // set actions for EPWM1A
  657. //EPwm2Regs.AQCTLA.bit.PRD = AQ_CLEAR;
  658. //EPwm2Regs.AQCTLB.bit.CAD = AQ_CLEAR; // set actions for EPWM1B
  659. //EPwm2Regs.AQCTLB.bit.ZRO = AQ_CLEAR;
  660.  
  661. TurnLedsOn(); //Turns both LEDs on as a failure indicator
  662. }
  663.  
  664.  
  665. void TurnLedsOn(void){
  666. EALLOW;
  667. //LED 2
  668. GpioCtrlRegs.GPAPUD.bit.GPIO31 = 0; // Enable pullup
  669. GpioDataRegs.GPASET.bit.GPIO31 = 0; // 0: Turn on LED
  670. GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 0;
  671. GpioCtrlRegs.GPADIR.bit.GPIO31 = 1; // GPIO6: output
  672.  
  673. //LED 3
  674. GpioCtrlRegs.GPBPUD.bit.GPIO34 = 0; // Enable pullup
  675. GpioDataRegs.GPBSET.bit.GPIO34 = 0; // 0: Turn on LED
  676. GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0;
  677. GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // GPIO6: output
  678. EDIS;
  679. }
  680.  
  681. void InitOurECan(void)
  682. {
  683. EALLOW;
  684.  
  685. //
  686. // Enable internal pull-up for the selected CAN pins
  687. // Pull-ups can be enabled or disabled by the user.
  688. // This will enable the pullups for the specified pins.
  689. // Comment out other unwanted lines.
  690. //
  691. //GpioCtrlRegs.GPAPUD.bit.GPIO8 = 0; //Enable pull-up for GPIO8 (CANTXB)
  692. //GpioCtrlRegs.GPAPUD.bit.GPIO12 = 0; //Enable pull-up for GPIO12(CANTXB)
  693. //GpioCtrlRegs.GPAPUD.bit.GPIO16 = 0; //Enable pull-up for GPIO16(CANTXB)
  694. GpioCtrlRegs.GPAPUD.bit.GPIO20 = 0; //Enable pull-up for GPIO20(CANTXB)
  695.  
  696. //GpioCtrlRegs.GPAPUD.bit.GPIO10 = 0; // Enable pull-up for GPIO10(CANRXB)
  697. //GpioCtrlRegs.GPAPUD.bit.GPIO13 = 0; // Enable pull-up for GPIO13(CANRXB)
  698. //GpioCtrlRegs.GPAPUD.bit.GPIO17 = 0; // Enable pull-up for GPIO17(CANRXB)
  699. GpioCtrlRegs.GPAPUD.bit.GPIO21 = 0; // Enable pull-up for GPIO21(CANRXB)
  700.  
  701. //
  702. // Set qualification for selected CAN pins to asynch only
  703. // Inputs are synchronized to SYSCLKOUT by default.
  704. // This will select asynch (no qualification) for the selected pins.
  705. // Comment out other unwanted lines.
  706. //
  707. //GpioCtrlRegs.GPAQSEL1.bit.GPIO10 = 3; // Asynch qual for GPIO10 (CANRXB)
  708. //GpioCtrlRegs.GPAQSEL1.bit.GPIO13 = 3; // Asynch qual for GPIO13 (CANRXB)
  709. //GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; // Asynch qual for GPIO17 (CANRXB)
  710. GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 3; // Asynch qual for GPIO21 (CANRXB)
  711.  
  712. //
  713. // Configure eCAN-B pins using GPIO regs
  714. // This specifies which of the possible GPIO pins will be eCAN functional
  715. // pins.
  716. //
  717. //GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 2; // Configure GPIO8 for CANTXB
  718. //GpioCtrlRegs.GPAMUX1.bit.GPIO12 = 2; // Configure GPIO12 for CANTXB
  719. //GpioCtrlRegs.GPAMUX2.bit.GPIO16 = 2; // Configure GPIO16 for CANTXB
  720. GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 3; // Configure GPIO20 for CANTXB
  721.  
  722. //GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 2; // Configure GPIO10 for CANRXB
  723. //GpioCtrlRegs.GPAMUX1.bit.GPIO13 = 2; // Configure GPIO13 for CANRXB
  724. //GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 2; // Configure GPIO17 for CANRXB
  725. GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 3; // Configure GPIO21 for CANRXB
  726.  
  727. EDIS;
  728. }
  729.  
  730.  
  731.  
  732. void SetupECan(void)
  733. {
  734.  
  735. // eCAN control registers require read/write access using 32-bits. Thus we
  736. // will create a set of shadow registers for this example. These shadow
  737. // registers will be used to make sure the access is 32-bits and not 16.
  738.  
  739.  
  740. // Step 1. Initialize System Control:
  741. // PLL, WatchDog, enable Peripheral Clocks
  742. // This example function is found in the DSP2833x_SysCtrl.c file.
  743. //InitSysCtrl();
  744.  
  745. // Step 2. Initialize GPIO:
  746. // This example function is found in the DSP2833x_Gpio.c file and
  747. // illustrates how to set the GPIO to it's default state.
  748. //- InitGpio(); // Skipped for this example
  749.  
  750. // For this example, configure CAN pins using GPIO regs here
  751. // This function is found in DSP2833x_ECan.c
  752. //InitECanGpio();
  753. InitOurECan();
  754. // Step 3. Clear all interrupts and initialize PIE vector table:
  755. // Disable CPU interrupts
  756. //- DINT;
  757.  
  758. // Initialize PIE control registers to their default state.
  759. // The default state is all PIE interrupts disabled and flags
  760. // are cleared.
  761. // This function is found in the DSP2833x_PieCtrl.c file.
  762. //InitPieCtrl();
  763.  
  764. // Disable CPU interrupts and clear all CPU interrupt flags:
  765. IER = 0x0000;
  766. IFR = 0x0000;
  767.  
  768. // Initialize the PIE vector table with pointers to the shell Interrupt
  769. // Service Routines (ISR).
  770. // This will populate the entire table, even if the interrupt
  771. // is not used in this example. This is useful for debug purposes.
  772. // The shell ISR routines are found in DSP2833x_DefaultIsr.c.
  773. // This function is found in DSP2833x_PieVect.c.
  774. //InitPieVectTable();
  775.  
  776. // Step 4. Initialize all the Device Peripherals:
  777. // This function is found in DSP2833x_InitPeripherals.c
  778. // InitPeripherals(); // Not required for this example
  779.  
  780. // Step 5. User specific code, enable interrupts:
  781.  
  782.  
  783. InitECanb();
  784.  
  785.  
  786. //Interrupt stuff
  787. EALLOW;
  788. PieVectTable.ECAN1INTB = &ecan1intB_isr; // re - map CAN INT1
  789. ECanbShadow.CANMIM.all = 0;
  790. ECanbShadow.CANMIM.bit.MIM16 = 1; // MB#5 Mailbox interrupt is enabled
  791. ECanbRegs.CANMIM.all = ECanbShadow.CANMIM.all;
  792. ECanbShadow.CANMIL.all = 0;
  793. ECanbShadow.CANMIL.bit.MIL16 = 1; // Int.-Level MB#5 -> I1EN
  794. ECanbRegs.CANMIL.all = ECanbShadow.CANMIL.all;
  795. ECanbShadow.CANGIM.all = 0;
  796. ECanbShadow.CANGIM.bit.I1EN = 1; // enable I1EN
  797. ECanbRegs.CANGIM.all = ECanbShadow.CANGIM.all;
  798.  
  799. PieCtrlRegs.PIEIER9.bit.INTx8 = 1; // ECAN1INTB
  800. IER = 0x0101; // enable core line INT1
  801. EINT; // enable global interrupt INTM
  802. ERTM; // Enable global real time DBGM
  803. CpuTimer0Regs.TCR.bit.TSS = 0; // start T0
  804. EDIS;
  805.  
  806.  
  807. //Disable mailbox before changing
  808. ECanbRegs.CANME.all = 0x00000000;
  809.  
  810. // Mailboxes can be written to 16-bits or 32-bits at a time
  811. // Write to the MSGID field of TRANSMIT mailboxes MBOX0 - 15
  812. // Start ID field with 0x8
  813. ECanbMboxes.MBOX0.MSGID.all = 0x800001A4; //420
  814.  
  815. // Write to the MSGID field of RECEIVE mailboxes MBOX16 - 31
  816. ECanbMboxes.MBOX16.MSGID.all = 0x00240000;//shift ID by two bits when not using extended identifier (fx. ID = 9 -> write 36 (24 in hex))
  817.  
  818. // ECanbMboxes.MBOX18.MSGID.bit.AME = 1; //Acceptance mask enable
  819. // ECanbMboxes.MBOX18.MSGID.bit.IDE = 1; //we are using extended identifier
  820. // ECanbLAMRegs.LAM18.all = 0xFFFFFFFF; //Setting LAM bits high -> accepting all IDs
  821.  
  822. // Configure Mailboxes 0-15 as Tx, 16-31 as Rx
  823. // Since this write is to the entire register (instead of a bit
  824. // field) a shadow register is not required.
  825. ECanbRegs.CANMD.all = 0xFFFF0000;
  826.  
  827. // Enable all Mailboxes */
  828. // Since this write is to the entire register (instead of a bit
  829. // field) a shadow register is not required.
  830. ECanbRegs.CANME.all = 0xFFFFFFFF;
  831.  
  832.  
  833. // Specify that 8 bits will be sent/received
  834. ECanbMboxes.MBOX0.MSGCTRL.bit.DLC = 8;
  835. ECanbMboxes.MBOX16.MSGCTRL.bit.DLC = 8;
  836.  
  837. //Data to be transmitted
  838. // Write to the mailbox RAM field of MBOX0 - 15
  839. ECanbMboxes.MBOX0.MDL.all = 0;
  840. ECanbMboxes.MBOX0.MDH.all = 100;
  841.  
  842. // Since this write is to the entire register (instead of a bit
  843. // field) a shadow register is not required.
  844. EALLOW;
  845. ECanbRegs.CANMIM.all = 0xFFFFFFFF;
  846. EDIS;
  847.  
  848. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement