| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- #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);
- }
|