【GD32】FreeRTOS-ADC-DMA采集

本文章介绍ADC多通道采集DMA进行传输,并且在任务中实时去获取数据。

一、时钟配置

分别配置GPIO、ADC、DMA时钟

static void SystemClock_Configration(void)
{
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_GPIOB);
    rcu_periph_clock_enable(RCU_GPIOC);
    rcu_periph_clock_enable(RCU_GPIOD);
    rcu_periph_clock_enable(RCU_GPIOF);
    rcu_periph_clock_enable(RCU_CFGCMP);
    rcu_periph_clock_enable(RCU_PMU);
	
	rcu_periph_clock_enable(RCU_ADC);
    rcu_adc_clock_config(RCU_ADCCK_APB2_DIV2);  // 主频108M ADCCLK = PCLK2/2 = 27M
	
    rcu_periph_clock_enable(RCU_DMA);
}

二、GPIO配置

配置对应ADC通道GPIO为模拟输入模式

static void AdcGpioConfigration(void)
{
    gpio_deinit(GPIOA | GPIOB | GPIOC | GPIOD | GPIOF);
    gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_1);   
    gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_4);   
    gpio_mode_set(GPIOB, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_0); 
    gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_0);     
    gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_4);   
    gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_5);   
    gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_5);    
    gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_3);     
    gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_2);       
    gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_1);     
    gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_6);   
    gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_7);    
    gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_2);     
    gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_3);   
    gpio_mode_set(GPIOB, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_1);       
}

三、ADC配置

static void AdcConfiguration(void)
{
    /* reset ADC */
    adc_deinit();
    /* ADC channel length config */
    adc_channel_length_config(ADC_REGULAR_CHANNEL, ADC_LENGTH);
    /* ADC regular channel config */
    adc_regular_channel_config(0, ADC_CHANNEL_1,  ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(1, ADC_CHANNEL_14, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(2, ADC_CHANNEL_8,  ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(3, ADC_CHANNEL_10, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(4, ADC_CHANNEL_4,  ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(5, ADC_CHANNEL_15, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(6, ADC_CHANNEL_5,  ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(7, ADC_CHANNEL_13, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(8, ADC_CHANNEL_12, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(9, ADC_CHANNEL_11, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(10, ADC_CHANNEL_6, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(11, ADC_CHANNEL_7, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(12, ADC_CHANNEL_2, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(13, ADC_CHANNEL_3, ADC_SAMPLETIME_71POINT5);
    adc_regular_channel_config(14, ADC_CHANNEL_9, ADC_SAMPLETIME_71POINT5);
    /* ADC external trigger enable */
    adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);
    /* ADC external trigger source config */
    adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);
    /* ADC data alignment config */
    adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
    /* ADC SCAN & CONTINUOUS function enable */
    adc_special_function_config(ADC_SCAN_MODE, ENABLE);
    //  adc_special_function_config(ADC_CONTINUOUS_MODE, ENABLE);       //auto repeat sample
    /* ADC DMA function enable */
    adc_dma_mode_enable();
    /* enable ADC interface */
    adc_enable();
    /* ADC calibration and reset calibration */
    adc_calibration_enable(); 
		/* enable ADC software trigger */
	adc_software_trigger_enable(ADC_REGULAR_CHANNEL);
}

四、DMA配置

static void AdcDmaConfiguration(void)
{
    dma_parameter_struct dma_init_struct;
    /* initialize DMA channel0 */
    dma_deinit(DMA_CH0);
    dma_init_struct.direction    = DMA_PERIPHERAL_TO_MEMORY;
    dma_init_struct.memory_addr  = (uint32_t )adc_dma;//此处为我们定义的数组地址
    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
    dma_init_struct.number       = ADC_LENGTH;
    dma_init_struct.periph_addr  = (uint32_t) & (ADC_RDATA);
    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_init_struct.priority     = DMA_PRIORITY_ULTRA_HIGH;
    dma_init(DMA_CH0, &dma_init_struct);
    /* clear DMA a channel flag */
    dma_interrupt_flag_clear(DMA_CH0, DMA_INT_FTF);
    /* channel transfer finish interrupt */
    dma_interrupt_enable(DMA_CH0, DMA_INT_FTF);
    /* configure DMA mode */
    dma_circulation_enable(DMA_CH0);//循环模式
    dma_memory_to_memory_disable(DMA_CH0);
    /* enable DMA channel0 */
    dma_channel_enable(DMA_CH0);
}
static void AdcNvicConfiguration(void) //中断等级配置
{
	nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
	nvic_irq_enable(DMA_Channel0_IRQn, 5, 0);
}
void DMA_Channel0_IRQHandler()
{
    if(dma_interrupt_flag_get(DMA_CH0, DMA_INT_FTF) != RESET)
    {
        dma_interrupt_flag_clear(DMA_CH0, DMA_INT_FTF);
		AdcStartSampling(); //每次传输完成后立马又软件触发采集
    }
}

五、主函数代码

#define ADC_LENGTH 15 //ADC通道数量
static uint16_t adc_dma[ADC_LENGTH];

uint16_t GetAdcValue(uint8_t channel)//获取对应通道ADC值
{
	return adc_dma[channel];
}
void AdcInitialize(void) //初始化所有ADC相关配置
{
	 SystemClock_Configration();
	 AdcGpioConfigration();
	 AdcConfiguration();
 	 AdcDmaConfiguration();
	 AdcNvicConfiguration();
}
int main(void)
{
    AdcInitialize();
	taskENTER_CRITICAL();          
	xTaskCreate(AdcDebugTask1,"AdcDebugTask1",128,NULL,1,NULL);
    taskEXIT_CRITICAL();  
    while(1)
	{    
	}
}
void AdcDebugTask1(void * pvParameters)
{
	while(1)
	{
		for(int i = 0;i < 15;i++)
		{
			arr_adc[i] = GetAdcValue(i);
		}	
	}
}

六、仿真验证

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值