打印
[AT32F403/403A]

AT32F403A的ADC采集为何达不到2MHz?

[复制链接]
1002|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
baonng|  楼主 | 2025-5-15 15:07 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
在使用AT32F403ACGT7的ADC采集时,发现ADC无法达到2MSPS,不知原因在哪里?配置使用的雅特力提供的Work Bench,ADC时钟为28MHz,每路ADC只采集一个通道,ADC1和ADC2使用一路DMA控制。触发使用的是定时器2的CH2。

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

使用特权

评论回复
5
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的原因了

使用特权

评论回复
6
zjsx8192| | 2025-5-17 09:45 | 只看该作者
触发一次那数据取出来完整么

使用特权

评论回复
7
baonng|  楼主 | 2025-5-19 11:18 | 只看该作者
zjsx8192 发表于 2025-5-17 09:45
触发一次那数据取出来完整么

初始化没问题,数据就没有问题。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

27

帖子

0

粉丝