tpgf 发表于 2024-10-13 16:30

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

之前看到一个博文,写的是关于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 = {0};

//采样率:ADC_CLK=25M,转换时间=239.5+12.5个周期,252*0.04 = 10.08us,采样率=1/10.08=99.2Khz
/**
* @briefinit adc1 function.
* @paramnone
* @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;
/**
* @briefinit dma1 channel1 for "adc1"
* @paramnone
* @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的值。不知为什么这样改就不行?

非常希望得到您的指导,谢谢
页: [1]
查看完整版本: AT32_ADC+DMA单次传输再触发的一个疑问