false

false

EN

GR5515中利用寄存器编程实现ADC编程如何启动ADC转换,目前一直在FIFO中看不到数据

130***761

2021-08-23 11:12:50

由于需要多通道采集,需要进行手动切换,为减少切换时间,需要使用寄存器编程,目前控制了CFG和CLK寄存器,但是ADC的启动一直未开始,在FIFO中看不到数据,请问下还有其他寄存器需要控制吗,还是ADC需要配合DMA一起使用才可以?

wan****com

2021-08-24 12:21:37

  ADC采用可以支持MCU Register Access和DMA Module Access方式读取ADC数据,根据您的描述,初步判断时钟未正确配置。

关于时钟的配置方式如下:

1、ADC初始化在初始化时,需要调用ll_cgc_disable_force_off_snsadc_hclk()和ll_cgc_disable_wfi_off_snsadc_hclk()开启SNSADC的总时钟,在hal_adc_init函数接口中已融入这方面的操作。

2、ADC操作在操作ADC时,实现流程为Flush ADC FIFO、Enable ADC Clock、Read ADC Data、Disable ADC Clock。注意Read ADC Data需要按照16bit进行操作。时钟操作接口有__HAL_ADC_ENABLE_CLOCK和__HAL_ADC_DISABLE_CLOCK

Enable ADC Clock之后到ADC数据生成需要时间,可以通过ll_adc_get_fifo_count接口判断当前ADC FIFO数据量。  

6条评论

您的评论

Rova

2021-08-30 17:50:06

根据我们之前的使用经验,建议用ll层操作,既可以加快执行速率,也方便代码维护。可以参考如下代码

void get_adc_value(uint16_t *p_adc_data, uint32_t length)
{
uint32_t wcont = length >> 1;
uint32_t *p_buf = (uint32_t *)p_adc_data;
uint32_t fifo_cnt;
uint32_t adc_fifo_read_retry_cnt =0;

/* Enable ADC Clock and Automatic turn off ADC clock during WFI. */
ll_cgc_disable_force_off_snsadc_hclk();
ll_cgc_disable_wfi_off_snsadc_hclk();

/* Disable the ADC peripheral */
ll_adc_disable();

/* Reset configuration */
AON->SNSADC_CFG = 0x0708070A;

// Configure ADC to sample temperature/bat data.
ll_adc_set_thresh(0x3F);//thresh cann't be zero, otherwise it will affect DMA enven if in polling mode.

ll_adc_set_channelp(LL_ADC_INPUT_SRC_IO0);
ll_adc_set_channeln(LL_ADC_INPUT_SRC_REF);

ll_adc_set_input_mode(LL_ADC_INPUT_DIFFERENTIAL);
ll_adc_set_ref(LL_ADC_REF_SRC_BUF_INT);
ll_adc_set_ref_value(ADC_REF_VALUE_0P8);
ll_adc_set_clock(LL_ADC_CLK_1P6);

/* Enable the ADC peripheral */
ll_adc_enable();

/* Flush FIFO and then enable adc clock */
do {
while(ll_adc_is_fifo_notempty())
{
ll_adc_read_fifo();
}
} while(0);

/* Enable the clock for ADC peripheral */
ll_adc_enable_clock();

while (wcont)
{
adc_fifo_read_retry_cnt = 0;
while(SET != ll_adc_is_fifo_notempty())
{
if (adc_fifo_read_retry_cnt > 1000)
{
ll_adc_disable();
ll_adc_enable_mas_rst();
ll_adc_disable_mas_rst();
ll_adc_disable_clock();
}
else
{
delay_us(1);
adc_fifo_read_retry_cnt++;
}
}

fifo_cnt = ll_adc_get_fifo_count();
fifo_cnt = fifo_cnt > wcont ? wcont : fifo_cnt;

for (uint32_t i = 0; i < fifo_cnt; i++)
{
*p_buf++ = ll_adc_read_fifo();
}
wcont -= fifo_cnt;
}

if ((0 == wcont) && (length & 0x1))
{
while(SET != ll_adc_is_fifo_notempty());
*(uint16_t *)p_buf = ll_adc_read_fifo() & 0xFFFF;
}

/* Disable the clock for ADC peripheral */
ll_adc_disable_clock();
}


0条评论

您的评论

共 2条记录
1

您的回答