немного подрюкал ацп в ch32v303. временно оно не вызывает опасений
(но это не точно) схема такая - отладочная платка
nano ch32v203c8t6 v1.1 в которую перепаян ch32v303cbt6
https://aliexpress.ru/item/1005006993112944.html
выводы pa1 и pa6 используются как входы adc1 и adc2 соответственно.
на входы закорочены между собой и на них подан общий сигнал <- ( 10k || 1nF <- 3.3v LDO <- 5V USB) || ( 10k || 1nF <- земля ), то есть сопротивление источника напряжения ~3.3/2=1.65V примерно 5к || 2nF.

для исследования этих вопросов написал скриптики для gdb что автоматом выгребалось из буфферов накопленные серии отсчетов и в gnuplot строились гистогоамма и распределение отсчетов на на мерном интервале. для статистики использовал 2^12 отсчетов в серии.
код в котором можно посмотреть как я настраивал каналы ацп
#include "appdefs.h"
struct iq_t
{
static constexpr size_t samples_bit = 12 ;
static constexpr size_t samples = 1 << samples_bit ;
static constexpr size_t samples_mask = (1 << samples_bit) - 1;
int16_t cos[samples] ;
int16_t sin[samples] ;
volatile size_t ptr = 0 ;
__ai__ void adc_eojc_handler()
{
adc1.end_of_injected_conversion_flag_clear();
cos[ptr] = adc1.injected_channel1_data ;
sin[ptr] = adc2.injected_channel1_data ;
ptr++ ;
ptr = ptr & samples_mask ;
}
__ai__ void init()
{
// pa1 pa3
rcc.apb2_peripheral_clock.modify(
rcc_t::apb2_peripheral_clock_t::afio_t::enable,
rcc_t::apb2_peripheral_clock_t::adc1_t::enable,
rcc_t::apb2_peripheral_clock_t::adc2_t::enable,
rcc_t::apb2_peripheral_clock_t::gpioa_t::enable
) ;
gpioa.config0.modify(
gpio_t::config0_t::pin1_mode_t::input, gpio_t::config0_t::pin1_input_type_t::analog,
gpio_t::config0_t::pin6_mode_t::input, gpio_t::config0_t::pin6_input_type_t::analog
) ;
adc1.clock_prescaler_div8() ; // устанавливается для обоих модулей в rcc
adc1.clock_reset();
adc2.clock_reset();
adc1.dual_mode_injected_simultaneous(); // режим сдвоенного ацп по инжектированым каналам
adc1.injected_channels_conversion_trigger_source_tim4_trgo();
adc1.injected_channels_conversion_trigger_enable();
/* adc1.injected_channel_sequence_count(1) ;
adc1.injected_channel_sequence_item1(1) ;
adc1.injected_channel_sequence_item2(1) ;
adc1.injected_channel_sequence_item3(1) ;
adc1.injected_channel_sequence_item4(1) ;*/
adc1.injected_channel_sequence.val(0x8421);
adc1.sample_time_channel1_cycles7dot5() ;
adc1.enable();
adc1.calibration_reset();
adc1.calibration_reset_state_wait();
adc1.calibration_start();
adc1.calibration_start_state_wait();
adc2.injected_channels_conversion_trigger_source_software();
adc2.injected_channels_conversion_trigger_enable();
/*adc2.injected_channel_sequence_count(1) ;
adc2.injected_channel_sequence_item1(6) ;
adc2.injected_channel_sequence_item2(6) ;
adc2.injected_channel_sequence_item3(6) ;
adc2.injected_channel_sequence_item4(6) ;*/
adc2.injected_channel_sequence.val(0x318c6);
adc2.sample_time_channel6_cycles7dot5() ;
adc2.enable();
adc2.calibration_reset();
adc2.calibration_reset_state_wait();
adc2.calibration_start();
adc2.calibration_start_state_wait();
// разрешение прерывания по окончанию преобразования
adc1.end_of_injected_conversion_interrupt_enable();
adc1.pfic_enable();
adc1.pfic_priority(0x80);
// таймер сэмплирования ацп
tim4.clock_enable();
tim4.clock_reset();
tim4.cc_control1.write( tim4_t::cc_control1_t::cc1_mode_t::output_compare, tim4_t::cc_control1_t::oc1_mode_t::pwm2);
tim4.cc_enable.write(tim4_t::cc_enable_t::cc1_state_t::enable, tim4_t::cc_enable_t::oc1_polarity_t::high);
tim4.freq(1000000);
tim4.cc1=tim4.auto_reload/2 ;
tim4.master_trgo_oc1ref(); // выход триггера на запуск ацп
tim4.enable();
}
} iq;
int main(void)
{
iq.init();
cout < "adc clock " < (size_t)adc1.clock_internal_freq() <= endl
< "adc sample clock " < (size_t)tim4.freq() <= endl
< "adc sample time " < adc1.sample_time_ns( adc1.sample_time_channel1()) < " ns" <= endl ;
cout <= "entre to main loop... \n" ;
nop_loop();
}
namespace ch32v3xx
{
cout_io_tx_dma_irq_hadler() { cout.async_write_event_handler (); }
sys_tick_irq_handler()
{
sys_tick.compare_flag_clear();
sys_tick_compare_update();
led_blue_toggle();
cout < sys_tick.compare <= endl ;
}
irq_handler_hpe(adc1_2) { iq.adc_eojc_handler(); }
exception_handler_hpe(nmi) { ebreak(); }
exception_handler_hpe(hard_fault) { ebreak(); }
}
для 1МГц и времени заряда конденсаторов SH 415 нс
серия отсчетов и гистограмма с распределением


тоже самое для примерно 10кГц семплирования


одним словом можно предварительно поверить что имеет честных 10 бит конвертер.
картинки прелестные но не красивые. если повесить в воздухе входы ацп, то он измеряет что то
внутри происходящее :) мотает его туда сюда... :)


для сравнения - pa1 - на делителе. pa6 в воздухе

