One Shot Polling

该示例通过使用 ADC One Shot Polling模式进行电压检测。示例中可用宏去配置ADC的采样模式和采样电压范围。

采样模式除普通ADC采样外,包含了Hardware Average采样和差分模式采样。

采样电压范围包含了Divide Mode和Bypass Mode。

以Polling ADC_INT_ONE_SHOT_DONE 中断的方式进行ADC采样。当检测到采样完成时,读取raw data并进行电压转换计算。

环境需求

该示例支持以下开发套件:

开发套件

Hardware Platforms

Board Name

RTL87x2G HDK

RTL87x2G EVB

更多信息请参考快速入门

硬件连线

  • 在配置为 ADC_DEMO_POLLING 模式和 ADC_DEMO_AVERAGE 模式时:

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

  • 在配置为 ADC_DEMO_DIFFERENTIAL 采样模式时:

    使用杜邦线短接P2_6与外部电压输入P端,P2_7与外部电压输入N端。

配置选项

该示例可配置的宏如下:

  1. ADC_DEMO_MODE :配置该宏可选择ADC的采样方式,可选择的值如下:

    • ADC_DEMO_POLLING :ADC普通Polling模式采样。在该模式下,16个通道均采样P2_4的电压。

    • ADC_DEMO_AVERAGE :ADC Hardware Average采样。在该模式下,通道0采样P2_4的电压。

    • ADC_DEMO_DIFFERENTIAL :ADC 差分模式采样。在该模式下,通道0和通道1采样P2_6和P2_7的差分电压。

  2. ADC_MODE_DIVIDE_OR_BYPASS :配置该宏可选择ADC的电压采样范围,可选择的值如下:

    • ADC_DIVIDE_MODE :在Divide Mode下,ADC的采样电压值范围为0~3.3V。

    • ADC_BYPASS_MODE :在Bypass Mode下,ADC的采样电压值范围为0~0.9V。

编译和下载

该示例的工程路径如下:

Project file: samples\peripheral\adc\oneshot_polling\proj\rtl87x2g\mdk

Project file: samples\peripheral\adc\oneshot_polling\proj\rtl87x2g\gcc

请按照以下步骤操作构建并运行该示例:

  1. 打开工程文件。

  2. 按照 快速入门编译APP Image 给出的步骤构建目标文件。

  3. 编译成功后,在路径 mdk\bingcc\bin 下会生成 app bin app_MP_xxx.bin 文件。

  4. 按照 快速入门MPTool 给出的步骤将app bin烧录至EVB内。

  5. 按下复位按键,开始运行。

测试验证

  1. IC启动后,在DebugAnalyzer工具内观察LOG:

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

    1. 若配置为 ADC_DIVIDE_MODE ,则会打印如下LOG:

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

      [ADC]ADC sample mode is bypass mode !
      
  3. ADC采样结束后,会在DebugAnalyzer工具内打印采集得到的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
    

代码介绍

该章节分为以下几个部分:

  1. 源码路径

  2. 初始化函数将在 初始化 章节介绍。

  3. 初始化后的功能实现将在 功能实现 章节介绍。

源码路径

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

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

该工程的工程文件代码结构如下:

└── Project: oneshot_polling
    └── secure_only_app
        └── Device                   includes startup code
            ├── startup_rtl.c
            └── system_rtl.c
        ├── CMSIS                    includes CMSIS header files
        ├── CMSE Library             Non-secure callable lib
        ├── lib                      includes all binary symbol files that user application is built on
            └── rtl87x2g_io.lib
        ├── peripheral               includes all peripheral drivers and module code used by the application
            ├── rtl_rcc.c
            ├── rtl_pinmux.c
            └── rtl_adc.c
        └── APP                      includes the ble_peripheral user application implementation
            ├── main_ns.c
            └── io_adc.c

初始化

初始化流程包括:board_adc_initdriver_adc_init


board_adc_init 中包含了PAD设置。

  1. 配置PAD:设置引脚、SW模式、PowerOn、无内部上拉、输出失能、输出高。

    1. 若设置 ADC_DEMO_MODEADC_DEMO_POLLINGADC_DEMO_AVERAGE 时,设置引脚为P2_4。

    2. 若设置 ADC_DEMO_MODEADC_DEMO_DIFFERENTIAL 时,设置引脚为P2_6和P2_7。


driver_adc_init 中包含了对ADC外设的初始化。

  1. 配置ADC的采样通道。

    1. 若设置 ADC_DEMO_MODEADC_DEMO_POLLING 时,将16个通道均设置为P2_4单端模式,设置Bitmap为0xFFFF。

    2. 若设置 ADC_DEMO_MODEADC_DEMO_AVERAGE 时,将通道0设置为P2_4单端模式,设置Bitmap为0x01,设置采样平均值为4。

    3. 若设置 ADC_DEMO_MODEADC_DEMO_DIFFERENTIAL 时,将通道0和1分别设置为P2_6和P2_7差分模式,设置Bitmap为0x03。

  2. 若开启Bypass Mode,执行函数 ADC_BypassCmd() 开启对应引脚的Bypass模式。

  3. 开启ADC One Shot Done中断。

#if (ADC_DEMO_MODE == ADC_DEMO_POLLING)
    for (uint8_t i = 0; i < 16; i++)
    {
        ADC_InitStruct.ADC_SchIndex[i]  = EXT_SINGLE_ENDED(ADC_SAMPLE_CHANNEL);
    }
    ADC_InitStruct.ADC_Bitmap           = 0xFFFF;
#elif (ADC_DEMO_MODE == ADC_DEMO_AVERAGE)
    ADC_InitStruct.ADC_SchIndex[0]      = EXT_SINGLE_ENDED(ADC_SAMPLE_CHANNEL);
    ADC_InitStruct.ADC_DataAvgEn        = ENABLE;
    ADC_InitStruct.ADC_DataAvgSel       = ADC_DATA_AVERAGE_OF_4;
    ADC_InitStruct.ADC_Bitmap           = 0x01;
#elif (ADC_DEMO_MODE == ADC_DEMO_DIFFERENTIAL)
    ADC_InitStruct.ADC_SchIndex[0]      = EXT_DIFFERENTIAL(ADC_SAMPLE_CHANNEL_0);
    ADC_InitStruct.ADC_SchIndex[1]      = EXT_DIFFERENTIAL(ADC_SAMPLE_CHANNEL_1);
    ADC_InitStruct.ADC_Bitmap           = 0x03;
#endif

备注

对于ADC的Average模式,仅适用于通道0,其他通道无法进行Average采样。

功能实现

  1. 执行 ADC_Cmd() ,开始ADC采样。

  2. adc_sample_demo 中,循环判断ADC单次转换完成中断状态,RESET时继续判断,SET时ADC单次转换完成。

  3. 执行 ADC_ReadRawData() 函数,读取采样数据。

  4. 执行 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 时,需要将采样数据的整数部分取出进行电压转换,小数部分暂不支持电压转换。

常见问题

  1. 若拿到的IC未经过FT校验,ADC则无法转换为正确的电压值。在LOG工具内会打印如下信息。

    [ADC]ADC_CalibrationInit fail!
    
  2. 若ADC采样值不正确,则会打印错误状态信息。

    [ADC]adc_sample_demo: ADC parameter or efuse data error! i = xxx, error_status = xxx