This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/TMS320F280049:EPWM1中断延迟太长

Guru**** 2027820 points
Other Parts Discussed in Thread: C2000WARE
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/719891/ccs-tms320f280049-epwm1-interrupt-delay-is-too-long

器件型号:TMS320F280049
主题中讨论的其他器件:C2000WARE

工具/软件:Code Composer Studio

我尝试使用 ePWM 触发 ADC。 在执行此操作时、我启用了 ePWM1中断来触发(GPIO 切换)。

我看到 ADC 转换正在尽早完成。 但是进入 ISR 切换 GPIO 所需的时间为10微秒、这太长了。

请告诉我如何降低中断延迟。

P.S. 我将使用一个10个 SYSCLK 周期的采样窗口来转换 ADC 中的9个通道。

系统频率= 100MHz

该程序复制如下:


//#include "F28x_Project.h"
#include "driverlib.h"
#include "device.h"

//
//定义
//

#define EPWM1_TIMER_TBPRD 5000U // 50us
#define EPWM1_CMPA 1000U // 10us

//
//全局
//

//
//函数原型
//
void initEPWM1 (void);
void initadc (void);
void initADCSOC (void);
_interrupt void epwm1ISR (void);

void main (void)

//初始化设备时钟和外设
device_init();

//禁用引脚锁定并启用内部上拉。
DEVICE_initGPIO();

//初始化 PIE 并清除 PIE 寄存器。 禁用 CPU 中断。
interrupt_initModule();

//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
interrupt_initVectorTable();

//将中断服务例程分配给 ADC 中断
INTERRUPT_REGISTER (INT_EPWM1、epwm1ISR);

//为 ADC ISR 配置 GPIO 引脚
GPIO_setPadConfig (4、GPIO_PIN_TYPE_PULLUP);
GPIO_setPinConfig (GPIO_4_GPIO4);
GPIO_setDirectionMode (4、GPIO_DIR_MODE_OUT);


//配置 EPWM1和 ADC-A
initadC();
initEPWM1();
initADCSOC();


INTERRUPT_ENABLE (INT_EPWM1);


//启用全局中断(INTM)和实时中断(DBGM)
EINT;
ERTM;

//
//启动 ePWM1、启用 SOCA 并将计数器置于递增计数模式
//
ePWM_enableADCtrigger (EPWM1_base、ePWM_SOC_A);

//
//空闲循环。 只需坐下来循环(可选):
//
for (;;)

NOP;


//
// initEPWM1 -用于配置 ePWM1的函数
//
空 initEPWM1 (空)

//将 GPIO0配置为 ePWM1A 引脚
GPIO_setPadConfig (0、GPIO_PIN_TYPE_STD);
GPIO_setPinConfig (GPIO_0_EPWM1A);// GPIO0 = PWM1A

//
//设置 TBCLK
//
ePWM_setTimeBasePeriod (EPWM1_base、EPWM1_TIMER_TBPRD);
ePWM_setPhaseShift (EPWM1_base、0U);
ePWM_setTimeBaseCounter (EPWM1_base、0);

//
//将比较 A 值设置为1000,即20%占空比或10us
//

ePWM_setCounterCompareValue (EPWM1_base、ePWM_COUNTER_COMPARE_A、EPWM1_CMPA);
//
//设置计数器模式
//
ePWM_setTimeBaseCounterMode (EPWM1_base、ePWM_COUNTER_MODE_UP);
ePWM_DisablePhaseShiftLoad (EPWM1_base);
ePWM_setClockPrescaler (EPWM1_base、ePWM_CLOCK 分频器_1、ePWM_HSCLOCK_divider 1);

//
//设置隐藏
//
EPWM_setCounterCompareShadowImage LoadMode (EPWM1_BASE、
ePWM_COUNTER_COMPARE_A、
ePWM_COMP_LOAD_ON_CNTR_ZERO);
//
//设置操作
//
ePWM_setActionQualifierAction (EPWM1_base、
ePWM_AQ_OUTPUT A、
ePWM_AQ_OUTPUT 高电平、
ePWM_AQ_output_on_timebase_zero);

