Matlab生成dsp程序——官方例程学习

  • 写在下面的话
  • ADC-PWM例子学习
    • 一、基本功能
    • 二、生成代码分析
    • 三、总结

写在下面的话

   还是很建议大家多去学习官方例程的,真的能够收获到很多很多东西的!例程和ccs程序我也会打包上传的!
官方链接:MW官方例程
打包程序+模型链接:模型程序

ADC-PWM例子学习

一、基本功能

    ADC采集到的模拟电压控制PWM波形的占空比(周期不发生改变)。当处理器收到ADC中断(ADCINT)时,触发中断服务程序(ISR)并执行子系统(ADC-PWM子系统)。ADC-PWM子系统由ADC与EPWM模块组成,该模块驱动PWM模块的占空比输入端口。PWM模块配置为触发ADC模块的转换开始(SOC)。

  • 1.结算器Slover

    I、 这个计算的步长,设置会在对应程序中生成一个变量modelBaseRate,之后设置的Timer0会每0.4s进入一次中断。

float modelBaseRate = 0.4;
float systemClock = 200;
……ConfigCpuTimer(&CpuTimer0, systemClock, baseRate *1000000);//baseRate=modelBaseRate

二、生成代码分析

   生成四个变量:

volatile int IsrOverrun = 0;
static boolean_T OverrunFlag = 0;volatile boolean_T stopRequested = false;
volatile boolean_T runModel = false;                 //三个布尔型变量,一个int形

    进入主函数之后生成两个浮点型变量:

