[AT32F403/403A] AT32F403A的ADC采集为何达不到2MHz?

[复制链接]
 楼主| baonng 发表于 2025-5-15 15:07 | 显示全部楼层 |阅读模式
在使用AT32F403ACGT7的ADC采集时,发现ADC无法达到2MSPS,不知原因在哪里?配置使用的雅特力提供的Work Bench,ADC时钟为28MHz,每路ADC只采集一个通道,ADC1和ADC2使用一路DMA控制。触发使用的是定时器2的CH2。
7563268259046914f7.png
void wk_adc12_init(void)
{
  gpio_init_type gpio_init_struct;
  adc_base_config_type adc_base_struct;

  gpio_default_para_init(&gpio_init_struct);

  /* add user code begin adc1_init 1 */

  /* add user code end adc1_init 1 */

  /*gpio--------------------------------------------------------------------*/
  /* configure the IN2 pin  and  configure the IN6 pin*/
  gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
  gpio_init_struct.gpio_pins = GPIO_PINS_2 | GPIO_PINS_6;
  gpio_init(GPIOA, &gpio_init_struct);

  crm_adc_clock_div_set(CRM_ADC_DIV_4);

  /*adc_common_settings-------------------------------------------------------------*/
  adc_combine_mode_select(ADC_ORDINARY_SMLT_ONLY_MODE);

  /*adc_settings--------------------------------------------------------------------*/
  adc_base_default_para_init(&adc_base_struct);
  adc_base_struct.sequence_mode = FALSE;
  adc_base_struct.repeat_mode = FALSE;
  adc_base_struct.data_align = ADC_LEFT_ALIGNMENT;
  adc_base_struct.ordinary_channel_length = 1;
  adc_base_config(ADC1, &adc_base_struct);
  /* adc_ordinary_conversionmode-------------------------------------------- */
  adc_ordinary_channel_set(ADC1, ADC_CHANNEL_2, 1, ADC_SAMPLETIME_1_5);
  adc_ordinary_conversion_trigger_set(ADC1, ADC12_ORDINARY_TRIG_TMR2CH2, TRUE);                // 定时器2触发
  adc_dma_mode_enable(ADC1, TRUE);
       
  /*adc_settings--------------------------------------------------------------------*/
  adc_base_config(ADC2, &adc_base_struct);
  /* adc_ordinary_conversionmode-------------------------------------------- */
  adc_ordinary_channel_set(ADC2, ADC_CHANNEL_6, 1, ADC_SAMPLETIME_1_5);
  adc_ordinary_conversion_trigger_set(ADC2, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);

  adc_interrupt_enable(ADC1, ADC_CCE_INT, TRUE);
  adc_enable(ADC1, TRUE);
  adc_enable(ADC2, TRUE);

  /* adc calibration-------------------------------------------------------- */
  adc_calibration_init(ADC1);
  while(adc_calibration_init_status_get(ADC1));
  adc_calibration_start(ADC1);
  while(adc_calibration_status_get(ADC1));
  /* adc calibration-------------------------------------------------------- */
  adc_calibration_init(ADC2);
  while(adc_calibration_init_status_get(ADC2));
  adc_calibration_start(ADC2);
  while(adc_calibration_status_get(ADC2));
       
  adc_enable(ADC1, FALSE); adc_enable(ADC2, FALSE);
}

void wk_dma1_channel2_init(void)  // DMA初始化
{
  dma_init_type dma_init_struct;

  dma_reset(DMA1_CHANNEL2);
  dma_default_para_init(&dma_init_struct);
  dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
  dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_WORD;
  dma_init_struct.memory_inc_enable = TRUE;
  dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_WORD;
  dma_init_struct.peripheral_inc_enable = FALSE;
  dma_init_struct.priority = DMA_PRIORITY_LOW;
  dma_init_struct.loop_mode_enable = TRUE;
  dma_init(DMA1_CHANNEL2, &dma_init_struct);

  /* flexible function enable */
  dma_flexible_config(DMA1, FLEX_CHANNEL2, DMA_FLEXIBLE_ADC1);

  wk_dma_channel_config(DMA1_CHANNEL2,
                        (uint32_t)&ADC1->odt,
                        (uint32_t)adc_buff,
                        1024);
  dma_channel_enable(DMA1_CHANNEL2, TRUE);

}