ePWM_setActionQualifierAction (EPWM1_base、
ePWM_AQ_OUTPUT A、
ePWM_AQ_OUTPUT 低电平、
ePWM_AQ_output_on_timebase_up_CMPA);

//
//禁用 SOCA
//
ePWM_DisableADCtrigger (EPWM1_base、ePWM_SOC_A);

//此处、当时基计数器等于零时、ADC 被触发
ePWM_setADCTriggerSource (EPWM1_base、ePWM_SOC_A、ePWM_SOC_TBCTR_ZERO);

ePWM_setADCTriggerEventPrescale (EPWM1_base、ePWM_SOC_A、1);

//
//在10us 后中断、ADC 数据处理将开始
//
ePWM_setInterruptSource (EPWM1_base、ePWM_INT_TBCTR_U_CMPA);
ePWM_enableInterrupt (EPWM1_base);
ePWM_setInterruptEventCount (EPWM1_BASE、1);


void initadC()

//将 VREF 设置为内部
ADC_setVREF (ADCA_BASE、ADC_reference_internal、ADC_reference_3_3V);
ADC_setVREF (ADCB_BASE、ADC_reference_internal、ADC_reference_3_3V);
ADC_setVREF (ADCC_BASE、ADC_reference_internal、ADC_reference_3_3V);

//
//将 ADCCLK 分频器设置为/2
//
ADC_setPrescaler (ADCA_BASE、ADC_CLK_DIV_2_0);
ADC_setPrescaler (ADCB_BASE、ADC_CLK_DIV_2_0);
ADC_setPrescaler (ADCC_BASE、ADC_CLK_DIV_2_0);


//
//将脉冲位置设置为晚期
// TODO:更改为 ACQ 结束
ADC_setInterruptPulseMode (ADCA_BASE、ADC_PULSE_END_TO_ACQ_WIN);
ADC_setInterruptPulseMode (ADCB_BASE、ADC_PULSE_END_TO_ACQ_WIN);
ADC_setInterruptPulseMode (ADCC_BASE、ADC_PULSE_END_TO_ACQ_WIN);

//
//为 ADC 加电、然后延迟1ms
//
ADC_enableConverter (ADCA_BASE);
ADC_enableConverter (ADCB_BASE);
ADC_enableConverter (ADCC_BASE);
DEVICE_DELAY_US (1000);


空 initADCSOC (空)

//通过将所有 SOC 设置为高优先级来禁用循环指针
ADC_setSOCPriority (ADCA_BASE、ADC_PRI_All_HIPRI);
ADC_setSOCPriority (ADCB_BASE、ADC_PRI_All_HIPRI);
ADC_setSOCPriority (ADCC_BASE、ADC_PRI_All_HIPRI);


//
//配置 ADCA 的 SOC
//- SOC0和 SOC1将转换引脚 A2、采样窗口为10个 SYSCLK 周期。
//- SOC2将转换引脚 A3、采样窗口为10个 SYSCLK 周期。
//
ADC_setupSOC (ADCA_BASE、ADC_SOC_NUMBER0、ADC_TRIGGER_EPWM1_SOCA、ADC_CH_ADCIN2、10);
ADC_setupSOC (ADCA_BASE、ADC_SOC_NUMBER1、ADC_TRIGGER_EPWM1_SOCA、ADC_CH_ADCIN2、10);
ADC_setupSOC (ADCA_BASE、ADC_SOC_NUMBER2、ADC_TRIGGER_EPWM1_SOCA、ADC_CH_ADCIN3、10);

//
//配置 ADCB 的 SOC
//- SOC0和 SOC1将转换引脚 B2、采样窗口为10个 SYSCLK 周期。
//
ADC_setupSOC (ADCB_BASE、ADC_SOC_NUMBER0、ADC_TRIGGER_EPWM1_SOCA、ADC_CH_ADCIN2、10);
ADC_setupSOC (ADCB_BASE、ADC_SOC_NUMBER1、ADC_TRIGGER_EPWM1_SOCA、ADC_CH_ADCIN2、10);

