DSP28337D-ePWM之Trip-Zone实战测试
基于TMS320F28377D-ePWM-TZ模块实现第一篇的两个如何触发trip-zone的想法(gpio绑定TZ1~3触发,ADC超越限制进行DCAEVT1/2或DCBEVT1/2触发)。本期先展示GPIO -----| I/P X-BAR |-----TZ1-----| ePWM TZ Module |-----TZ-Event触发,后期有时间再更新ADC事件触发TZ。
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。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)