.. highlight:: c .. _libmaple-adc: ```` ==================== :ref:`Analog to Digital Conversion ` (ADC) support. A common API for basic ADC functionality is available, but the characteristics of the ADC peripherals vary slightly across targets. To manage this, each target defines a small set of datatypes expressing its capabilities (namely :ref:`adc_extsel_event `, :ref:`adc_smp_rate `, and :ref:`adc_prescaler `). .. contents:: Contents :local: :depth: 2 Devices ------- The individual ADC peripherals have the following device struct. .. doxygenstruct:: adc_dev The available ADC peripherals vary by target. The complete list is ``ADC1``, ``ADC2``, and ``ADC3``. .. doxygenvariable:: ADC1 .. doxygenvariable:: ADC2 .. doxygenvariable:: ADC3 Functions --------- Activation and Deactivation ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``adc_enable_single_swstart()`` is simple, portable function, which enables an ADC and sets it up for its basic usage: performing single conversions using :ref:`adc_read() `. .. _adc-adc_enable_single_swstart: .. doxygenfunction:: adc_enable_single_swstart The precise software sequence used varies by target, so this is a good function to use if your program needs to support multiple MCUs. By default, Wirish calls ``adc_enable_single_swstart()`` on all available ADCs at ``init()`` time, so Wirish users don't have to call this function. There are several other lower-level routines used for activating and deactivating ADCs: .. _adc-adc_init: .. doxygenfunction:: adc_init .. _adc-adc_enable: .. doxygenfunction:: adc_enable .. _adc-adc_disable: .. doxygenfunction:: adc_disable .. _adc-adc_disable_all: .. doxygenfunction:: adc_disable_all ADC Conversion ~~~~~~~~~~~~~~ ``adc_read()`` is a simple function which starts conversion on a single ADC channel, blocks until it has completed, and returns the converted result. Don't use the ADC device for any other purpose while it's running. .. _adc-adc_read: .. doxygenfunction:: adc_read To use ``adc_read()``, the device must be configured appropriately. You can do this with :ref:`adc_enable_single_swstart() `. Note that for an ADC device to perform conversion on a GPIO input (which is the usual case; the notable exception being taking temperature reading), the pin must be configured for analog conversion. Do this with :ref:`adc_config_gpio() `. Other routines helpful for ADC conversion: .. _adc-adc_set_reg_seqlen: .. doxygenfunction:: adc_set_reg_seqlen .. _adc-adc_set_extsel: .. doxygenfunction:: adc_set_extsel .. _adc-adc_extsel_event: The last of these, :ref:`adc_set_extsel() `, takes a target-dependent ``adc_extsel_event`` argument. STM32F1 Targets +++++++++++++++ .. doxygenenum:: stm32f1::adc_extsel_event STM32F2 Targets +++++++++++++++ .. doxygenenum:: stm32f2::adc_extsel_event ADC Clock Prescaler ~~~~~~~~~~~~~~~~~~~ ``adc_set_prescaler()`` is available for setting the prescaler which determines the common ADC clock rate. (Wirish sets a sensible default for this, so Wirish users ordinarily don't need to call this function.) .. warning:: Increasing the ADC clock rate does speed conversion time, but the ADC peripherals have a maximum clock rate which must not be exceeded. Make sure to configure your system and ADC clocks to respect your device's maximum rate. .. _adc_adc_set_prescaler: .. doxygenfunction:: adc_set_prescaler .. _adc-adc_prescaler: ADC prescaler values are target-dependent. STM32F1 Targets +++++++++++++++ .. doxygenenum:: stm32f1::adc_prescaler STM32F2 Targets +++++++++++++++ .. doxygenenum:: stm32f2::adc_prescaler .. _adc-adc_set_sample_rate: ADC Sample Time ~~~~~~~~~~~~~~~ You can control the sampling time (in ADC cycles) for an entire ADC device using ``adc_set_sample_rate()`` [#fchansamp]_. This function **only controls the sample rate**; the total conversion time is equal to the sample time plus an additional number of ADC cycles. Consult the reference manual for your chip for more details. .. warning:: Decreasing ADC sample time speeds conversion, but it also decreases the maximum allowable impedance of the voltage source you are measuring. If your voltage source has a high impedance (e.g. you're measuring Vcc through a potentiometer), and your sample time is too low, you will get inaccurate results. Consult the datasheet for your target for more details. .. note:: Wirish sets a sensible default sample rate to allow for high-impedance inputs at ``init()`` time, but Wirish users who know what they're doing may want to call this function to speed up ADC conversion. .. doxygenfunction:: adc_set_sample_rate .. _adc-adc_smp_rate: The ``adc_smp_rate`` argument to :ref:`adc_set_sample_rate() ` is target-dependent. STM32F1 Targets +++++++++++++++ .. doxygenenum:: stm32f1::adc_smp_rate STM32F2 Targets +++++++++++++++ .. doxygenenum:: stm32f2::adc_smp_rate Miscellaneous ~~~~~~~~~~~~~ .. FIXME [0.0.13] why don't adc_config_gpio()'s docs show up? .. _adc-adc_foreach: .. doxygenfunction:: adc_foreach .. _adc-adc_config_gpio: .. doxygenfunction:: adc_config_gpio STM32F1 only ~~~~~~~~~~~~ The following routines are available only on STM32F1 targets. .. _adc-adc_set_exttrig: .. doxygenfunction:: adc_set_exttrig ``adc_calibrate()`` performs calibration necessary on STM32F1 before using an ADC. Note that on STM32F1 targets, :ref:`adc_enable_single_swstart() ` calls ``adc_calibrate()``, so there's no need to do it separately. .. _adc-adc_calibrate: .. doxygenfunction:: adc_calibrate Register Maps ------------- Individual ADC peripherals have the following register map. The base pointers are ``ADC1_BASE``, ``ADC2_BASE``, and ``ADC3_BASE``. .. _adc-adc_reg_map: .. doxygenstruct:: adc_reg_map On **STM32F2 targets**, there is an additional common set of registers shared by all ADC peripherals. Its base pointer is ``ADC_COMMON_BASE``. .. _adc-adc_common_reg_map: .. doxygenstruct:: stm32f2::adc_common_reg_map Register Bit Definitions ------------------------ .. TODO [0.0.13] TODO .. rubric:: Footnotes .. [#fchansamp] Per-channel sample time configuration is possible, but currently unsupported.