打印
[应用相关]

AT32_ADC+DMA单次传输再触发的一个疑问

[复制链接]
1602|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2024-10-13 16:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
DM, DMA, AD, ADC, dc
之前看到一个博文,写的是关于AT32_ADC+DMA单次传输再触发的一个例子,这个例子里边分两次配置的DMA,那么我想要问一下,针对不同的功能使用dma  是不是可以一次性配置好呢?一下是博文内容:



ADC+DMA软件触发,DMA配置传输完中断

#define Channel_num 4
#define ADC1_BUffer_Size 64
#define DMA_buffer_size  (Channel_num*ADC1_BUffer_Size)
uint16_t ADC1_Buffer[ADC1_BUffer_Size][Channel_num] = {0};

//采样率:ADC_CLK=25M,转换时间=239.5+12.5个周期,252*0.04 = 10.08us,采样率=1/10.08=99.2Khz
/**
  * @brief  init adc1 function.
  * @param  none
  * @retval none
  */
void wk_adc1_init(void)
{
  crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE);
  crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);

  gpio_init_type gpio_init_struct;
  adc_base_config_type adc_base_struct;

  gpio_default_para_init(&gpio_init_struct);

  /*gpio--------------------------------------------------------------------*/
  /* configure the IN10 pin */
  gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
  gpio_init_struct.gpio_pins = GPIO_PINS_0;
  gpio_init(GPIOC, &gpio_init_struct);

  /* configure the IN11 pin */
  gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
  gpio_init_struct.gpio_pins = GPIO_PINS_1;
  gpio_init(GPIOC, &gpio_init_struct);

  /* configure the IN12 pin */
  gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
  gpio_init_struct.gpio_pins = GPIO_PINS_2;
  gpio_init(GPIOC, &gpio_init_struct);

  /* configure the IN13 pin */
  gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
  gpio_init_struct.gpio_pins = GPIO_PINS_3;
  gpio_init(GPIOC, &gpio_init_struct);

  crm_adc_clock_div_set(CRM_ADC_DIV_4);//4分频,APB2/4 = 25Mhz

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

  /*adc_settings--------------------------------------------------------------------*/
  adc_base_default_para_init(&adc_base_struct);
  adc_base_struct.sequence_mode = TRUE;
  adc_base_struct.repeat_mode = TRUE;
  adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
  adc_base_struct.ordinary_channel_length = 4;
  adc_base_config(ADC1, &adc_base_struct);

  /* adc_ordinary_conversionmode-------------------------------------------- */
  adc_ordinary_channel_set(ADC1, ADC_CHANNEL_10, 1, ADC_SAMPLETIME_239_5);
  adc_ordinary_channel_set(ADC1, ADC_CHANNEL_11, 2, ADC_SAMPLETIME_239_5);
  adc_ordinary_channel_set(ADC1, ADC_CHANNEL_12, 3, ADC_SAMPLETIME_239_5);
  adc_ordinary_channel_set(ADC1, ADC_CHANNEL_13, 4, ADC_SAMPLETIME_239_5);

  adc_ordinary_conversion_trigger_set(ADC1, ADC12_ORDINARY_TRIG_SOFTWARE, TRUE);

  adc_ordinary_part_mode_enable(ADC1, FALSE);

  adc_dma_mode_enable(ADC1, TRUE);
  adc_enable(ADC1, TRUE);

  /* adc calibration-------------------------------------------------------- */
  adc_calibration_init(ADC1);
  while(adc_calibration_init_status_get(ADC1));
  adc_calibration_start(ADC1);
  while(adc_calibration_status_get(ADC1));

}


uint8_t adc_flag=0;
/**
  * @brief  init dma1 channel1 for "adc1"
  * @param  none
  * @retval none
  */
void wk_dma1_channel1_init(void)
{
  dma_init_type dma_init_struct;
  crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
  dma_reset(DMA1_CHANNEL1);
  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_HALFWORD;
  dma_init_struct.memory_inc_enable = TRUE;
  dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_HALFWORD;
  dma_init_struct.peripheral_inc_enable = FALSE;
  dma_init_struct.priority = DMA_PRIORITY_MEDIUM;
  dma_init_struct.loop_mode_enable = FALSE;

  dma_init_struct.peripheral_base_addr = (uint32_t)&ADC1->odt;
  dma_init_struct.memory_base_addr = (uint32_t)ADC1_Buffer;
  dma_init_struct.buffer_size = DMA_buffer_size;
  dma_init(DMA1_CHANNEL1, &dma_init_struct);
     nvic_irq_enable(DMA1_Channel1_IRQn, 1, 0);
  /* flexible function enable */
  dma_flexible_config(DMA1, FLEX_CHANNEL1, DMA_FLEXIBLE_ADC1);

  dma_interrupt_enable(DMA1_CHANNEL1, DMA_FDT_INT, TRUE);
}

void ADC1_Init()
{
     wk_dma1_channel1_init();
     dma_channel_enable(DMA1_CHANNEL1, TRUE);
     wk_adc1_init();
     adc_ordinary_software_trigger_enable(ADC1, TRUE);//软件触发
}
触发结束后,再次设置DMA传递数据长度并使能

dma_channel_enable(DMA1_CHANNEL1, FALSE);
        dma_data_number_set(DMA1_CHANNEL1,256);
        dma_channel_enable(DMA1_CHANNEL1, TRUE);
        adc_ordinary_software_trigger_enable(ADC1, TRUE);//软件触发



原文链接:https://blog.csdn.net/weixin_43554366/article/details/142836052


使用特权

评论回复
沙发
可怜的小弗朗士| | 2024-10-22 11:38 | 只看该作者
单次触发后,必须再次配置传输长度才行啊

使用特权

评论回复
板凳
黑心单片机| | 2024-11-16 19:32 | 只看该作者
同一个功能再次触发只需要配置传输长度就行,但是不同的功能还是要重新配置DMA

使用特权

评论回复
地板
zhjb1| | 2024-11-18 19:14 | 只看该作者
您好!
看了您的帖子很有启发,我想弄成可触发式的,结果有一个问题。
我用AWB创建的工程,其中ADC1给放到中断DMA2_CANNAL4_5,在工程代码中可以找到是DMA2_CANNAL_4,由此更改DMA初始化全都写成DMA2,DMA2_CANNAL_4;由于ADC原创建了5个:ADC1的IN1,IN2,IN3,IN6,IN7;IN4,IN5作为DAC用了。为了适应代码,将IN7去掉了,正好余4路ADC;将您说的重新给出DMA长度的那几行放到软起动代码段中;由主程序控制采样。将中断IRQn——只有void DMA2_Channel4_5_IRQHandler(void)这个中断源,曾经将那几行代码放这个中断请求中。改完之后,无论是主控还是中断请求,都依旧没有出来任何ADC的值。不知为什么这样改就不行?

非常希望得到您的指导,谢谢

使用特权

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

本版积分规则

2022

主题

15893

帖子

13

粉丝