int main(void)
{float modelBaseRate = 0.4;           //这个是求解器设置的步长
float systemClock = 200;             //CPU晶振频率,与Clocking中的参数相互对应c2000_flash_init();                  //将Flash有关程序拷贝到RAM执行(Init_Flash、Flashoff程序都存放在Flash中)
init_board();                        //初始化各个部件(GPIO、时钟等)#ifdef MW_EXEC_PROFILER_ONconfig_profilerTimer();#endif                                //目前猜测是用来调试使用,Simulink环境也支持调试/*接下下个代码块部分*/

    下面先看一个结构体:

c2807x_2837xx_adcpwmasynctes_M 结构体:(因为前面都是文件名这里简记为_M结构体)
struct tag_RTM_c2807x_2837xx_adcpwma_T {const char_T *errorStatus;
};rtmSetErrorStatus(c2807x_2837xx_adcpwmasynctes_M, 0);   //给_M结构体中的errorStatus标志赋值为0 c2807x_2837xx_adcpwmasynctest_ert_initialize();         //初始化函数/*再看一个结构体*/
c2807x_2837xx_adcpwmasynctest_B 结构体:(因为前面都是文件名这里简记为_B结构体)
typedef struct {uint16_T ADC;                        /* '<S1>/ADC' */
} B_c2807x_2837xx_adcpwmasyncte_T;                     //注释中给的是模块信号结构体
(void) memset(((void *) &c2807x_2837xx_adcpwmasynctest_B), 0,sizeof(B_c2807x_2837xx_adcpwmasyncte_T));     //给_B结构体赋值为0
void c2807x_2837xx_adcpwmasynctest_ert_initialize(void)//根据Simulink中设置进行初始化设置()[这里是ADC和ePWM]
{/* Registration code *//* initialize error status */rtmSetErrorStatus(c2807x_2837xx_adcpwmasynctes_M, (NULL));   //给_M结构体中的errorStatus指向空(代表未操作过?)/* block I/O */(void) memset(((void *) &c2807x_2837xx_adcpwmasynctest_B), 0,sizeof(B_c2807x_2837xx_adcpwmasyncte_T));       //给_B结构体赋值为0/* Start for S-Function (c28xisr_c2000): '<Root>/C28x Hardware Interrupt' incorporates:*  SubSystem: '<Root>/ADC-PWM Subsystem'*//* Start for function-call system: '<Root>/ADC-PWM Subsystem' *//* Start for S-Function (c2802xadc): '<S1>/ADC' */if (MW_adcAInitFlag == 0) {InitAdcA();                                              //ADCA、12位、单端MW_adcAInitFlag = 1;}                                                          //利用标志控制ADC只初始化一次config_ADCA_SOC0 ();                                       //SOC0-ADCIN0、epwm1(soca)触发//EOC0触发ADCINT1(不触发SOC0)、转换完成后产生中断/* Start for S-Function (c2802xpwm): '<S1>/ePWM' */EALLOW;CpuSysRegs.PCLKCR2.bit.EPWM1 = 1;CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;EDIS;/*** Initialize ePWM1 modules ***/{/*  // Time Base Control RegisterEPwm1Regs.TBCTL.bit.CTRMODE              = 2;          // Counter ModeEPwm1Regs.TBCTL.bit.SYNCOSEL             = 3;          // Sync Output SelectEPwm1Regs.TBCTL.bit.PRDLD                = 0;          // Shadow selectEPwm1Regs.TBCTL.bit.PHSEN                = 0;          // Phase Load EnableEPwm1Regs.TBCTL.bit.PHSDIR               = 0;          // Phase Direction BitEPwm1Regs.TBCTL.bit.HSPCLKDIV            = 0;          // High Speed TBCLK Pre-scalerEPwm1Regs.TBCTL.bit.CLKDIV               = 0;          // Time Base Clock Pre-scalerEPwm1Regs.TBCTL.bit.SWFSYNC              = 0;          // Software Force Sync Pulse*/EPwm1Regs.TBCTL.all = (EPwm1Regs.TBCTL.all & ~0x3FFF) | 0x32;     //up-down模式、不使能同步信号输出/*-- Setup Time-Base (TB) Submodule --*/EPwm1Regs.TBPRD = 10000;           // Time Base Period Register/* // Time-Base Phase RegisterEPwm1Regs.TBPHS.bit.TBPHS               = 0;          // Phase offset register*/EPwm1Regs.TBPHS.all = (EPwm1Regs.TBPHS.all & ~0xFFFF0000) | 0x0;// Time Base Counter RegisterEPwm1Regs.TBCTR = 0x0000;          /* Clear counter*//*-- Setup Counter_Compare (CC) Submodule --*//*    // Counter Compare Control RegisterEPwm1Regs.CMPCTL.bit.SHDWAMODE           = 0;  // Compare A Register Block Operating ModeEPwm1Regs.CMPCTL.bit.SHDWBMODE           = 0;  // Compare B Register Block Operating ModeEPwm1Regs.CMPCTL.bit.LOADAMODE           = 0;          // Active Compare A LoadEPwm1Regs.CMPCTL.bit.LOADBMODE           = 0;          // Active Compare B Load*/EPwm1Regs.CMPCTL.all = (EPwm1Regs.CMPCTL.all & ~0x5F) | 0x0; //通过shadow写入/* EPwm1Regs.CMPCTL2.bit.SHDWCMODE           = 0;  // Compare C Register Block Operating ModeEPwm1Regs.CMPCTL2.bit.SHDWDMODE           = 0;  // Compare D Register Block Operating Mode*/EPwm1Regs.CMPCTL2.all = (EPwm1Regs.CMPCTL2.all & ~0x50) | 0x0;EPwm1Regs.CMPA.bit.CMPA = 5000;    // Counter Compare A RegisterEPwm1Regs.CMPB.bit.CMPB = 0;       // Counter Compare B RegisterEPwm1Regs.CMPC = 0;                // Counter Compare C RegisterEPwm1Regs.CMPD = 0;                // Counter Compare D Register/*-- Setup Action-Qualifier (AQ) Submodule --*/EPwm1Regs.AQCTLA.all = 96;   // Action Qualifier Control Register For Output A  注意是96十进制(0x60)// =CMPA(up)时置高,=prd(down)时置低EPwm1Regs.AQCTLB.all = 0;  // Action Qualifier Control Register For Output B/*  // Action Qualifier Software Force RegisterEPwm1Regs.AQSFRC.bit.RLDCSF              = 0;          // Reload from Shadow Options*/EPwm1Regs.AQSFRC.all = (EPwm1Regs.AQSFRC.all & ~0xC0) | 0x0;    //(在等于0时加载)/*  // Action Qualifier Continuous S/W Force RegisterEPwm1Regs.AQCSFRC.bit.CSFA               = 0;          // Continuous Software Force on output AEPwm1Regs.AQCSFRC.bit.CSFB               = 0;          // Continuous Software Force on output B*/EPwm1Regs.AQCSFRC.all = (EPwm1Regs.AQCSFRC.all & ~0xF) | 0x0;/*-- Setup Dead-Band Generator (DB) Submodule --*//*   // Dead-Band Generator Control RegisterEPwm1Regs.DBCTL.bit.OUT_MODE             = 0;          // Dead Band Output Mode ControlEPwm1Regs.DBCTL.bit.IN_MODE              = 0;          // Dead Band Input Select Mode ControlEPwm1Regs.DBCTL.bit.POLSEL               = 0;          // Polarity Select ControlEPwm1Regs.DBCTL.bit.HALFCYCLE            = 0;          // Half Cycle Clocking Enable*/EPwm1Regs.DBCTL.all = (EPwm1Regs.DBCTL.all & ~0x803F) | 0x0;EPwm1Regs.DBRED.bit.DBRED = 0;// Dead-Band Generator Rising Edge Delay Count RegisterEPwm1Regs.DBFED.bit.DBFED = 0;// Dead-Band Generator Falling Edge Delay Count Register/*-- Setup Event-Trigger (ET) Submodule --*//*  // Event Trigger Selection and Pre-Scale RegisterEPwm1Regs.ETSEL.bit.SOCAEN               = 1;          // Start of Conversion A EnableEPwm1Regs.ETSEL.bit.SOCASELCMP = 0;EPwm1Regs.ETSEL.bit.SOCASEL              = 2 ;          // Start of Conversion A SelectEPwm1Regs.ETPS.bit.SOCAPRD               = 1;          // EPWM1SOCA Period SelectEPwm1Regs.ETSEL.bit.SOCBEN               = 0;          // Start of Conversion B EnableEPwm1Regs.ETSEL.bit.SOCBSELCMP = 0;EPwm1Regs.ETSEL.bit.SOCBSEL              = 1;          // Start of Conversion A SelectEPwm1Regs.ETPS.bit.SOCBPRD               = 1;          // EPWM1SOCB Period SelectEPwm1Regs.ETSEL.bit.INTEN                = 0;          // EPWM1INTn EnableEPwm1Regs.ETSEL.bit.INTSELCMP = 0;EPwm1Regs.ETSEL.bit.INTSEL              = 1;          // Start of Conversion A SelectEPwm1Regs.ETPS.bit.INTPRD                = 1;          // EPWM1INTn Period Select*/EPwm1Regs.ETSEL.all = (EPwm1Regs.ETSEL.all & ~0xFF7F) | 0x1A01;EPwm1Regs.ETPS.all = (EPwm1Regs.ETPS.all & ~0x3303) | 0x1101;/*-- Setup PWM-Chopper (PC) Submodule --*//*    // PWM Chopper Control RegisterEPwm1Regs.PCCTL.bit.CHPEN                = 0;          // PWM chopping enableEPwm1Regs.PCCTL.bit.CHPFREQ              = 0;          // Chopping clock frequencyEPwm1Regs.PCCTL.bit.OSHTWTH              = 0;          // One-shot pulse widthEPwm1Regs.PCCTL.bit.CHPDUTY              = 0;          // Chopping clock Duty cycle*/EPwm1Regs.PCCTL.all = (EPwm1Regs.PCCTL.all & ~0x7FF) | 0x0;/*-- Set up Trip-Zone (TZ) Submodule --*/EALLOW;EPwm1Regs.TZSEL.all = 0;           // Trip Zone Select Register/* // Trip Zone Control RegisterEPwm1Regs.TZCTL.bit.TZA                  = 3;          // TZ1 to TZ6 Trip Action On EPWM1AEPwm1Regs.TZCTL.bit.TZB                  = 3;          // TZ1 to TZ6 Trip Action On EPWM1BEPwm1Regs.TZCTL.bit.DCAEVT1              = 3;          // EPWM1A action on DCAEVT1EPwm1Regs.TZCTL.bit.DCAEVT2              = 3;          // EPWM1A action on DCAEVT2EPwm1Regs.TZCTL.bit.DCBEVT1              = 3;          // EPWM1B action on DCBEVT1EPwm1Regs.TZCTL.bit.DCBEVT2              = 3;          // EPWM1B action on DCBEVT2*/EPwm1Regs.TZCTL.all = (EPwm1Regs.TZCTL.all & ~0xFFF) | 0xFFF;/*   // Trip Zone Enable Interrupt RegisterEPwm1Regs.TZEINT.bit.OST                 = 0;          // Trip Zones One Shot Int EnableEPwm1Regs.TZEINT.bit.CBC                 = 0;          // Trip Zones Cycle By Cycle Int EnableEPwm1Regs.TZEINT.bit.DCAEVT1             = 0;          // Digital Compare A Event 1 Int EnableEPwm1Regs.TZEINT.bit.DCAEVT2             = 0;          // Digital Compare A Event 2 Int EnableEPwm1Regs.TZEINT.bit.DCBEVT1             = 0;          // Digital Compare B Event 1 Int EnableEPwm1Regs.TZEINT.bit.DCBEVT2             = 0;          // Digital Compare B Event 2 Int Enable*/EPwm1Regs.TZEINT.all = (EPwm1Regs.TZEINT.all & ~0x7E) | 0x0;/* // Digital Compare A Control RegisterEPwm1Regs.DCACTL.bit.EVT1SYNCE           = 0;          // DCAEVT1 SYNC EnableEPwm1Regs.DCACTL.bit.EVT1SOCE            = 1;          // DCAEVT1 SOC EnableEPwm1Regs.DCACTL.bit.EVT1FRCSYNCSEL      = 0;          // DCAEVT1 Force Sync SignalEPwm1Regs.DCACTL.bit.EVT1SRCSEL          = 0;          // DCAEVT1 Source SignalEPwm1Regs.DCACTL.bit.EVT2FRCSYNCSEL      = 0;          // DCAEVT2 Force Sync SignalEPwm1Regs.DCACTL.bit.EVT2SRCSEL          = 0;          // DCAEVT2 Source Signal*/EPwm1Regs.DCACTL.all = (EPwm1Regs.DCACTL.all & ~0x30F) | 0x4;/*  // Digital Compare B Control RegisterEPwm1Regs.DCBCTL.bit.EVT1SYNCE           = 0;          // DCBEVT1 SYNC EnableEPwm1Regs.DCBCTL.bit.EVT1SOCE            = 0;          // DCBEVT1 SOC EnableEPwm1Regs.DCBCTL.bit.EVT1FRCSYNCSEL      = 0;          // DCBEVT1 Force Sync SignalEPwm1Regs.DCBCTL.bit.EVT1SRCSEL          = 0;          // DCBEVT1 Source SignalEPwm1Regs.DCBCTL.bit.EVT2FRCSYNCSEL      = 0;          // DCBEVT2 Force Sync SignalEPwm1Regs.DCBCTL.bit.EVT2SRCSEL          = 0;          // DCBEVT2 Source Signal*/EPwm1Regs.DCBCTL.all = (EPwm1Regs.DCBCTL.all & ~0x30F) | 0x0;/*  // Digital Compare Trip Select RegisterEPwm1Regs.DCTRIPSEL.bit.DCAHCOMPSEL      = 0;          // Digital Compare A High COMP Input SelectEPwm1Regs.DCTRIPSEL.bit.DCALCOMPSEL      = 1;          // Digital Compare A Low COMP Input SelectEPwm1Regs.DCTRIPSEL.bit.DCBHCOMPSEL      = 0;          // Digital Compare B High COMP Input SelectEPwm1Regs.DCTRIPSEL.bit.DCBLCOMPSEL      = 1;          // Digital Compare B Low COMP Input Select*/EPwm1Regs.DCTRIPSEL.all = (EPwm1Regs.DCTRIPSEL.all & ~ 0xFFFF) | 0x1010;/*  // Trip Zone Digital Comparator Select RegisterEPwm1Regs.TZDCSEL.bit.DCAEVT1            = 0;          // Digital Compare Output A Event 1EPwm1Regs.TZDCSEL.bit.DCAEVT2            = 0;          // Digital Compare Output A Event 2EPwm1Regs.TZDCSEL.bit.DCBEVT1            = 0;          // Digital Compare Output B Event 1EPwm1Regs.TZDCSEL.bit.DCBEVT2            = 0;          // Digital Compare Output B Event 2*/EPwm1Regs.TZDCSEL.all = (EPwm1Regs.TZDCSEL.all & ~0xFFF) | 0x0;/* // Digital Compare Filter Control RegisterEPwm1Regs.DCFCTL.bit.BLANKE              = 0;          // Blanking Enable/DisableEPwm1Regs.DCFCTL.bit.PULSESEL            = 1;          // Pulse Select for Blanking & Capture AlignmentEPwm1Regs.DCFCTL.bit.BLANKINV            = 0;          // Blanking Window InversionEPwm1Regs.DCFCTL.bit.SRCSEL              = 0;          // Filter Block Signal Source Select*/EPwm1Regs.DCFCTL.all = (EPwm1Regs.DCFCTL.all & ~0x3F) | 0x10;EPwm1Regs.DCFOFFSET = 0;           // Digital Compare Filter Offset RegisterEPwm1Regs.DCFWINDOW = 0;           // Digital Compare Filter Window Register/*    // Digital Compare Capture Control RegisterEPwm1Regs.DCCAPCTL.bit.CAPE              = 0;          // Counter Capture Enable*/EPwm1Regs.DCCAPCTL.all = (EPwm1Regs.DCCAPCTL.all & ~0x1) | 0x0;/*    // HRPWM Configuration RegisterEPwm1Regs.HRCNFG.bit.SWAPAB              = 0;          // Swap EPWMA and EPWMB Outputs BitEPwm1Regs.HRCNFG.bit.SELOUTB             = 0;          // EPWMB Output Selection Bit*/EPwm1Regs.HRCNFG.all = (EPwm1Regs.HRCNFG.all & ~0xA0) | 0x0;/* Update the Link Registers with the link value for all the Compare values and TBPRD *//* No error is thrown if the ePWM register exists in the model or not */EPwm1Regs.EPWMXLINK.bit.TBPRDLINK = 0;EPwm1Regs.EPWMXLINK.bit.CMPALINK = 0;EPwm1Regs.EPWMXLINK.bit.CMPBLINK = 0;EPwm1Regs.EPWMXLINK.bit.CMPCLINK = 0;EPwm1Regs.EPWMXLINK.bit.CMPDLINK = 0;EDIS;EALLOW;CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;EDIS;}/* End of Start for S-Function (c28xisr_c2000): '<Root>/C28x Hardware Interrupt' */
}
/*接上面的主函数*/
rtmSetErrorStatus(c2807x_2837xx_adcpwmasynctes_M, 0);   //_M结构体中的错误标志赋值为0
c2807x_2837xx_adcpwmasynctest_ert_initialize();            //_M结构体赋值为NULL,_B结构体(只有一个ADC)赋值为0
configureTimer0(modelBaseRate, systemClock);            //开启Timer0中断(中断时长为步长),中断函数:TINT0_isr()
runModel =rtmGetErrorStatus(c2807x_2837xx_adcpwmasynctes_M) == (NULL); //检测_M中错误标志是否是NULL
enableTimer0Interrupt();                                //开启Timer0中断
enable_interrupts();                                    //开ADC中断,ADC中断函数为ADCA1_INT_isr()
globalInterruptEnable();                                //开全局中断
while (runModel)
{stopRequested = !(rtmGetErrorStatus(c2807x_2837xx_adcpwmasynctes_M) == (NULL));     //stopRequested是一个标志,一直检测_M结构                                                                            中的错误标志是否发送了改变
}        /*Terminate mode*/
c2807x_2837xx_adcpwmasynctest_ert_terminate(); //空函数与设置中的Custom Code可能有关,以后进行测试一下
globalInterruptDisable();                      //关中断
return 0;
}/*主函数完毕*/

   主函数主要是完成了:

  • 1.Timer0初始化为0.4s(求解器的步长)进入一次中断

  • 2.初始化了ADC和ePWM模块(按照Simulink中的有关设置)

  • 3.在主循环中一直在,获取一个标志位stopRequested ,推测可能是一个重要的函数运行/停止的标志

    下面着重看一下两个中断函数:1.**Timer0中断 **[TINT0_isr()](这个中断并不是我们设置的,是系统求解器自动生成的一个中。可能与系统运行密切相关)。2.**ADC中断 **[ADCA1_INT_isr()],这个中断可能是完成我们需要的操作(把ADC采集的结果传送到ePWM的CMPA中,进而改变占空比)。

  如上图所示,自动生成了以上四个文件,Timer0中断函数就在红框所示文件内。