// 定时器2初始化
void wk_tmr2_init(void)
{
  tmr_output_config_type tmr_oc_init_structure;
  /* configure counter settings */
  tmr_cnt_dir_set(TMR2, TMR_COUNT_UP);
  tmr_clock_source_div_set(TMR2, TMR_CLOCK_DIV1);
  tmr_base_init(TMR2, 3, 27);

  /* configure overflow event */
       
  tmr_output_default_para_init(&tmr_oc_init_structure);
  tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
  tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_LOW;
  tmr_oc_init_structure.oc_output_state = TRUE;
  tmr_oc_init_structure.oc_idle_state = FALSE;
  tmr_output_channel_config(TMR2, TMR_SELECT_CHANNEL_2, &tmr_oc_init_structure);
  tmr_channel_enable(TMR2, TMR_SELECT_CHANNEL_2, TRUE);
  tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_2, 2);
  //tmr_counter_enable(TMR2, TRUE);
}

以上就是ADC相关的初始化,对被采对象采集时,发现,只能达到1MHZ的采样速率,还望熟悉的工程师告知问题,谢谢!!!
骑着蜗牛狂奔O 发表于 2025-5-15 17:19 | 显示全部楼层
将两个ADC的这个语句adc_base_struct.repeat_mode = FALSE;
改成adc_base_struct.repeat_mode = TRUE;

ADC工作在反复模式,ADC只需要触发一次,然后ADC转换速度就可以达到2M

原因是ADC从接收到触发信号到开始转换,会有一点延时,TMR的触发信号间隔刚好时2M,所以在第二次触发来的时候,ADC其实还在转换,所以你速度要跑满2M的话,就让ADC工作在反复模式

xionghaoyun 发表于 2025-5-16 08:54 | 显示全部楼层
学习一下
 楼主| baonng 发表于 2025-5-16 09:16 | 显示全部楼层
骑着蜗牛狂奔O 发表于 2025-5-15 17:19
将两个ADC的这个语句adc_base_struct.repeat_mode = FALSE;
改成adc_base_struct.repeat_mode = TRUE;

改为TRUE后,就是2MHz了,但是改变定时触发就无效了。如果这是改变定时器为500K,他还是2MHz
 楼主| baonng 发表于 2025-5-16 09:17 | 显示全部楼层
骑着蜗牛狂奔O 发表于 2025-5-15 17:19
将两个ADC的这个语句adc_base_struct.repeat_mode = FALSE;
改成adc_base_struct.repeat_mode = TRUE;

多谢你的回答,知道了为何不能到2M的原因了
zjsx8192 发表于 2025-5-17 09:45 | 显示全部楼层
触发一次那数据取出来完整么
 楼主| baonng 发表于 2025-5-19 11:18 | 显示全部楼层
zjsx8192 发表于 2025-5-17 09:45
触发一次那数据取出来完整么

初始化没问题,数据就没有问题。
mnynt121 发表于 2025-6-4 10:01 | 显示全部楼层
ADC 的时钟频率通常是由系统时钟分频得到的。
cemaj 发表于 2025-6-4 10:44 | 显示全部楼层
AT32F403A的ADC在数据手册中标注的最高采样率
vivilyly 发表于 2025-6-4 12:31 | 显示全部楼层
12 位 ADC 的建立时间通常是时间常数的 8.4 倍,这在一定程度上限制了其最高采样率
hearstnorman323 发表于 2025-6-4 15:17 | 显示全部楼层
ADC的转换速率通常有一个上限,这个上限在数据手册中有明确的说明。
mnynt121 发表于 2025-6-5 11:56 | 显示全部楼层
直接测量ADC_CLK引脚波形,确认实际频率是否达到预期。
qiufengsd 发表于 2025-6-5 15:48 | 显示全部楼层
ADC 采集需要一定的时间对内部电容进行充电,如果采样时间设置过短,电容无法充满电,导致电压不稳定,会影响转换精度和采集速率。
robincotton 发表于 2025-6-5 17:59 | 显示全部楼层
ADC每个通道的采样时间需足够长以完成信号采集。
mattlincoln 发表于 2025-6-5 20:30 | 显示全部楼层
硬件限制与IO配置              
houjiakai 发表于 2025-6-5 22:28 | 显示全部楼层
AT32F403A的ADC可能无法支持2MHz的转换速率。
mollylawrence 发表于 2025-6-6 08:55 | 显示全部楼层
时钟配置限制              
eefas 发表于 2025-6-6 10:50 | 显示全部楼层
ADC的转换速率受到其时钟频率的限制。
pixhw 发表于 2025-6-6 13:30 | 显示全部楼层
实际应用中,为了保证采样精度和稳定性,可能会选择较大的采样周期数,从而导致实际采样频率无法达到2MHz。
pentruman 发表于 2025-6-6 15:17 | 显示全部楼层
采样时间直接影响总转换周期。              
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

29

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部