One Shot Polling

This sample demonstrates one shot voltage sampling using an ADC in polling mode.

ADC sampling is performed by polling the ADC_INT_ONE_SHOT_DONE interrupt. When the interrupt flag is detected as 1, it indicates that the sampling is complete, and the raw data is read for voltage conversion calculation.

Users can change the sampling mode of the ADC channel, input voltage range, and other information in the sample through different macro configurations. For specific macro configurations, see Configurations.

Requirements

For requirements, please refer to the Requirements.

Wiring

Use a Dupont wire to connect P2_4 to external voltage input.

Configurations

  1. The following macro can be configured to modify the ADC sample mode.

    #define ADC_DEMO_POLLING                    0                   /*< ADC One Shot Polling Mode. */
    #define ADC_DEMO_AVERAGE                    1                   /*< ADC One Shot Polling Average Mode. */
    
    #define ADC_DEMO_MODE                       ADC_DEMO_POLLING    /*< Set this macro to select the ADC sample mode. */
    
  2. The following macro can be configured to modify the ADC input voltage range.

    #define ADC_DIVIDE_MODE                     1                   /*< Divide Mode, input voltage range is 0V~Vbat. */
    #define ADC_BYPASS_MODE                     0                   /*< Bypass Mode, input voltage range is 0V~0.9V. */
    
    #define ADC_MODE_DIVIDE_OR_BYPASS           ADC_DIVIDE_MODE     /*< Set this macro to select the ADC input voltage range. */
    
  3. The following macro can be configured to modify the pin definitions.

    #define ADC_SAMPLE_PIN                      P2_4
    #define ADC_SAMPLE_CHANNEL                  ADC_Channel_Index_4
    

Building and Downloading

For building and downloading, please refer to the Building and Downloading.

Experimental Verification

  1. When the EVB starts, observe the following log within the Debug Analyzer.

    Start adc polling test!
    
  2. ADC Configurations:

    1. If ADC_MODE_DIVIDE_OR_BYPASS is configured as ADC_DIVIDE_MODE, the following log will be printed:

      [ADC]ADC sample mode is divide mode !
      
    2. If ADC_MODE_DIVIDE_OR_BYPASS is configured as ADC_BYPASS_MODE, the following log will be printed:

      [ADC]ADC sample mode is bypass mode !
      
  3. After initialization is complete, the ADC begins sampling. Once a single ADC sampling is finished, the raw data collected and the converted voltage values will be printed in the Debug Analyzer tool.

    [ADC] adc_sample_demo: ADC one shot mode sample data_0 = xxx, voltage_0 = xxx mV
    ...
    [ADC] adc_sample_demo: ADC one shot mode sample data_15 = xxx, voltage_15 = xxx mV
    

Code Overview

This section introduces the code and process description for initialization and corresponding function implementation in the sample.

Source Code Directory

The directory for project file and source code are as follows:

  • Project directory: sdk\samples\peripheral\adc\oneshot_polling\proj

  • Source code directory: sdk\samples\peripheral\adc\oneshot_polling\src

Initialization

The initialization flow for peripherals can refer to Initialization Flow in General Introduction.

  1. Call Pad_Config() and Pinmux_Config() to configure the PAD and PINMUX of the corresponding pins. Please ensure that the PAD is configured in Shutdown mode to prevent leakage.

    void board_adc_init(void)
    {
        Pad_Config(ADC_SAMPLE_PIN, PAD_SW_MODE, PAD_NOT_PWRON, PAD_PULL_NONE, PAD_OUT_DISABLE, PAD_OUT_LOW);
    }
    
  2. Call RCC_PeriphClockCmd() to enable the ADC clock.

  3. Initialize the ADC peripheral:

    1. Define the ADC_InitTypeDef type ADC_InitStruct, and call ADC_StructInit() to pre-fill ADC_InitStruct with default values.

    2. Modify the ADC_InitStruct parameters as needed. When ADC_DEMO_MODE is configured with different values, the initialization configuration will be different. The ADC initialization parameter configuration is shown in the table below.

    3. Call ADC_Init() to initialize the ADC peripheral.

ADC Initialization Parameters

ADC Hardware Parameters

Setting in the ADC_InitStruct

ADC_DEMO_POLLING

ADC_DEMO_AVERAGE

Sample Time

ADC_InitTypeDef::ADC_SampleTime

255

255

Schedule Index

ADC_InitTypeDef::ADC_SchIndex

All index is set to EXT_SINGLE_ENDED(4)

Only index 0 is set to EXT_SINGLE_ENDED(4)

Bit Map

ADC_InitTypeDef::ADC_Bitmap

0xFFFF

0x01

Data Average Enable or Disable

ADC_InitTypeDef::ADC_DataAvgEn

DISABLE

ENABLE

Data Average number

ADC_InitTypeDef::ADC_DataAvgSel

-

ADC_DATA_AVERAGE_OF_4

Power Always On

ADC_InitTypeDef::ADC_PowerAlwaysOnEn

ENABLE

ENABLE

  1. If ADC_MODE_DIVIDE_OR_BYPASS is configured as ADC_BYPASS_MODE, the function ADC_BypassCmd() must be called to enable the Bypass mode for the corresponding pin.

  2. Call ADC_INTConfig() to configure the ADC one shot done interrupt ADC_INT_ONE_SHOT_DONE.

  3. Before the ADC begins sampling, it is necessary to call ADC_CalibrationInit() for ADC voltage calibration. If the return value is false, it indicates that the IC has not been calibrated and cannot accurately convert voltage values, but raw data can still be read.

Note

For the Average mode of the ADC, it is only applicable to channel 0; other channels cannot perform Average sampling. The Schedule Index configuration of the ADC must be configured starting from 0.

Functional Implementation

The flow for ADC one shot polling mode is shown in the figure:

Here should be ADC one shot polling flow

ADC one shot polling mode flow

  1. Call ADC_Cmd() to start ADC sampling.

  2. Continuously check the ADC one shot done interrupt ADC_INT_ONE_SHOT_DONE status and wait for the ADC single sampling to complete.

  3. Call the ADC_ReadRawData() function to read the sampled data from the corresponding channel. Call the ADC_GetVoltage() function, input the corresponding sampling mode, and convert the sampled data into a voltage value.

    while (ADC_GetINTStatus(ADC, ADC_INT_ONE_SHOT_DONE) == RESET) {}
    ADC_ClearINTPendingBit(ADC, ADC_INT_ONE_SHOT_DONE);
    ...
    sample_data[i] = ADC_ReadRawData(ADC, ADC_Schedule_Index_0 + i);
    sample_voltage[i] = ADC_GetVoltage(DIVIDE_SINGLE_MODE, (int32_t)sample_data[i], &error_status);
    

Note

If configure ADC_DEMO_MODE as ADC_DEMO_AVERAGE, the integer part of the sampled data needs to be extracted for voltage conversion, while the fractional part is not yet supported for voltage conversion.