DSP系列文章目录

第一章:DSP28337D-ePWM之Trip-Zone是什么
第二章:DSP28337D-ePWM之Trip-Zone实战测试
第三章:DSP28337D-IPC共享内存
第四章:DSP28337D-EMIF&ASRAM
第五章:DSP28337D-EMIF&SDRAM



前言

基于TMS320F28377D-ePWM-TZ模块
实现第一篇的两个如何触发trip-zone的想法(gpio绑定TZ1~3触发,ADC超越限制进行DCAEVT1/2或DCBEVT1/2触发)。


一、GPIO如何触发Trip-zone

1、验证功能:

1、gpio67(IO2)作为错误控制输入,通过低电平可触发ePWM1/2-TZ。
2、ePWM1A绑定OSHT-TZISR1,ISR1中断只会触发一次,且pwm持续拉低
3、ePWM2A绑定CBC-TZISR2,ISR2中断中,gpio65(LED2)会在ISR中循环周期翻转,每次中断时pwm拉低

2、上程序:

直接上c2000ware源码,稍作修改,main.c代码如下:

//Globals
uint32_t  epwm1TZIntCount;
uint32_t  epwm2TZIntCount;
uint32_t  hhh=0;
// Function Prototypes
void initEPWM1(void);
void initEPWM2(void);
__interrupt void epwm1TZISR(void);
__interrupt void epwm2TZISR(void);
void udelay(uint32_t usecs)
{
    SysCtl_delay(((((long double)(usecs)) / (1000000.0L /
        (long double)DEVICE_SYSCLK_FREQ)) - 9.0L) / 5.0L);
}
void mdelay(uint32_t msecs)
{
    udelay(msecs*1000);
}
void main(void)
{
    // Initialize global variables
    epwm1TZIntCount = 0U;
    epwm2TZIntCount = 0U;
    // Initialize device clock and peripherals
    Device_init();
    // Disable pin locks and enable internal pull-ups.
    Device_initGPIO();
    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    Interrupt_initModule();
    // Initialize the PIE vector table with pointers to the shell Interrupt
    Interrupt_initVectorTable();
    // Interrupts that are used in this example are re-mapped to ISR functions
    Interrupt_register(INT_EPWM1_TZ, &epwm1TZISR);
    Interrupt_register(INT_EPWM2_TZ, &epwm2TZISR);
    // Configure ePWM1, ePWM2, and TZ GPIOs
    Board_init();
    // Disable sync(Freeze clock to PWM as well)
    SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    // Initialize ePWM1 and ePWM2
    initEPWM1();
    initEPWM2();
    // Enable sync and clock to PWM
    SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    // Enable interrupts required for this example
    Interrupt_enable(INT_EPWM1_TZ);
    Interrupt_enable(INT_EPWM2_TZ);
    
    // Enable Global Interrupt (INTM) and real time interrupt (DBGM)
    EINT;
    ERTM;
    mdelay(200);
    while(1)
    {
        mdelay(100);
        hhh++;
    }
}

// epwm1TZISR - ePWM1 TZ ISR
__interrupt void epwm1TZISR(void)
{
    epwm1TZIntCount++;
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP2);
}

// epwm2TZISR - ePWM2 TZ ISR
__interrupt void epwm2TZISR(void)
{
    epwm2TZIntCount++;
    // Toggle GPIO to notify when TZ is entered
    GPIO_togglePin(myGPIO11);
    // Clear the flags - we will continue to take this interrupt until the TZ.
    EPWM_clearTripZoneFlag(myEPWM2_BASE, (EPWM_TZ_INTERRUPT | EPWM_TZ_FLAG_CBC));
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP2);
}

// initEPWM1 - Configure ePWM1
void initEPWM1()
{
    // Enable TZ1 as one shot trip sources
    EPWM_enableTripZoneSignals(myEPWM1_BASE, EPWM_TZ_SIGNAL_OSHT1);
    // Action on TZ1
    EPWM_setTripZoneAction(myEPWM1_BASE, EPWM_TZ_ACTION_EVENT_TZA,EPWM_TZ_ACTION_HIGH);

    // Enable TZ interrupt
    EPWM_enableTripZoneInterrupt(myEPWM1_BASE, EPWM_TZ_INTERRUPT_OST);
    // Set-up TBCLK
    EPWM_setTimeBasePeriod(myEPWM1_BASE, 12000U);
    EPWM_setPhaseShift(myEPWM1_BASE, 0U);
    EPWM_setTimeBaseCounter(myEPWM1_BASE, 0U);
    EPWM_setTimeBaseCounterMode(myEPWM1_BASE, EPWM_COUNTER_MODE_UP_DOWN);
    EPWM_disablePhaseShiftLoad(myEPWM1_BASE);
    // Set ePWM clock pre-scaler
    EPWM_setClockPrescaler(myEPWM1_BASE, EPWM_CLOCK_DIVIDER_4, EPWM_HSCLOCK_DIVIDER_4);
    // Set up shadowing
    EPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);
    // Set-up compare
    EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A, 6000U);
    // Set actions
    EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW,  EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
}

// initEPWM2 - Configure ePWM2
void initEPWM2()
{
    // Enable TZ1 as one cycle-by-cycle trip sources
    EPWM_enableTripZoneSignals(myEPWM2_BASE, EPWM_TZ_SIGNAL_CBC1);
    // Action on TZ1
    EPWM_setTripZoneAction(myEPWM2_BASE, EPWM_TZ_ACTION_EVENT_TZA, EPWM_TZ_ACTION_HIGH);
    // Enable TZ interrupt
    EPWM_enableTripZoneInterrupt(myEPWM2_BASE, EPWM_TZ_INTERRUPT_CBC);
    // Set-up TBCLK
    EPWM_setTimeBasePeriod(myEPWM2_BASE, 6000U);
    EPWM_setPhaseShift(myEPWM2_BASE, 0U);
    EPWM_setTimeBaseCounter(myEPWM2_BASE, 0U);
    EPWM_setTimeBaseCounterMode(myEPWM2_BASE, EPWM_COUNTER_MODE_UP_DOWN);
    EPWM_disablePhaseShiftLoad(myEPWM2_BASE);
    // Set ePWM clock pre-scaler
    EPWM_setClockPrescaler(myEPWM2_BASE, EPWM_CLOCK_DIVIDER_4, EPWM_HSCLOCK_DIVIDER_4);
    // Set-up compare
    EPWM_setCounterCompareValue(myEPWM2_BASE, EPWM_COUNTER_COMPARE_A, 3000U);
    // Set actions  
    EPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
    EPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA);
}

3、现象展示:

3.1 debug展示中断计数
在这里插入图片描述
3.2 led闪烁就不展示了,拍图有点low,以上足够说明一切

4、原理解释

这张图感觉已经能说明一切了,总之就是将GPIO作为中断触发源,input-X-bar理解为就是个万能连接器(确实能相互交叉连接不同外设),INPUT1~3就是个信号,然后再触发的时候能进入epwm-TZ模块的接口TZ1/2/3。
低电平触发的时候可以产生两个动作。一个动作是TZ信号直接触发错误机制(ePWM高电平、低电平、高阻态、无控制,这些和你初始化设置直接绑定),另外一个动作是TZ中断,需要配置,不配置会略过。

在这里插入图片描述


二、ADC设置超限触发Trip-Zone

1.

代码如下:


2.

代码如下:



总结

本期先展示GPIO -----| I/P X-BAR |-----TZ1-----| ePWM TZ Module |-----TZ-Event触发,后期有时间再更新ADC事件触发TZ。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