本帖最后由 guozq980 于 2023-12-16 16:16 编辑
GD32F470 ADC0_ADC1_ADC2_所有的ADC工作在常规并行模式,DMA传送数据,怎么每隔一段时间数据就错位了?
#include "bsp_timer.h"
#define EPS_ADC_ALL_ROUTINE_PARALLEL
#define ADC0_CONVERT_COUNT 6
#define ADC1_CONVERT_COUNT 6
#define ADC2_CONVERT_COUNT 6
uint16_t adc_convert_value[ADC0_CONVERT_COUNT + ADC1_CONVERT_COUNT + ADC2_CONVERT_COUNT];
static void rcu_config(void)
{
// enable GPIOC clock
rcu_periph_clock_enable(RCU_DMA1);
rcu_periph_clock_enable(RCU_ADC0);
rcu_periph_clock_enable(RCU_ADC1);
rcu_periph_clock_enable(RCU_ADC2);
//adc_clock_config(ADC_ADCCK_PCLK2_DIV4); // ADC CLK 120MHz / 4 = 30MHz
adc_clock_config(ADC_ADCCK_HCLK_DIV6); // ADC CLK 240MHz / 6 = 40MHz
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_GPIOC);
}
static void gpio_config(void)
{
// config the GPIO as analog mode
gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_0);
gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_1);
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(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_4);
gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_5);
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(GPIOB, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_0);
gpio_mode_set(GPIOB, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_1);
gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_0);
gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_1);
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_3);
gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_4);
gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_5);
}
#ifndef EPS_ADC_ALL_ROUTINE_PARALLEL
static void adc0_dma_config(void)
{
// ADC_DMA_channel configuration
dma_single_data_parameter_struct dma_single_data_parameter;
// ADC DMA_channel configuration
dma_deinit(DMA1, DMA_CH0);
// initialize DMA single data mode
dma_single_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA(ADC0));
dma_single_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_single_data_parameter.memory_addr = (uint32_t)(&adc_convert_value[0]);
dma_single_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_single_data_parameter.periph_memory_width = DMA_PERIPH_WIDTH_16BIT;
dma_single_data_parameter.direction = DMA_PERIPH_TO_MEMORY;
dma_single_data_parameter.number = ADC0_CONVERT_COUNT;
dma_single_data_parameter.priority = DMA_PRIORITY_HIGH;
dma_single_data_mode_init(DMA1, DMA_CH0, &dma_single_data_parameter);
dma_channel_subperipheral_select(DMA1, DMA_CH0, DMA_SUBPERI0);
// enable DMA circulation mode
dma_circulation_enable(DMA1, DMA_CH0);
nvic_irq_enable(DMA1_Channel0_IRQn, 0, 4);
dma_flag_clear(DMA1, DMA_CH0, DMA_FLAG_FTF | DMA_FLAG_HTF);
dma_interrupt_enable(DMA1, DMA_CH0, DMA_CHXCTL_FTFIE);
// enable DMA channel
dma_channel_enable(DMA1, DMA_CH0);
}
static void adc1_dma_config(void)
{
// ADC_DMA_channel configuration
dma_single_data_parameter_struct dma_single_data_parameter;
// ADC DMA_channel configuration
dma_deinit(DMA1, DMA_CH2);
// initialize DMA single data mode
dma_single_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA(ADC1));
dma_single_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_single_data_parameter.memory_addr = (uint32_t)(&adc_convert_value[6]);
dma_single_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_single_data_parameter.periph_memory_width = DMA_PERIPH_WIDTH_16BIT;
dma_single_data_parameter.direction = DMA_PERIPH_TO_MEMORY;
dma_single_data_parameter.number = ADC0_CONVERT_COUNT;
dma_single_data_parameter.priority = DMA_PRIORITY_HIGH;
dma_single_data_mode_init(DMA1, DMA_CH2, &dma_single_data_parameter);
dma_channel_subperipheral_select(DMA1, DMA_CH2, DMA_SUBPERI1);
// enable DMA circulation mode
dma_circulation_enable(DMA1, DMA_CH2);
nvic_irq_enable(DMA1_Channel2_IRQn, 0, 4);
dma_flag_clear(DMA1, DMA_CH2, DMA_FLAG_FTF | DMA_FLAG_HTF);
dma_interrupt_enable(DMA1, DMA_CH2, DMA_CHXCTL_FTFIE);
// enable DMA channel
dma_channel_enable(DMA1, DMA_CH2);
}
static void adc2_dma_config(void)
{
// ADC_DMA_channel configuration
dma_single_data_parameter_struct dma_single_data_parameter;
// ADC DMA_channel configuration
dma_deinit(DMA1, DMA_CH1);
// initialize DMA single data mode
dma_single_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA(ADC2));
dma_single_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_single_data_parameter.memory_addr = (uint32_t)(&adc_convert_value[12]);
dma_single_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_single_data_parameter.periph_memory_width = DMA_PERIPH_WIDTH_16BIT;
dma_single_data_parameter.direction = DMA_PERIPH_TO_MEMORY;
dma_single_data_parameter.number = ADC0_CONVERT_COUNT;
dma_single_data_parameter.priority = DMA_PRIORITY_HIGH;
dma_single_data_mode_init(DMA1, DMA_CH1, &dma_single_data_parameter);
dma_channel_subperipheral_select(DMA1, DMA_CH1, DMA_SUBPERI2);
// enable DMA circulation mode
dma_circulation_enable(DMA1, DMA_CH1);
nvic_irq_enable(DMA1_Channel1_IRQn, 0, 4);
dma_flag_clear(DMA1, DMA_CH1, DMA_FLAG_FTF | DMA_FLAG_HTF);
dma_interrupt_enable(DMA1, DMA_CH1, DMA_CHXCTL_FTFIE);
// enable DMA channel
dma_channel_enable(DMA1, DMA_CH1);
}
#else
void dma_adc_sync_config(void)
{
// ADC_DMA_channel configuration
dma_single_data_parameter_struct dma_single_data_parameter;
// ADC DMA_channel configuration
dma_deinit(DMA1, DMA_CH0);
// initialize DMA single data mode
dma_single_data_parameter.periph_addr = (uint32_t)(&ADC_SYNCDATA);
dma_single_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_single_data_parameter.memory_addr = (uint32_t)(adc_convert_value);
dma_single_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_single_data_parameter.periph_memory_width = DMA_PERIPH_WIDTH_16BIT;
dma_single_data_parameter.direction = DMA_PERIPH_TO_MEMORY;
dma_single_data_parameter.circular_mode = DMA_CIRCULAR_MODE_ENABLE;
dma_single_data_parameter.number = (ADC0_CONVERT_COUNT + ADC1_CONVERT_COUNT + ADC2_CONVERT_COUNT);
dma_single_data_parameter.priority = DMA_PRIORITY_HIGH;
dma_single_data_mode_init(DMA1, DMA_CH0, &dma_single_data_parameter);
dma_channel_subperipheral_select(DMA1, DMA_CH0, DMA_SUBPERI0);
nvic_irq_enable(DMA1_Channel0_IRQn, 0, 4);
dma_flag_clear(DMA1, DMA_CH0, DMA_FLAG_FTF | DMA_FLAG_HTF);
dma_interrupt_enable(DMA1, DMA_CH0, DMA_CHXCTL_FTFIE);
// enable DMA channel
dma_channel_enable(DMA1, DMA_CH0);
}
#endif
void adc0_config(void)
{
// ADC contineous function disable
adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, DISABLE);
// ADC scan mode enable
adc_special_function_config(ADC0, ADC_SCAN_MODE, ENABLE);
// ADC data alignment config
adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);
adc_resolution_config(ADC0,ADC_RESOLUTION_12B);
// ADC channel length config
adc_channel_length_config(ADC0, ADC_ROUTINE_CHANNEL, ADC0_CONVERT_COUNT);
// ADC routine channel config
adc_routine_channel_config(ADC0, 0, ADC_CHANNEL_10, ADC_SAMPLETIME_56);
adc_routine_channel_config(ADC0, 1, ADC_CHANNEL_9, ADC_SAMPLETIME_56);
adc_routine_channel_config(ADC0, 2, ADC_CHANNEL_14, ADC_SAMPLETIME_56);
adc_routine_channel_config(ADC0, 3, ADC_CHANNEL_15, ADC_SAMPLETIME_56);
adc_routine_channel_config(ADC0, 4, ADC_CHANNEL_16, ADC_SAMPLETIME_56);
adc_routine_channel_config(ADC0, 5, ADC_CHANNEL_17, ADC_SAMPLETIME_56);
// ADC trigger config
adc_external_trigger_source_config(ADC0, ADC_ROUTINE_CHANNEL, ADC_EXTTRIG_ROUTINE_T1_CH3);
adc_external_trigger_config(ADC0, ADC_ROUTINE_CHANNEL, EXTERNAL_TRIGGER_RISING);
#ifndef EPS_ADC_ALL_ROUTINE_PARALLEL
adc_dma_request_after_last_enable(ADC0);
adc_dma_mode_enable(ADC0);
#endif
// enable ADC interface
adc_enable(ADC0);
// wait for ADC stability
delay_1ms(1);
// ADC calibration and reset calibration
adc_calibration_enable(ADC0);
}
void adc1_config(void)
{
// ADC contineous function disable
adc_special_function_config(ADC1, ADC_CONTINUOUS_MODE, DISABLE);
// ADC scan mode enable
adc_special_function_config(ADC1, ADC_SCAN_MODE, ENABLE);
// ADC data alignment config
adc_data_alignment_config(ADC1, ADC_DATAALIGN_RIGHT);
adc_resolution_config(ADC1,ADC_RESOLUTION_12B);
// ADC channel length config
adc_channel_length_config(ADC1, ADC_ROUTINE_CHANNEL, ADC1_CONVERT_COUNT);
adc_routine_channel_config(ADC1, 0, ADC_CHANNEL_11, ADC_SAMPLETIME_56);
adc_routine_channel_config(ADC1, 1, ADC_CHANNEL_4, ADC_SAMPLETIME_56);
adc_routine_channel_config(ADC1, 2, ADC_CHANNEL_5, ADC_SAMPLETIME_56);
adc_routine_channel_config(ADC1, 3, ADC_CHANNEL_6, ADC_SAMPLETIME_56);
adc_routine_channel_config(ADC1, 4, ADC_CHANNEL_7, ADC_SAMPLETIME_56);
adc_routine_channel_config(ADC1, 5, ADC_CHANNEL_8, ADC_SAMPLETIME_56);
#ifndef EPS_ADC_ALL_ROUTINE_PARALLEL
// ADC trigger config
adc_external_trigger_source_config(ADC1, ADC_ROUTINE_CHANNEL, ADC_EXTTRIG_ROUTINE_T1_CH3);
adc_external_trigger_config(ADC1, ADC_ROUTINE_CHANNEL, EXTERNAL_TRIGGER_RISING);
adc_dma_request_after_last_enable(ADC1);
adc_dma_mode_enable(ADC1);
#else
adc_external_trigger_config(ADC1, ADC_ROUTINE_CHANNEL, EXTERNAL_TRIGGER_DISABLE);
#endif
// enable ADC interface
adc_enable(ADC1);
// wait for ADC stability
delay_1ms(1);
// ADC calibration and reset calibration
adc_calibration_enable(ADC1);
}
void adc2_config(void)
{
// ADC contineous function disable
adc_special_function_config(ADC2, ADC_CONTINUOUS_MODE, DISABLE);
// ADC scan mode enable
adc_special_function_config(ADC2, ADC_SCAN_MODE, ENABLE);
// ADC data alignment config
adc_data_alignment_config(ADC2, ADC_DATAALIGN_RIGHT);
adc_resolution_config(ADC2,ADC_RESOLUTION_12B);
// ADC channel length config
adc_channel_length_config(ADC2, ADC_ROUTINE_CHANNEL, ADC2_CONVERT_COUNT);
adc_routine_channel_config(ADC2, 0, ADC_CHANNEL_12, ADC_SAMPLETIME_56);
adc_routine_channel_config(ADC2, 1, ADC_CHANNEL_13, ADC_SAMPLETIME_56);
adc_routine_channel_config(ADC2, 2, ADC_CHANNEL_0, ADC_SAMPLETIME_56);
adc_routine_channel_config(ADC2, 3, ADC_CHANNEL_1, ADC_SAMPLETIME_56);
adc_routine_channel_config(ADC2, 4, ADC_CHANNEL_2, ADC_SAMPLETIME_56);
adc_routine_channel_config(ADC2, 5, ADC_CHANNEL_3, ADC_SAMPLETIME_56);
#ifndef EPS_ADC_ALL_ROUTINE_PARALLEL
// ADC trigger config
adc_external_trigger_source_config(ADC2, ADC_ROUTINE_CHANNEL, ADC_EXTTRIG_ROUTINE_T1_CH3);
adc_external_trigger_config(ADC2, ADC_ROUTINE_CHANNEL, EXTERNAL_TRIGGER_RISING);
adc_dma_request_after_last_enable(ADC2);
adc_dma_mode_enable(ADC2);
#else
adc_external_trigger_config(ADC2, ADC_ROUTINE_CHANNEL, EXTERNAL_TRIGGER_DISABLE);
#endif
// enable ADC interface
adc_enable(ADC2);
// wait for ADC stability
delay_1ms(1);
// ADC calibration and reset calibration
adc_calibration_enable(ADC2);
}
void adc_config(void)
{
rcu_config();
gpio_config();
// ADC mode config
#ifndef EPS_ADC_ALL_ROUTINE_PARALLEL
adc_sync_mode_config(ADC_SYNC_MODE_INDEPENDENT); // ADC_ALL_ROUTINE_PARALLEL
adc0_dma_config();
adc1_dma_config();
adc2_dma_config();
#else
adc_sync_mode_config(ADC_ALL_ROUTINE_PARALLEL); // 所有ADC工作在常规并行模式
adc_sync_dma_config(ADC_SYNC_DMA_MODE0);
adc_sync_dma_request_after_last_enable();
dma_adc_sync_config();
#endif
// ADC Vbat channel enable
adc_channel_16_to_18(ADC_VBAT_CHANNEL_SWITCH, ENABLE);
// ADC temperature and Vref enable
adc_channel_16_to_18(ADC_TEMP_VREF_CHANNEL_SWITCH, ENABLE);
adc0_config();
adc1_config();
adc2_config();
}
|
|