工具与软件:
您好:
我已按计时器验证 ADC 采集时间、结果有点奇怪。
在单次触发模式下、将捕获8个通道、触发器 FIFO 阈值设置为15 (8*2-1)、从 ADC 启动到进入中断的时间约为9us。
但同样、采集1个通道后、触发 FIFO 阈值设置为1 (1*2-1)、从启动 ADC 到进入中断大约需要50us。
我的问题:
1.为什么收集通道较少,但时间延长;
2.根据数据手册、采样频率是4Msps、请帮助我们确认9us 采样时间是否合理;
3、是否有措施加快采样时间。
我的程序如下、计时开始和结束于 hal_adc_trigger ()和 App_adcGetData ():
uint16_t adc_original_buff[APP_ADC_NUM_CH];
int32_t adc_buff[APP_ADC_NUM_CH];
float curr_result[3];
static HwiP_Object gAdcHwiObject;
HwiP_Params hwiPrms;
volatile uint32_t adc_start_ns = 0;
volatile uint32_t adc_interval_ns = 0;
void App_adcGetData(void)
{
uint32_t voltageLvl;
uint32_t id;
uint32_t baseAddr = CONFIG_ADC0_BASE_ADDR;
uint32_t i = 0;
uint32_t fifoData = 0;
uint32_t fifoWordCnt;
if(is_float_zero(gUserParams_float.adc_gain) == MT_TRUE)
{
gUserParams_float.adc_gain = 0.15f;
}
/* Get FIFO data */
fifoWordCnt = ADCGetFIFOWordCount(baseAddr, ADC_FIFO_NUM_0);
for (i = 0U; i < fifoWordCnt; i++)
{
fifoData = ADCGetFIFOData(baseAddr, ADC_FIFO_NUM_0);
id = ((fifoData & ADC_FIFODATA_ADCCHNLID_MASK) >>
ADC_FIFODATA_ADCCHNLID_SHIFT);
fifoData = ((fifoData & ADC_FIFODATA_ADCDATA_MASK) >>
ADC_FIFODATA_ADCDATA_SHIFT);
adc_original_buff[id] = (uint16_t)fifoData;
if((id > 2) && (id < 6))
{
voltageLvl = fifoData * (uint32_t) (V_ADC_REF * 1000);
voltageLvl /= (uint32_t) ADC_GET_RANGE(CONFIG_ADC0_NUM_BITS);
if(Old_m_state == MC_STATE_CALIBRATION)
{
//1650 = 3.3V * 1000 / 2
adc_buff[id] = voltageLvl - 1650;
}
else
{
adc_buff[id] = voltageLvl - 1650 - hal_hwParams_u32_t.PhaseCurrOffset[id - 3];
}
curr_result[id - 3] = (adc_buff[id] * 1.0f / 1000.0f) / gUserParams_float.adc_gain;
}
else
{
adc_buff[id] = fifoData;
}
}
adc_interval_ns = clock_cal_interval(adc_start_ns, clock_get_ns());
}
void App_adcISR(void *handle)
{
uint32_t status;
uint32_t baseAddr = CONFIG_ADC0_BASE_ADDR;
/* Get interrupt status and clear */
status = ADCGetIntrStatus(baseAddr);
ADCClearIntrStatus(baseAddr, status);
App_adcGetData();
/* Set EOI to generate next interrupt if any */
ADCWriteEOI(baseAddr);
}
void App_adcConfig(uint32_t baseAddr)
{
adcStepConfig_t adcConfig;
uint32_t chCnt, adcStep;
/* Enable interrupts */
ADCEnableIntr(baseAddr, ADC_INTR_SRC_FIFO0_THRESHOLD);
/*
* Configure all ADC Steps
*/
/* Initialize ADC configuration params */
adcConfig.mode = ADC_OPERATION_MODE_SINGLE_SHOT;
adcConfig.openDelay = 0x0U;
adcConfig.sampleDelay = 0U;
adcConfig.rangeCheckEnable = 0U;
adcConfig.averaging = ADC_AVERAGING_NONE;
adcConfig.fifoNum = ADC_FIFO_NUM_0;
/* Configure all required steps - Step 1 to N mapped to Channel 1 to N */
for(chCnt = 0U; chCnt < APP_ADC_NUM_CH; chCnt++)
{
adcConfig.channel = ADC_CHANNEL_1 + chCnt;
adcStep = ADC_STEP_1 + chCnt; /* Step -> Channel one to one mapped */
ADCSetStepParams(baseAddr, adcStep, &adcConfig);
}
ADCStepIdTagEnable(baseAddr, TRUE);
ADCSetCPUFIFOThresholdLevel(baseAddr, ADC_FIFO_NUM_0, APP_ADC_NUM_CH * 2);
/* Step enable */
for(chCnt = 0U; chCnt < APP_ADC_NUM_CH; chCnt++)
{
adcStep = ADC_STEP_1 + chCnt; /* Step -> Channel one to one mapped */
ADCStepEnable(baseAddr, adcStep, TRUE);
}
}
static void App_adcInit(uint32_t baseAddr)
{
/* Clear All interrupt status */
ADCClearIntrStatus(baseAddr, ADC_INTR_STATUS_ALL);
/* Register & enable interrupt */
HwiP_Params_init(&hwiPrms);
hwiPrms.intNum = CONFIG_ADC0_INTR;
hwiPrms.callback = &App_adcISR;
hwiPrms.priority = 1U;
HwiP_construct(&gAdcHwiObject, &hwiPrms);
/* Power up AFE */
ADCPowerUp(baseAddr, TRUE);
/* Wait for 4us at least */
ClockP_usleep(5U);
/* Do the internal calibration */
ADCInit(baseAddr, FALSE, 0U, 0U);
}
static void App_adcStart(uint32_t baseAddr)
{
adcSequencerStatus_t status;
/* Check if FSM is idle */
ADCGetSequencerStatus(baseAddr, &status);
while ((ADC_ADCSTAT_FSM_BUSY_IDLE != status.fsmBusy) &&
ADC_ADCSTAT_STEP_ID_IDLE != status.stepId)
{
ADCGetSequencerStatus(baseAddr, &status);
}
/* Start ADC conversion */
ADCStart(baseAddr, TRUE);
}
int32_t hal_adc_init(void)
{
uint32_t baseAddr = CONFIG_ADC0_BASE_ADDR;
App_adcInit(baseAddr);
App_adcConfig(baseAddr);
/* Set EOI to generate next interrupt if any */
ADCWriteEOI(baseAddr);
App_adcStart(baseAddr);
return MT_OK;
}
void hal_adc_trigger(void)
{
uint32_t baseAddr = CONFIG_ADC0_BASE_ADDR;
uint32_t chCnt, adcStep;
/* Step enable */
for(chCnt = 0U; chCnt < APP_ADC_NUM_CH; chCnt++)
{
adcStep = ADC_STEP_1 + chCnt; /* Step -> Channel one to one mapped */
ADCStepEnable(baseAddr, adcStep, TRUE);
}
adc_start_ns = clock_get_ns();
App_adcStart(baseAddr);
}





