1. 程式人生 > >Digital Boost Converter Example for DSP

Digital Boost Converter Example for DSP

lec PE setting glob int mit ets PC 最大

  1 //###########################################################################
  2 //
  3 // Original Author: D.F.
  4 //
  5 // $TI Release: 2833x/2823x Header Files and Peripheral Examples V133 $
  6 // $Release Date: June 8, 2012 $
  7 //###########################################################################
8 9 #include "DSP28x_Project.h" 10 #include "math.h" 11 #include "stdlib.h" 12 #include "stdio.h" 13 14 // Prototype statements for functions found within this file. 15 16 //中斷副程式 17 interrupt void system_isr(void); 18 interrupt void uart_isr(void); 19 20 //其他副程式 21 void ADC_setup(void);
22 void GPIO_Select(void); 23 void InitEPwm1(void); //Battery開關20kHz使用 24 void InitEPwm6(void); //System中斷60kHz使用 25 void scia_echoback_init(void); 26 void scia_fifo_init(void); 27 void scia_xmit(int a); 28 void scia_msg(char *msg); 29 30 // Global variables 31 Uint16 LoopCount;
32 float timercount=0,sec=0; 33 float fsample = 60000; //60k 34 float Tsample=0.00001667; //除數被除數都要用float或double,不然會錯 35 36 //AD參數 37 float ADCa4=0,ADCa5=0,ADCa6=0,ADCa7=0; //給ADCa用的參數 38 float ADCb0=0,ADCb1=0,ADCb2=0,ADCb3=0,ADCb4=0,ADCb5=0,ADCb6=0,ADCb7=0; //給ADCb用的參數 39 40 //Battery Converter參數 41 float Digital_Vin_Battery=0,Digital_Iin_Battery=0,Digital_Vout_Battery=0,Digital_Iout_Battery=0; 42 float Actual_Vin_Battery=0, Actual_Iin_Battery=0,Actual_Vout_Battery=0, Actual_Iout_Battery=0; 43 float Actual_Pin=0, Actual_Pout=0,Actual_Eff; 44 float Vout_Battery_ref=250; //BUS Voltage=300V 45 float Battery_command=0.05; 46 float Vout_Battery_error=0, Battery_temp=0; 47 float kp_Battery=0.0005, ki_Battery=0.02; 48 49 //與電腦通訊的參數 50 int B0=0,B1=0,B2=0,B3=0,B4=0,B5=0,B6=0,B7=0; //10Hz中斷用來與電腦通訊的參數 51 //int Bb0=0,Bb1=0,Bb2=0,Bb3=0,Bb4=0,Bb5=0,Bb6=0,Bb7=0; 52 53 char *msg=0; 54 55 //***************主程式***************// 56 main() 57 { 58 // Step 1. Initialize System Control: 59 InitSysCtrl(); 60 61 //***************晶片頻率配置(150MHz)***************// 62 EALLOW; 63 #if (CPU_FRQ_150MHZ) // Default - 150 MHz SYSCLKOUT 64 #define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3) = 25.0 MHz 65 #endif 66 #if (CPU_FRQ_100MHZ) 67 #define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2) = 25.0 MHz 68 #endif 69 EDIS; 70 //***************System系統頻率配置(15MHz)***************// 71 EALLOW; 72 SysCtrlRegs.HISPCP.all = ADC_MODCLK; //Define ADCCLK clock frequency(ADC頻率為25MHz) 73 EDIS; 74 75 // Step 2. Initialize GPIO and UART: 76 InitGpio(); 77 InitSciaGpio(); 78 79 // Step 3. Clear all interrupts and initialize PIE vector table: 80 DINT; 81 InitPieCtrl(); 82 IER = 0x0000; // Disable CPU interrupts and clear all CPU interrupt flags 83 IFR = 0x0000; // Disable CPU interrupts and clear all CPU interrupt flags 84 InitPieVectTable(); // Initialize the PIE vector table with pointers to the shell Interrupt 85 86 //***************中斷向量表配置***************// //目前CpuTimer的中斷好像比EPWM6的中斷還優先,可能會有問題 87 EALLOW; // This is needed to write to EALLOW protected register 88 PieVectTable.ADCINT = &system_isr; //系統用PAW6中斷 89 // PieVectTable.TINT0 = &uart_isr; //UART用系統內部CPUT_IMER中斷 90 EDIS; // This is needed to disable write to EALLOW protected registers 91 92 // Step 4. Initialize all the Device Peripherals: 93 InitCpuTimers(); 94 InitAdc(); 95 ADC_setup(); 96 97 ConfigCpuTimer(&CpuTimer0,15,1000000); //決定CpuTimer0的中段時間,頻率為150M/15/1000=10kHz 98 CpuTimer0Regs.TCR.all=0x4000; 99 // Step 5. User specific code, enable interrupts: 100 101 // Enable ADCINT in PIE 102 PieCtrlRegs.PIEIER1.bit.INTx6 = 1; //INTx6 為EPWM6的中斷,因此靠EPWM6來做中斷副程式(可查中斷向量表) 103 // PieCtrlRegs.PIEIER1.bit.INTx7 = 1; //INTx7 為CpuTimer0的中斷,因此靠CpuTimer0來做中斷副程式(可查中斷向量表) 104 IER |= M_INT1; // Enable CPU Interrupt 1 105 EINT; // Enable Global interrupt INTM 106 ERTM; // Enable Global realtime interrupt DBGM 107 108 LoopCount = 0; 109 110 scia_fifo_init(); // Initialize the SCI FIFO 111 scia_echoback_init(); // Initalize SCI for echoback 112 InitEPwm1(); 113 InitEPwm6(); 114 GPIO_Select(); 115 116 // Wait for ADC interrupt 117 for(;;) 118 { 119 LoopCount++; 120 } 121 122 } 123 124 //***************系統中斷副程式以下***************// 125 interrupt void system_isr(void) 126 { 127 timercount++; 128 if(timercount==60000) sec++; 129 if(timercount>=60000) timercount=0; 130 131 //ADC取值 132 Digital_Vin_Battery = AdcRegs.ADCRESULT0 >>4; 133 Digital_Iin_Battery = AdcRegs.ADCRESULT1 >>4; 134 Digital_Vout_Battery = AdcRegs.ADCRESULT2 >>4; 135 Digital_Iout_Battery = AdcRegs.ADCRESULT3 >>4; 136 137 //計算實際值 ""3/4095=0.00073260073"" 數位轉到DSP收到的0-3V,再轉回實際值 138 Actual_Vin_Battery = (Digital_Vin_Battery/4095)*317; // 130為電壓最大值 139 Actual_Iin_Battery = (Digital_Iin_Battery-1.5*4095/3)*3/4095*12/3*2; // 12為電流最大值 *2因為電流有正負交流 140 Actual_Vout_Battery = (Digital_Vout_Battery/4095)*305; 141 Actual_Iout_Battery = (Digital_Iout_Battery-1.5*4095/3)*3/4095*5/3*2; 142 143 Actual_Pin=Actual_Vin_Battery*Actual_Iin_Battery; 144 Actual_Pout=Actual_Vout_Battery*Actual_Iout_Battery; 145 Actual_Eff=Actual_Pout/Actual_Pin*100; 146 Vout_Battery_error=Vout_Battery_ref-Actual_Vout_Battery; 147 148 //*****測試PWM用3V電阻分壓穩1.55V***// 149 // = Digital_Vout_Battery*3/4095; 150 //Vout_Battery_error=1.55-Actual_Vout_Battery; 151 152 if(1)//可以作300V+-?的判斷 153 { 154 Battery_temp=Battery_temp+Vout_Battery_error*Tsample; //積分 : 上次的量+誤差量*Tsample 155 if(Battery_temp<=-60) Battery_temp=-60; //限制暫存不要衝太快 156 if(Battery_temp>=60) Battery_temp=60; //限制暫存不要衝太快 157 Battery_command=kp_Battery*Vout_Battery_error+ki_Battery*Battery_temp; //kp*誤差+ki*積分誤差量 158 if(Battery_command<=0.05) Battery_command=0.05; //限制輸出不可超出此範圍 159 if(Battery_command>=0.8) Battery_command=0.8; //限制輸出不可超出此範圍 160 } 161 if(Actual_Vin_Battery>=8)//可以作保護判斷(進入else,關閉EPWM) 162 { 163 InitEPwm1Gpio(); 164 EPwm1Regs.CMPA.half.CMPA=Battery_command*3750; 165 166 //EPwm1Regs.CMPA.half.CMPA=Digital_Vin_Battery/4095*3750; //測試AD進來的數值直接轉成PWM 167 } 168 else //超過保戶限制,將PWM強制式設置成GPIO形式,並令為OFF,然後清除累積誤差 169 { 170 EALLOW; 171 GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; // Configure GPIO0 as GPIO0 (GPIO原本EPWM功能設為I/O輸出角位) 172 GpioCtrlRegs.GPADIR.bit.GPIO0=1; // 設定GPIO在輸入輸出模式時 : 0為輸入 1為輸出 (is used for output) 173 GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 0; // Configure GPIO1 as GPIO1 (GPIO原本EPWM功能設為I/O輸出角位) 174 GpioCtrlRegs.GPADIR.bit.GPIO1=1; // 設定GPIO在輸入輸出模式時 : 0為輸入 1為輸出 (is used for output) 175 EDIS; 176 GpioDataRegs.GPACLEAR.bit.GPIO0=1; //MOSFET turn off (Inverter兩臂4開關turn OFF) 177 GpioDataRegs.GPACLEAR.bit.GPIO1=1; //MOSFET turn off (Inverter兩臂4開關turn OFF) 178 //清除誤差的累積 179 Battery_temp=0; 180 Battery_command=0; 181 Vout_Battery_error=0; 182 GpioDataRegs.GPATOGGLE.bit.GPIO14=1; 183 } 184 // ADCa4 = AdcRegs.ADCRESULT4 >>4; 185 // ADCa5 = AdcRegs.ADCRESULT5 >>4; 186 // ADCa6 = AdcRegs.ADCRESULT6 >>4; 187 // ADCa7 = AdcRegs.ADCRESULT7 >>4; 188 // ADCb0 = AdcRegs.ADCRESULT8 >>4; 189 // ADCb1 = AdcRegs.ADCRESULT9 >>4; 190 // ADCb2 = AdcRegs.ADCRESULT10 >>4; 191 // ADCb3 = AdcRegs.ADCRESULT11 >>4; 192 // ADCb4 = AdcRegs.ADCRESULT12 >>4; 193 // ADCb5 = AdcRegs.ADCRESULT13 >>4; 194 // ADCb6 = AdcRegs.ADCRESULT14 >>4; 195 // ADCb7 = AdcRegs.ADCRESULT15 >>4; 196 197 GpioDataRegs.GPATOGGLE.bit.GPIO13=1; //因為60k才驅動一次,因此示波器看到的方波應該為30kHz 198 // Reinitialize for next ADC sequence 199 AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1; // Reset SEQ1 200 AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; // Clear INT SEQ1 bit 201 PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE 202 return; 203 } 204 //***************系統中斷副程式以上***************// 205 206 207 //***************UART中斷副程式以下***************// 208 interrupt void uart_isr(void) 209 { 210 CpuTimer0.InterruptCount++; 211 B0=Digital_Vin_Battery; //傳回電腦終端機的參數 212 B1=Digital_Iin_Battery; //傳回電腦終端機的參數 213 B2=Digital_Vout_Battery; //傳回電腦終端機的參數 214 B3=Digital_Iout_Battery; //傳回電腦終端機的參數 215 B4=ADCa4; //傳回電腦終端機的參數 216 B5=ADCa5; //傳回電腦終端機的參數 217 B6=ADCa6; //傳回電腦終端機的參數 218 B7=ADCa7; //傳回電腦終端機的參數 219 sprintf(msg,"\r\n A%4d B%4d C%4d D%4d E%4d F%4d G%4d H%4d \n\0",B0,B1,B2,B3,B4,B5,B6,B7); 220 scia_msg(msg); 221 //GpioDataRegs.GPATOGGLE.bit.GPIO14=1; //因為10Hz才驅動一次,因此示波器看到的方波應該為5Hz 222 PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; 223 } 224 //***************UART中斷副程式以上***************// 225 226 227 //***************GOIP設置以下***************// 228 void GPIO_Select(void) 229 { 230 //GPAMUX1:GPIO0 ~GPIO15 的設定 231 //GPAMUX2:GPIO16~GPIO31 的設定 232 233 EALLOW; 234 //GPIO13配置為System的系統中斷確認 235 GpioCtrlRegs.GPAMUX1.bit.GPIO13=0; // 0為GPIO一般輸入輸出 236 GpioCtrlRegs.GPADIR.bit.GPIO13=1; // 設定GPIO在輸入輸出模式時 : 0為輸入 1為輸出 (is used for output) 237 //GPIO14配置為UART的系統中斷確認 238 GpioCtrlRegs.GPAMUX1.bit.GPIO14=0; // 0為GPIO一般輸入輸出 239 GpioCtrlRegs.GPADIR.bit.GPIO14=1; // 設定GPIO在輸入輸出模式時 : 0為輸入 1為輸出 (is used for output) 240 EDIS; 241 242 GpioDataRegs.GPASET.bit.GPIO13=1;//turn on GPIO12 (initial GPIO12 state to high) 243 GpioDataRegs.GPASET.bit.GPIO14=1;//turn on GPIO14 (initial GPIO14 state to high) 244 } 245 //***************GOIP設置以上***************// 246 247 248 //***************EPWM1設置以下***************// 249 void InitEPwm1() //For Battery開關 g1,g2 250 { 251 EPwm1Regs.TBPRD = 3750; // 設定開關切換頻率20kHz,因為上下數,頻率減半,所以TBPRD從7500(20kHz)調為3750(40kHz) //f=150M/2(上下數)/TBPRD 252 EPwm1Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero 相移為零 253 EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;//TB_COUNT_UPDOWN 為 上下數的三角載波 254 EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // ?Master module? (then the synchronization event is ignored and the time-base counter is not loaded with the phase.) 255 EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; //? 256 EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; //? Sync down-stream module 257 EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; //系統除頻功能(不除頻,系統150MHZ) Clock ratio to SYSCLKOUT 258 EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; //系統除頻功能(不除頻,系統150MHZ) 259 EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; 260 EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; 261 EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero 262 EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero 263 264 //SPWM 當command > carrier : set high (for positive cycle) 265 EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; //上數碰到,PWM設為0(看EPWM就很明顯了) 266 EPwm1Regs.AQCTLA.bit.CAD = AQ_SET; //下數碰到,PWM設為1(看EPWM就很明顯了) 267 268 EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // 上下數的Dead-band 都開啟 269 EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC; //EPWMxB對A反向 Active high complementary (AHC). EPWMxB is inverted. 270 //---setting Dead-time---// 271 EPwm1Regs.DBFED = 75;//150; // FED = 75 TBCLKs (TBCLKS=1/150M) 0.5us (下降緣Dead-time) 272 EPwm1Regs.DBRED = 75;//150; // RED = 75 TBCLKs (上升緣Dead-time) 273 } 274 275 276 void InitEPwm6() 277 { 278 //EPWM6 isn‘t divided, so EPWM6 clock is 150MHz 279 EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // 不要除頻Clock ratio equal to SYSCLKOUT 280 EPwm6Regs.TBCTL.bit.CLKDIV = TB_DIV1; // 不要除頻 281 // Assumes ePWM6 clock is already enabled in InitSysCtrl(); 282 EPwm6Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group 283 EPwm6Regs.ETSEL.bit.SOCASEL = 2; //當TBCTR=TBPRD開始取樣 284 EPwm6Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event 285 //EPwm6Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from CMPA on upcount 286 //EPwm6Regs.CMPA.half.CMPA = 1250; // Set compare A value 剛好讓ADC中斷和inverter中斷各有1250個系統clock時間來處理自己中斷副程式要處理的任務 287 EPwm6Regs.TBPRD = 2500; // Set period for ePWM6 (PWM頻率為:150M/TB_DIV1(1:不除頻)/TB_DIV1(1:不除頻)/TBPRD=60k) 288 EPwm6Regs.TBCTL.bit.CTRMODE = 0; // count up and start 289 } 290 291 292 293 //*****************ADC設置以下***************// 294 void ADC_setup(void) 295 { 296 AdcRegs.ADCTRL3.bit.SMODE_SEL = 0x0; // Setup simultaneous sampling mode 297 AdcRegs.ADCTRL1.bit.SEQ_CASC = 0x1; // Setup cascaded sequencer mode 298 AdcRegs.ADCMAXCONV.all = 15; //設定一共需要8個(0~7)ADC轉換 on SEQ1 299 300 AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0;//設定"ADCIN0"抓到的值,轉換後存到 "ADCRESULT0 (CONV00)" 301 AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 1;//設定"ADCIN1"抓到的值,轉換後存到 "ADCRESULT1 (CONV01)" 302 AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 2;//設定"ADCIN2"抓到的值,轉換後存到 "ADCRESULT2 (CONV01)" 303 AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 3;//設定"ADCIN3"抓到的值,轉換後存到 "ADCRESULT3 (CONV03)" 304 AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 4;//設定"ADCIN4"抓到的值,轉換後存到 "ADCRESULT4 (CONV04)" 305 AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 5;//設定"ADCIN5"抓到的值,轉換後存到 "ADCRESULT5 (CONV05)" 306 AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 6;//設定"ADCIN5"抓到的值,轉換後存到 "ADCRESULT6 (CONV06)" 307 AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 7;//設定"ADCIN5"抓到的值,轉換後存到 "ADCRESULT7 (CONV07)" 308 AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 8; 309 AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 9; 310 AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 10; 311 AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 11; 312 AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 12; 313 AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 13; 314 AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 14; 315 AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 15; 316 317 AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1; // 允許ADC使用EPWM中斷 Enable SOCA from ePWM to start SEQ1 318 AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS) 319 } 320 321 //*****************ADC設置以上***************// 322 323 324 //*****************UART設置以下***************// 325 void scia_echoback_init() 326 { 327 328 SciaRegs.SCICCR.all =0x0007; 329 SciaRegs.SCICTL1.all =0x0003; 330 SciaRegs.SCICTL2.all =0x0003; 331 SciaRegs.SCICTL2.bit.TXINTENA =1; 332 SciaRegs.SCICTL2.bit.RXBKINTENA =1; 333 #if (CPU_FRQ_150MHZ) 334 SciaRegs.SCIHBAUD =0x0001; // 9600 baud @LSPCLK = 37.5MHz. 335 SciaRegs.SCILBAUD =0x00E7; 336 #endif 337 #if (CPU_FRQ_100MHZ) 338 SciaRegs.SCIHBAUD =0x0001; // 9600 baud @LSPCLK = 20MHz. 339 SciaRegs.SCILBAUD =0x0044; 340 #endif 341 SciaRegs.SCICTL1.all =0x0023; 342 } 343 void scia_xmit(int a) 344 { 345 while (SciaRegs.SCIFFTX.bit.TXFFST != 0) {} 346 SciaRegs.SCITXBUF=a; 347 348 } 349 void scia_msg(char * msg) 350 { 351 int i; 352 i = 0; 353 while(msg[i] != \0) 354 { 355 scia_xmit(msg[i]); 356 i++; 357 } 358 } 359 void scia_fifo_init() 360 { 361 SciaRegs.SCIFFTX.all=0xE040; 362 SciaRegs.SCIFFRX.all=0x204f; 363 SciaRegs.SCIFFCT.all=0x0; 364 } 365 //*****************UART設置以上***************//

Digital Boost Converter Example for DSP