您好!
我对 ADC 有疑问、在我的项目中、我使用3个 ePWM 进行半导体控制、并将 ADC 与一个 ePWM 通道同步以解决状态机问题。 我已经定义了几个对应于 ADC 每个输入的 SOC、它们是链式的、但我想在切断另一个 ePWM 的一段时间内获得几个样本。 我尝试以不同于其他 ePWM 的方式配置 TBPRD 寄存器、但它不起作用。 在本例中、我不会输入中断。 知道我已经在转换结束时配置了中断。
目前、采样工作正常、但频率未达到所需频率、我希望在开关周期中具有更多的点
如果我在用于 ADC 同步的 ePWM 通道上设置更高的频率、为什么它不起作用?
谢谢
/**ePWM initialization with phase shift*/
void epwm_init(uint32_t base, uint16_t phi)
{
/**Parameters*/
EPWM_setTimeBaseCounterMode(base, EPWM_COUNTER_MODE_UP);
EPWM_setTimeBasePeriod(base, EPWM_TBPRD);
EPWM_setTimeBaseCounter(base, 0U);
EPWM_setClockPrescaler(base, EPWM_CLOCK_DIVIDER_4, EPWM_HSCLOCK_DIVIDER_4);
/**Set up shadowing*/
EPWM_setCounterCompareShadowLoadMode(base, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO);
/**Set actions
For boost assembly*/
EPWM_setActionQualifierAction(base, SPWM_TOP, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA);
EPWM_setActionQualifierAction(base, SPWM_TOP, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
/**For buck assembly*/
EPWM_setActionQualifierAction(base, SPWM_BOT, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB);
EPWM_setActionQualifierAction(base, SPWM_BOT, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);
EPWM_setActionQualifierContSWForceAction(SPWM_U, SPWM_BOT, EPWM_AQ_SW_OUTPUT_LOW);
EPWM_setActionQualifierContSWForceAction(SPWM_V, SPWM_BOT, EPWM_AQ_SW_OUTPUT_LOW);
EPWM_setActionQualifierContSWForceAction(SPWM_W, SPWM_BOT, EPWM_AQ_SW_OUTPUT_LOW);
EPWM_setActionQualifierContSWForceAction(SPWM_U, SPWM_TOP, EPWM_AQ_SW_OUTPUT_LOW);
EPWM_setActionQualifierContSWForceAction(SPWM_V, SPWM_TOP, EPWM_AQ_SW_OUTPUT_LOW);
EPWM_setActionQualifierContSWForceAction(SPWM_W, SPWM_TOP, EPWM_AQ_SW_OUTPUT_LOW);
if(base == SPWM_FOR_ADC)
{
-> EPWM_setTimeBasePeriod(base, EPWM_TBPRD);
/**Initialize PWM to add samples ADC in loop close regulation*/
EPWM_setCounterCompareValue(base, EPWM_COUNTER_COMPARE_A, CMPA_EPWM_ADC);
}
/**Configure ePMWs*/
// Todo comments to explain
if(phi == 0)
{
EPWM_disablePhaseShiftLoad(base);
EPWM_setPhaseShift(base, phi);
EPWM_enableSyncOutPulseSource(base, EPWM_SYNC_OUT_PULSE_ON_CNTR_ZERO);
}
else
{
uint16_t tbphs = epwm_get_tbphs_from_phi(base, phi);
EPWM_setSyncInPulseSource(base, EPWM_SYNC_IN_PULSE_SRC_SYNCOUT_EPWM1);
EPWM_enablePhaseShiftLoad(base);
EPWM_selectPeriodLoadEvent(base, EPWM_SHADOW_LOAD_MODE_SYNC);
EPWM_setPhaseShift(base, tbphs);
EPWM_setTimeBaseCounter(base, tbphs);
}
}
ADC configuration
/**
* Configure ADC set pulse at End Of Conversion to enter on interrupt when ADC register is full
*/
void adc_config(uint32_t adc_base)
{
/**
* Enable ADC with external reference A4 (3V)
*/
ADC_setVREF(adc_base, ADC_REFERENCE_EXTERNAL, ADC_REFERENCE_3_3V);
ADC_setPrescaler(adc_base, ADC_CLK_DIV_1_0);
/**
* Set pulse ADCINTx at the end of conversion
*/
ADC_setInterruptPulseMode(adc_base, ADC_PULSE_END_OF_CONV);
if(adc_base == ADCA_BASE)
{
/**
* Configure the SOC to occur on the first up-count event
*/
EPWM_setADCTriggerSource(SPWM_FOR_ADC, EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPA);
/**
* Sets the SOC event count that determines the number of events that have to occur before an SOC is issued.
*/
EPWM_setADCTriggerEventPrescale(SPWM_FOR_ADC, EPWM_SOC_A, PRESCALE_COUNT_ADC_SOC);
EPWM_enableADCTrigger(SPWM_FOR_ADC, EPWM_SOC_A);
}
ADC_enableConverter(adc_base);
/**
* Delay to allow ADC time to power up
*/
DEVICE_DELAY_US(ADC_DELAY_POWERUP_US);
}
/**
* Corresponding module ADCx -> SOC -> pin.
* Enchainement des SOC une fois la conversion terminée sur un SOC. SOC0 will start at 1 / PWM_FREQ and an another SOC0 at 1 / PWM_FREQ after.
* See notes for ADC_ACQPS_WINDOW details.
* Two conversions per SOC : the first on ADCA and the other on ADCC.
*/
void adc_init_soc(void)
{
/**MU_TRAC_BATT_FLT with pin ADCINA3*/
ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM7_SOCA, ADC_CH_ADCIN3, ADC_ACQPS_WINDOW);
/**MU_FUEL_CELL_FLT with pin ADCINA2*/
ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER1, ADC_TRIGGER_EPWM7_SOCA, ADC_CH_ADCIN2, ADC_ACQPS_WINDOW);
/**MI_TRAC_BATT_FLT with pin ADCINA14*/
ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER2, ADC_TRIGGER_EPWM7_SOCA, ADC_CH_ADCIN14, ADC_ACQPS_WINDOW);
/**MU_FUEL_CELL_PCH_FLT with pin ADCINA0*/
ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER3, ADC_TRIGGER_EPWM7_SOCA, ADC_CH_ADCIN0, ADC_ACQPS_WINDOW);
/**MU_TRAC_BATT_PCH_FLT with pin ADCINC6*/
ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM7_SOCA, ADC_CH_ADCIN6, ADC_ACQPS_WINDOW);
/**MT_COLD_PLATE_FLT with pin ADCINC0*/
ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER1, ADC_TRIGGER_EPWM7_SOCA, ADC_CH_ADCIN0, ADC_ACQPS_WINDOW);
/**MI_L_U_FLT with pin ADCINC14*/
ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER2, ADC_TRIGGER_EPWM7_SOCA, ADC_CH_ADCIN14, ADC_ACQPS_WINDOW);
/**MI_L_V_FLT with pin ADCINC8*/
ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER3, ADC_TRIGGER_EPWM7_SOCA, ADC_CH_ADCIN8, ADC_ACQPS_WINDOW);
/**MI_L_W_FLT with pin ADCINC10*/
ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER4, ADC_TRIGGER_EPWM7_SOCA, ADC_CH_ADCIN10, ADC_ACQPS_WINDOW);
/**Corresponding EOC to ADCINTX pulse to enter on interrupt for read ADCRESULTx registers. Refer to ADCINTSEL1N2 and ADCRESULTx registers.*/
ADC_setInterruptSource(ADCC_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER4);
ADC_enableInterrupt(ADCC_BASE, ADC_INT_NUMBER1);
ADC_clearInterruptStatus(ADCC_BASE, ADC_INT_NUMBER1);
}
/**Enter on interrupt when SOC4 on ADCC will end. Only average samples in interrupt and not conversion to have more time available.
See requirement REQ_SYST0006*/
__interrupt void isr_adc(void)
{
//
// Save IER register on stack
//
//volatile uint16_t tempPIEIER = HWREGH(PIECTRL_BASE + PIE_O_IER1);
//
// Set the global and group priority to allow CPU interrupts
// with higher priority
//
/*IER |= M_INT1;
IER &= MINT1;
HWREGH(PIECTRL_BASE + PIE_O_IER1) &= MG1_3;
//
// Enable Interrupts
//
Interrupt_clearACKGroup(0xFFFFU);
__asm(" NOP");
EINT;*/
/**Read samples results in ADCARESULT registers and stock them.*/
MU_TRAC_BATT_PCH_FLT_SAMPLE = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER0);
MT_COLD_PLATE_FLT_SAMPLE = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER1);
MI_L_U_FLT_SAMPLE = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER2);
MI_L_V_FLT_SAMPLE = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER3);
MI_L_W_FLT_SAMPLE = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER4);
MU_TRAC_BATT_FLT_SAMPLE = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0);
MU_FUEL_CELL_FLT_SAMPLE = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER1);
MI_TRAC_BATT_FLT_SAMPLE = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER2);
MU_FUEL_CELL_PCH_FLT_SAMPLE = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER3);
average();
/**Clear the interrupt flag*/
ADC_clearInterruptStatus(ADCC_BASE, ADC_INT_NUMBER1);
/**Check if overflow has occurred*/
if(ADC_getInterruptOverflowStatus(ADCC_BASE, ADC_INT_NUMBER1) == true)
{
ADC_clearInterruptOverflowStatus(ADCC_BASE, ADC_INT_NUMBER1);
ADC_clearInterruptStatus(ADCC_BASE, ADC_INT_NUMBER1);
}
/**Acknowledge the interrupt, see PIE Interrupt Vectors table*/
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
//
// Disable interrupts and restore registers saved:
//
/*DINT;
HWREGH(PIECTRL_BASE + PIE_O_IER1) = tempPIEIER;*/
}