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.
工具/软件: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);
}
您好、Subrahmanya、
系统时钟频率= 100MHz。
是的、PWM 脉冲宽度与我的预期值相匹配。 我将连接波形