gd32_adc.c 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include "gd32_adc.h"
  2. #include "gpio.h"
  3. #include "clock.h"
  4. /* For 12-bits resolution, the total conversion time is
  5. *sampling time + 12.5 ADCCLK cycles
  6. *all channel is enabled oversample to reach 16bit accurate
  7. */
  8. void adc_init(void){
  9. rcu_periph_clock_enable(RCU_GPIOA);
  10. rcu_periph_clock_enable(RCU_GPIOB);
  11. gpio_mode_analog_input(GPIOA, GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);
  12. gpio_mode_analog_input(GPIOB, GPIO_PIN_1|GPIO_PIN_0);
  13. /* config ADC clock */
  14. rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6); //adc clock:28M
  15. rcu_periph_clock_enable(RCU_ADC);
  16. adc_deinit();
  17. /* ADC trigger config */
  18. adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);
  19. /* ADC data alignment config */
  20. adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
  21. /* ADC channel length config */
  22. adc_channel_length_config(ADC_REGULAR_CHANNEL, 1);
  23. adc_resolution_config(ADC_RESOLUTION_12B);
  24. //adc_special_function_config(ADC_SCAN_MODE,ENABLE);
  25. adc_discontinuous_mode_config(ADC_REGULAR_CHANNEL, 1);
  26. adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);
  27. }
  28. int adc_sample(int chan, int calibration){
  29. int value = -0xFFFFFF;
  30. int mask = 0xFFFF;
  31. //hardware oversample to 16bit
  32. adc_oversample_mode_config(ADC_OVERSAMPLING_ALL_CONVERT, ADC_OVERSAMPLING_SHIFT_4B, ADC_OVERSAMPLING_RATIO_MUL256);
  33. adc_oversample_mode_enable();
  34. /* use max convert time to make sure the adc work fine */
  35. adc_regular_channel_config(0, chan, ADC_SAMPLETIME_55POINT5);//239.5 + 12.5 = 242 cycle, 242/(28*1000000)
  36. adc_enable();
  37. delay_us(1000); //MUST delay, for adc work fine
  38. if (calibration) {
  39. /* ADC calibration and reset calibration */
  40. adc_calibration_enable();
  41. }
  42. adc_software_trigger_enable(ADC_REGULAR_CHANNEL);
  43. while(SET != adc_flag_get(ADC_FLAG_EOC));
  44. value = adc_regular_data_read();
  45. adc_flag_clear(ADC_FLAG_EOC);
  46. adc_disable();
  47. return value & mask;
  48. }
  49. int adc_sample_avg(int chan, int times){
  50. int value = 0;
  51. int count = 0;
  52. int min = 0xFFFFF;
  53. int max = -0xFFFFF;
  54. //hardware oversample to 16bit
  55. adc_oversample_mode_config(ADC_OVERSAMPLING_ALL_CONVERT, ADC_OVERSAMPLING_SHIFT_4B, ADC_OVERSAMPLING_RATIO_MUL256);
  56. adc_oversample_mode_enable();
  57. /* use max convert time to make sure the adc work fine */
  58. adc_regular_channel_config(0, chan, ADC_SAMPLETIME_55POINT5);//239.5 + 12.5 = 242 cycle, 242/(28*1000000)
  59. adc_enable();
  60. delay_us(1000); //MUST delay, for adc work fine
  61. /* ADC calibration and reset calibration */
  62. adc_calibration_enable();
  63. while(count < times){
  64. adc_software_trigger_enable(ADC_REGULAR_CHANNEL);
  65. while(SET != adc_flag_get(ADC_FLAG_EOC));
  66. int one = adc_regular_data_read();
  67. adc_flag_clear(ADC_FLAG_EOC);
  68. value += (one & 0xFFFF);
  69. count ++;
  70. if (one > max){
  71. max = one;
  72. }
  73. if (one < min) {
  74. min = one;
  75. }
  76. }
  77. adc_disable();
  78. return (value - min - max)/(times-2);
  79. }