interrupt void TINT0_isr(void)
{     //#define PIEMASK0                       64//#define IFRMASK                        1#ifdef PIEMASK0          //再MW_c28xx_pie.h文件中进行了相关的声明                                             volatile unsigned int PIEIER1_stack_save = PieCtrlRegs.PIEIER1.all;//PIE1中1.7是Timer0中断;1.1是ADC中断#endif/* #ifdef PIEMASK1volatile unsigned int PIEIER2_stack_save  = PieCtrlRegs.PIEIER2.all;#endif#ifdef PIEMASK2volatile unsigned int PIEIER3_stack_save  = PieCtrlRegs.PIEIER3.all;#endif#ifdef PIEMASK3volatile unsigned int PIEIER4_stack_save  = PieCtrlRegs.PIEIER4.all;#endif#ifdef PIEMASK4volatile unsigned int PIEIER5_stack_save  = PieCtrlRegs.PIEIER5.all;#endif#ifdef PIEMASK5volatile unsigned int PIEIER6_stack_save  = PieCtrlRegs.PIEIER6.all;#endif#ifdef PIEMASK6volatile unsigned int PIEIER7_stack_save  = PieCtrlRegs.PIEIER7.all;#endif#ifdef PIEMASK7volatile unsigned int PIEIER8_stack_save  = PieCtrlRegs.PIEIER8.all;#endif#ifdef PIEMASK8volatile unsigned int PIEIER9_stack_save  = PieCtrlRegs.PIEIER9.all;#endif#ifdef PIEMASK9volatile unsigned int PIEIER10_stack_save = PieCtrlRegs.PIEIER10.all;#endif#ifdef PIEMASK10volatile unsigned int PIEIER11_stack_save = PieCtrlRegs.PIEIER11.all;#endif#ifdef PIEMASK11volatile unsigned int PIEIER12_stack_save = PieCtrlRegs.PIEIER12.all;#endif*/      //这一段并不是注释掉了,表示文件中没有宏定义,目前没有起作用#ifdef PIEMASK0PieCtrlRegs.PIEIER1.all &= ~PIEMASK0;      /* disable group1 lower/equal priority interrupts */#endif#ifdef PIEMASK1PieCtrlRegs.PIEIER2.all &= ~PIEMASK1;      /* disable group2 lower/equal priority interrupts */#endif#ifdef PIEMASK2PieCtrlRegs.PIEIER3.all &= ~PIEMASK2;      /* disable group3 lower/equal priority interrupts */#endif#ifdef PIEMASK3PieCtrlRegs.PIEIER4.all &= ~PIEMASK3;      /* disable group4 lower/equal priority interrupts */#endif#ifdef PIEMASK4PieCtrlRegs.PIEIER5.all &= ~PIEMASK4;      /* disable group5 lower/equal priority interrupts */#endif#ifdef PIEMASK5PieCtrlRegs.PIEIER6.all &= ~PIEMASK5;      /* disable group6 lower/equal priority interrupts */#endif#ifdef PIEMASK6PieCtrlRegs.PIEIER7.all &= ~PIEMASK6;      /* disable group7 lower/equal priority interrupts */#endif#ifdef PIEMASK7PieCtrlRegs.PIEIER8.all &= ~PIEMASK7;      /* disable group8 lower/equal priority interrupts */#endif#ifdef PIEMASK8PieCtrlRegs.PIEIER9.all &= ~PIEMASK8;      /* disable group9 lower/equal priority interrupts */#endif#ifdef PIEMASK9PieCtrlRegs.PIEIER10.all &= ~PIEMASK9;     /* disable group10 lower/equal priority interrupts */#endif#ifdef PIEMASK10PieCtrlRegs.PIEIER11.all &= ~PIEMASK10;    /* disable group11 lower/equal priority interrupts */#endif#ifdef PIEMASK11PieCtrlRegs.PIEIER12.all &= ~PIEMASK11;    /* disable group12 lower/equal priority interrupts */#endif#ifdef PIEMASK12IER &= ~(M_INT13);#endif#ifdef PIEMASK13IER &= ~(M_INT14);#endifasm(" RPT #5 || NOP");               /* wait 5 cycles */  //等待五个周期IFR &= ~IFRMASK;                           /* eventually disable lower/equal priority pending interrupts */PieCtrlRegs.PIEACK.all = IFRMASK;          /* ACK to allow other interrupts from the same group to fire */IER |= 1;EINT;                                /* global interrupt enable */rt_OneStep();DINT;                                /* disable global interrupts during context switch, CPU will enable global interrupts after exiting ISR */#ifdef PIEMASK0PieCtrlRegs.PIEIER1.all = PIEIER1_stack_save;/*restore PIEIER register that was modified */#endif  #ifdef PIEMASK1PieCtrlRegs.PIEIER2.all = PIEIER2_stack_save;/*restore PIEIER register that was modified */#endif#ifdef PIEMASK2PieCtrlRegs.PIEIER3.all = PIEIER3_stack_save;/*restore PIEIER register that was modified */#endif#ifdef PIEMASK3PieCtrlRegs.PIEIER4.all = PIEIER4_stack_save;/*restore PIEIER register that was modified */#endif#ifdef PIEMASK4PieCtrlRegs.PIEIER5.all = PIEIER5_stack_save;/*restore PIEIER register that was modified */#endif#ifdef PIEMASK5PieCtrlRegs.PIEIER6.all = PIEIER6_stack_save;/*restore PIEIER register that was modified */#endif#ifdef PIEMASK6PieCtrlRegs.PIEIER7.all = PIEIER7_stack_save;/*restore PIEIER register that was modified */#endif#ifdef PIEMASK7PieCtrlRegs.PIEIER8.all = PIEIER8_stack_save;/*restore PIEIER register that was modified */#endif#ifdef PIEMASK8PieCtrlRegs.PIEIER9.all = PIEIER9_stack_save;/*restore PIEIER register that was modified */#endif#ifdef PIEMASK9PieCtrlRegs.PIEIER10.all= PIEIER10_stack_save;/*restore PIEIER register that was modified */#endif#ifdef PIEMASK10PieCtrlRegs.PIEIER11.all= PIEIER11_stack_save;/*restore PIEIER register that was modified */#endif#ifdef PIEMASK11PieCtrlRegs.PIEIER12.all= PIEIER12_stack_save;/*restore PIEIER register that was modified */#endif#ifdef PIEMASK12IER |= M_INT13;#endif#ifdef PIEMASK13IER |= M_INT14;#endif
}
  • 1.建立一个堆栈PIEIER1_stack_save保存了PIE1的状态,

