One Shot Polling

该示例通过使用 ADC 以轮询模式进行单次采样电压。

以轮询 ADC_INT_ONE_SHOT_DONE 中断的方式进行 ADC 采样。当检测中断标志位置 1 代表采样完成,读取 raw data 并进行电压转换计算。

用户可以通过不同的宏配置改变示例中 ADC 通道的采样模式,输入电压范围等信息,具体宏配置详见 配置选项

环境需求

该示例的环境需求,可参考 环境需求

硬件连线

使用杜邦线短接 P2_4 和外部输入电压。

配置选项

  1. 可配置如下宏修改 ADC 采样模式。

    #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. 可配置如下宏修改 ADC 输入电压范围。

    #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. 可配置如下宏修改引脚定义。

    #define ADC_SAMPLE_PIN                      P2_4
    #define ADC_SAMPLE_CHANNEL                  ADC_Channel_Index_4
    

编译和下载

该示例的编译和下载流程,可参考 编译和下载

测试验证

  1. EVB 启动后,在 Debug Analyzer 工具内观察 log:

    Start adc polling test!
    
  2. ADC 初始化配置:

    1. ADC_MODE_DIVIDE_OR_BYPASS 配置为 ADC_DIVIDE_MODE,则会打印如下 log:

      [ADC]ADC sample mode is divide mode !
      
    2. ADC_MODE_DIVIDE_OR_BYPASS 配置为 ADC_BYPASS_MODE,则会打印如下 log:

      [ADC]ADC sample mode is bypass mode !
      
  3. 初始化完成后 ADC 开始采样。ADC 单次采样结束后,会在 Debug Analyzer 工具内打印采集得到的 raw data 和转换后的电压值。

    [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
    

代码介绍

该章节主要介绍示例中的初始化和相应功能实现的代码和流程说明。

源码路径

工程文件和源码路径如下:

  • 工程路径: sdk\samples\peripheral\adc\oneshot_polling\proj

  • 源码路径: sdk\samples\peripheral\adc\oneshot_polling\src

初始化

外设的初始化流程可参考 General Introduction 中的 初始化流程 部分。

  1. 调用 Pad_Config()Pinmux_Config(),配置对应引脚的 PAD 和 PINMUX。注意需要配置 PAD 为 Shutdown 模式,防止漏电。

    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. 调用 RCC_PeriphClockCmd() ,开启 ADC 时钟。

  3. 对 ADC 外设进行初始化:

    1. 定义 ADC_InitTypeDef 类型 ADC_InitStruct ,调用 ADC_StructInit()ADC_InitStruct 预填默认值。

    2. 根据需求修改 ADC_InitStruct 参数,当 ADC_DEMO_MODE 配置为不同值时,初始化配置会有所不同。ADC 的初始化参数配置如下表。

    3. 调用 ADC_Init(),初始化 ADC 外设。

ADC 初始化参数

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. ADC_MODE_DIVIDE_OR_BYPASS 配置为 ADC_BYPASS_MODE,需要调用函数 ADC_BypassCmd() 开启对应引脚的 Bypass 模式。

  2. 调用 ADC_INTConfig() ,配置 ADC 单次采样完成中断 ADC_INT_ONE_SHOT_DONE

  3. 在 ADC 开始采样前,必须调用 ADC_CalibrationInit() 进行 ADC 电压校准。若返回值为 false,则代表该 IC 未经校验,无法正确转换电压值,但仍可读到 raw data。

备注

对于 ADC 的 Average 模式,仅适用于通道 0,其他通道无法进行 Average 采样。ADC 的 Schedule Index 配置,必须从 0 开始配置。

功能实现

ADC 轮询模式单次采样的流程如图所示:

这里应该是 ADC one shot polling flow

ADC 轮询模式单次采样流程图

  1. 调用 ADC_Cmd() ,开始 ADC 采样。

  2. 循环判断 ADC 单次采样完成中断 ADC_INT_ONE_SHOT_DONE 状态,等待 ADC 单次采样完成。

  3. 调用 ADC_ReadRawData() 函数,读取对应通道的采样数据。调用 ADC_GetVoltage() 函数,输入对应采样模式,将采样数据转换为电压值。

    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);
    

备注

若配置 ADC_DEMO_MODEADC_DEMO_AVERAGE 时,需要将采样数据的整数部分取出进行电压转换,小数部分暂不支持电压转换。