//
//配置 ADCC 的 SOC
//- SOC0和 SOC1将转换引脚 C0、其采样窗口为10个 SYSCLK 周期。
//- SOC2将用一个10个 SYSCLK 周期的采样窗口来转换引脚 C2。
//- SOC3将用一个10个 SYSCLK 周期的采样窗口来转换引脚 C4。
//
ADC_setupSOC (ADCC_BASE、ADC_SOC_NUMBER0、ADC_TRIGGER_EPWM1_SOCA、ADC_CH_ADCIN0、10);
ADC_setupSOC (ADCC_BASE、ADC_SOC_number1、ADC_TRIGGER_EPWM1_SOCA、ADC_CH_ADCIN0、10);
ADC_setupSOC (ADCC_BASE、ADC_SOC_numer2、ADC_TRIGGER_EPWM1_SOCA、ADC_CH_ADCIN2、10);
ADC_setupSOC (ADCC_BASE、ADC_SOC_Number3、ADC_TRIGGER_EPWM1_SOCA、ADC_CH_ADCIN4、10);


//
// epwm1ISR - EPWM1中断 ISR
//
_interrupt void epwm1ISR (void)

GPIO_writePin (4、1);
//延迟2us。
DEVICE_DELAY_US (2);
GPIO_writePin (4、0);

//
//清除此计时器的 INT 标志
//
ePWM_clearEventTriggerInterruptFlag (EPWM1_BASE);

//
//确认中断组
//
INTERRUPT_clearACKGROUP (INTERRUPT_ACK_Group3);

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Anusha、您好!

    中断延迟只能是~14SYSCLK 周期、这是从触发中断到进入 ISR 的时间代码的时间。
    因此、10us 数字远高于预期延迟。
    在本例中、您如何测量延迟? 当您说 GPIO 切换时间过长时-您要测量延时时间的基准是什么?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Subrahmanya、

    我在示波器上跟踪 PWM (占空比为20%、时间为50微秒)。 同时还跟踪 GPIO 中断。

    当 TBCTR = CMPA (10us)时、PWM 中断被记录。 当我运行程序时、我看到 GPIO 的上升沿在20%占空比后10微秒被触发(PWM 的下降沿、即 CMPA)。

    理想情况下、它应该是几纳秒。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    如果您将同一事件用于中断触发器和 PWM 边沿-那么我不希望看到太长的延迟(超出中断延迟+切换写入 GPIO 的时间)。 是否有任何其他中断正在执行中?
    我建议您禁用所有中断、并在仅打开此处所需的中断时进行检查。
    此外、您还可以使用其中一个示例来检查配置(C:\ti\c2000Ware_1_00_05_00\driverlib\f28004x\examples\ePWM)。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我只有一个中断在运行、它是 ePWM1、并且配置与示例代码完全一样。 还有其他调试功能吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我尝试运行 ePWM_ex2_updown_AQ、并且在 ISR 中添加了 GPIO 触发器。 我仍然看到10us 延迟。
    我还尝试通过闪存运行程序、但没有看到任何变化
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    系统时钟频率是多少? PWM 脉冲宽度是否与预期值匹配-这是为了确保时钟配置正确。 此外、您能否共享波形捕获?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Subrahmanya、

    系统时钟频率= 100MHz。  

    是的、PWM 脉冲宽度与我的预期值相匹配。 我将连接波形

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在上面的波形中、PWM 波形具有10%的占空比(深红色)。 GPIO 在 PWM ISR 中触发、该 ISR 在10%占空比的下降沿触发。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我在这里看不到任何明显的配置问题。 我将尝试在 h/w 上运行示例代码、并在本周结束前告知您我的观察结果。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!

    我已经更新了 ePWM_ex2_updown_AQ 上的示例、以在 ISR 中切换 GPIO (来自您的代码段)。 并且还更改了在 CMPA 匹配时生成的中断(PWM 设置和中断生成的事件相同)-延迟小于预期值1us、而不是10us。
    最好仔细检查时钟源/配置、并确保禁用其他中断源、以确保 CPU 能够进入 ISR 并切换 GPIO 异步。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您是否仍然遇到中断延迟问题? 您是否能够执行上述检查?