然后是这段代码:PieCtrlRegs.PIEIER1.all &= ~PIEMASK0;(PIEMASK0等于64,即:0100 0000)

~PIEMASK0为:1011 1111,与上PIE1之后可以发现,是将1.7(Timer0中断)位进行置零;就是关Timer0中断。

  • 2.然后等待5个周期,将IFR最低位置为0,清除INT1的标志位。

  • 3.将ACK1置为1,禁止同级中断响应。

  • 4.将IER最低位置为1,应答。

  • 5.开启全局中断。

然后进入函数 **rt_OneStep();**本程序中为空函数。[推测跟步长有关的函数将在此函数里面执行,比如GPIO翻转实验中的内容]

  • 6.DINT,关闭全局中断。将PIE恢复为进入时候的状态,即重新开启Timer0中断。

其实感觉真正自己写的话,不用那么复杂。这里可能是Mathwork为了编写程序模块化写程序,进行了一定的固定设置。

下面看一下ADC中断函数()[ADCA1_INT_isr()]

interrupt void ADCA1_INT_isr(void)
{isr_int1pie1_task_fcn();EALLOW;AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;        //清除ADC的标志位EDIS;PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;       //应答}

主要的函数内容都在**isr_int1pie1_task_fcn()**函数中:

void isr_int1pie1_task_fcn(void)
{/* Call the system: <Root>/ADC-PWM Subsystem */{/* S-Function (c28xisr_c2000): '<Root>/C28x Hardware Interrupt' *//* Output and update for function-call system: '<Root>/ADC-PWM Subsystem' */{/* local block i/o variables */uint16_T rtb_Gain;/* S-Function (c2802xadc): '<S1>/ADC' */{/*  Internal Reference Voltage : Fixed scale 0 to 3.3 V range.  *//*  External Reference Voltage : Allowable ranges of VREFHI(ADCINA0) = 3.3 and VREFLO(tied to ground) = 0  */c2807x_2837xx_adcpwmasynctest_B.ADC = (AdcaResultRegs.ADCRESULT0); //读取ADC采集结果}/* Gain: '<S1>/Gain' */rtb_Gain = (uint16_T)(((uint32_T)c2807x_2837xx_adcpwmasynctest_P.Gain_Gain* c2807x_2837xx_adcpwmasynctest_B.ADC) >> 13U);         //40960>>13*(ADC的采样结果)=5*(ADCresult)/* S-Function (c2802xpwm): '<S1>/ePWM' *//*-- Update CMPA value for ePWM1 --*/{EPwm1Regs.CMPA.bit.CMPA = (uint16_T)(rtb_Gain);     //将这个值赋给epwm的CMPA}}/* End of Outputs for S-Function (c28xisr_c2000): '<Root>/C28x Hardware Interrupt' */}
}

这里有点意思,因为Simulink中这里使用的是一个Function Call模块,可以猜想,里面含有其他的模块,可能也在这一部分。

最后看一下MW生成的这些文件都有哪些功能:

红框内的都是MW生成的文件,其他的都是库文件。

  • 1.c2807x_2837xx_adcpwmasynctest_ert_data.c,(_data前面都是文件名,所以简记为:data文件),文件中存储了会使用到的一些参数,如这一次的常数5)

  • 2.c2807x_2837xx_adcpwmasynctest_ert.c,这文件里面有ADC中断执行的isr_int1pie1_task_fcn函数。**c2807x_2837xx_adcpwmasynctest_ert_step()**函数,**c2807x_2837xx_adcpwmasynctest_ert_initialize()**函数,**c2807x_2837xx_adcpwmasynctest_ert_terminate()**函数。

    可以看出是与模型相关的一些函数。

  • 3.c2837xDBoard_Realtime_Support.c,一些板子的支持函数,通用性的功能函数

  • 4.c2837xDSchedulerTimer0.c,就是跟求解器步长相关的函数,如果加入积分模块很有可能就在这里运算。

  • 5.MW_c28xGPIO.c,存放初始化GPIO和设置相关GPIO的函数

  • 6.MW_c28x_adc.c,存放ADC初始化和配置ADC的函数。

  • 7.MW_c28x_board.c,存放初始化时钟和一些配置的相关函数(如外设属于CPU1还是CPU2等等)。

  • 8.MW_c28x_csl.c,存放开启中断,以及中断函数如ADCA1_INT_isr)。

  • 9.MW_c28x_pwm.c,配置开启PWM,需要使用的GPIO

  • 10.profiler_Support.c,感觉与调试相关。

下面尝试一下,如果不开启ADC中断,将ADC结果乘5赋值给CMPA将在哪部分完成!

结果是失败了,目测是跟这个模块关系非常大。

弄明白了,这个是通过CPU中断号和PIE中断号进行服务的中断函数,具体对应关系需要查看帮助文档。


这里给的CPU和PIE号都是1,而且这两个号码还能在模块中配置为向量,看来能够多个中断里面都使用一个函数体。

三、总结

总的来说,整个生成的程序有严格的框架,主要是步长会默认占用一个Timer0的中断,不知道这个能否进行改动。再就是其他的东西都与模型有严格的对照,非常建议第一次学习的时候,将模型和程序进行对照学习,收获会非常非常大的。环境搭建的步骤,我也已经上传了,有需要的可以看我的博文。

Matlab生成dsp程序——官方例程学习相关推荐

  1. MATLAB调用Origin绘图官方案例学习

    MATLAB调用Origin origin官方案例 1. 绘图 2 创建修改workbook 日常处理实验数据绘图用的都是origin,origin自带的模板和调色板比matlab好看太多(origi ...

  2. matlab 生成plc程序,利用MATLABsimulink的自动代码生成工具开发PLC程序..docx

    利用MATLABsimulink的自动代码生成工具开发PLC程序. 利用MATLAB/simulink的自动代码生成工具开发PLC程序MATLAB之控制系统 2010-07-07 15:17:43 阅 ...

  3. matlab生成vhdl程序,使用HDL Workflow Advisor将matlab代码转换为vhdl

    我制作了一个Matlab程序,用于检测2个圆形是否相互交叉并输出交点的坐标.现在,我试图将代码转换为vhdl来实现FPGA. 我的代码中HDL Workflow Advisor中仍然存在错误的函数之一 ...

  4. 旋转编码器测速c语言程序,官方例程中编码器测速程序高低速怎么区分

    如下是官方编码器测速的程序: //**** High Speed Calculation using QEP Position counter ****// // Check unit Time ou ...

  5. 采用MATLAB的DSP调试方法

    本文结合具体例证,介绍基于MATLAB 的DSP 应用程序调试方法. MATLAB 具有强大的分析.计算和可视化功能,利用MATLAB 提供的数十个专业工具箱,可以方便.灵活地实现对自动控制.信号处理 ...

  6. 一天上手Aurora 8B/10B IP核(5)----从Framing接口的官方例程学起

    文章目录 写在前面 1.IP核定制与官方例程的生成 1.1.第一页配置:物理层以及链路层信息选择 1.2.第二页配置:对应GT收发器的物理位置选择 1.3.第三页配置:共享逻辑的位置 1.4.官方例程 ...

  7. Matlab生成.exe可执行程序

    生成exe可执行程序 (1)选择编译器 在matlab命令行输入mbuild -setup以及mex -setup,选择安装的c++编译器,matlab自带LCC,我配了VS2019. (2)调用编译 ...

  8. qt中调用matlab生成的动态库

    前言: 前面已经实现了在vc中调用matlab生成的动态库,请参考:vc中调用matlab生成的动态库 现在在前面已经生成好的matlab动态库的基础上,在qt中调用matlab生成的动态库.生成ma ...

  9. AtmelStudio 7 ASF库学习笔记一:新建工程、配置时钟、下载程序和查看官方例程

    一.前言 由于需要学习一下atmel的atsaml 系列,使用AtmelStudio 7开发,之前主要用STM32,现在看到Atmel的库函数,其实是有许多相似之处.ASF3的库对应ST的标准库.AS ...

最新文章

  1. (转载)机器学习知识点(二十九)LDA入门级学习笔记
  2. 搭载第四代自研神龙架构 阿里云发布RDMA增强型实例等多款新品
  3. 【渝粤教育】国家开放大学2018年春季 0603-21T建筑工程管理与实务 参考试题
  4. jdk8 32位_HashMap源码分析 jdk8
  5. 发现这里才是我的地方
  6. 如何在本地一键安装、重启Linux服务器和远程debug调试代码 idea
  7. 背包问题(背包九讲)
  8. 笔记本开机速度怎么计算机,笔记本开机加速的步骤_如何给笔记本电脑开机提速-win7之家...
  9. 联想Y470 非虚拟机安装苹果Mac OS X Mavericks 10.9.1教程详解(文字+图片),通俗易懂亲自动手——序列四之重启系统,系统设置
  10. 华硕飞行堡垒56789原厂Windows10系统
  11. cnpm不是内部命令的解决方案:配置环境变量【推荐】
  12. matlab中pwelch函数计算功率谱密度
  13. Accumulation
  14. Matplotlib空气质量数据分析(附数据集下载)
  15. LeetCode#17 Python解
  16. SRS 对接GB28181 token防盗链配置
  17. 为什么short类型取值范围为-32768~32767
  18. html tab顶部吸附,flutter,SliverPersistentHeader实现Tab顶部吸附固定效果
  19. 论文笔记 EMNLP 2020|Event Extraction by Answering (Almost) Natural Questions
  20. 限制儿童使用计算机,win7设置控制孩子的上网时间不让他一直在玩电脑

热门文章

  1. 045关于树形div空白定位问题的处理方案
  2. 项目实战 | Excel导出(一)——导出方式
  3. MySQL数据库锁表
  4. 再生龙制作无盘一键还原
  5. 怎么用迅捷视频转换器将MP4格式视频转成AVI格式
  6. Python 生成器和迭代器详解
  7. springboot+网建短信通发送短信
  8. Windows注册表互换Caps Lock、Shift、Ctr l键
  9. 使用px2rem不生效
  10. Mongodb3.4离线升级到4.2