#include "gd32_adc.h" #include "gpio.h" #include "clock.h" /* For 12-bits resolution, the total conversion time is *sampling time + 12.5 ADCCLK cycles *all channel is enabled oversample to reach 16bit accurate */ void adc_init(void){ rcu_periph_clock_enable(RCU_GPIOA); rcu_periph_clock_enable(RCU_GPIOB); gpio_mode_analog_input(GPIOA, GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7); gpio_mode_analog_input(GPIOB, GPIO_PIN_1|GPIO_PIN_0); /* config ADC clock */ rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6); //adc clock:28M rcu_periph_clock_enable(RCU_ADC); adc_deinit(); /* ADC trigger 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 channel length config */ adc_channel_length_config(ADC_REGULAR_CHANNEL, 1); adc_resolution_config(ADC_RESOLUTION_12B); //adc_special_function_config(ADC_SCAN_MODE,ENABLE); adc_discontinuous_mode_config(ADC_REGULAR_CHANNEL, 1); adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE); } int adc_sample(int chan, int calibration){ int value = -0xFFFFFF; int mask = 0xFFFF; //hardware oversample to 16bit adc_oversample_mode_config(ADC_OVERSAMPLING_ALL_CONVERT, ADC_OVERSAMPLING_SHIFT_4B, ADC_OVERSAMPLING_RATIO_MUL256); adc_oversample_mode_enable(); /* use max convert time to make sure the adc work fine */ adc_regular_channel_config(0, chan, ADC_SAMPLETIME_55POINT5);//239.5 + 12.5 = 242 cycle, 242/(28*1000000) adc_enable(); delay_us(1000); //MUST delay, for adc work fine if (calibration) { /* ADC calibration and reset calibration */ adc_calibration_enable(); } adc_software_trigger_enable(ADC_REGULAR_CHANNEL); while(SET != adc_flag_get(ADC_FLAG_EOC)); value = adc_regular_data_read(); adc_flag_clear(ADC_FLAG_EOC); adc_disable(); return value & mask; } int adc_sample_avg(int chan, int times){ int value = 0; int count = 0; int min = 0xFFFFF; int max = -0xFFFFF; //hardware oversample to 16bit adc_oversample_mode_config(ADC_OVERSAMPLING_ALL_CONVERT, ADC_OVERSAMPLING_SHIFT_4B, ADC_OVERSAMPLING_RATIO_MUL256); adc_oversample_mode_enable(); /* use max convert time to make sure the adc work fine */ adc_regular_channel_config(0, chan, ADC_SAMPLETIME_55POINT5);//239.5 + 12.5 = 242 cycle, 242/(28*1000000) adc_enable(); delay_us(1000); //MUST delay, for adc work fine /* ADC calibration and reset calibration */ adc_calibration_enable(); while(count < times){ adc_software_trigger_enable(ADC_REGULAR_CHANNEL); while(SET != adc_flag_get(ADC_FLAG_EOC)); int one = adc_regular_data_read(); adc_flag_clear(ADC_FLAG_EOC); value += (one & 0xFFFF); count ++; if (one > max){ max = one; } if (one < min) { min = one; } } adc_disable(); return (value - min - max)/(times-2); }