ADC

简要说明

ADC(Analog-to-Digital Converter)模拟/数字转换驱动,可以将外部模拟量转换为数字量,并且信号比较和触发中断的功能。

接口描述

drv_adc_initialize

adc_handle_t drv_adc_initialize(int32_t idx, adc_event_cb_t cb_event);
  • 功能描述:

    • 通过设备号初始化对应的adc实例,返回adc实例的句柄。
  • 参数:

    • idx: 设备号。

    • cb_event: adc实例的事件回调函数。应用可根据回调函数做相应的睡前睡后行为。回调函数原型定义见adc_event_cb_t。

      回调函数类型adc_event_cb_t定义如下:

      typedef void (*adc_event_cb_t)(int32_t idx, adc_event_e event);
      

      其中idx为设备号,event 为传给回调函数的事件类型。

      ADC回调事件枚举类型见 adc_event_e 定义。

  • 返回值:

    • NULL: 初始化失败。
    • 其它: 实例句柄。

adc_event_e:

名称 定义 备注
ADC_EVENT_CONVERSION_COMPLETE 所有数据转换完毕
ADC_EVENT_DATA_LOST 数据丢失
ADC_EVENT_DATA_OVERWRITE 将新转换结果加载到数据寄存器前,尚未读取转换到后数据。
ADC_EVENT_DATA_COMPARE_VALID 数据比较匹配

drv_adc_uninitialize

int32_t drv_adc_uninitialize(adc_handle_t handle);
  • 功能描述:
    • 反初始化adc实例。
  • 参数:
    • handle: adc实例句柄。
  • 返回值:
    • 0: 成功。
    • 其它: 错误码。

drv_adc_power_control

int32_t drv_adc_power_control(adc_handle_t handle, csi_power_stat_e state)
  • 功能描述:
    • adc功耗控制。
  • 参数:
    • handle: adc实例句柄。
    • state: 设置功耗状态,见csi_power_stat_e定义。
  • 返回值:
    • 0: 成功。
    • 其它: 错误码。

csi_power_stat_e

名称 定义 备注
DRV_POWER_OFF 关闭电源
DRV_POWER_LOW 保持状态,检测并发出唤醒事件的信号
DRV_POWER_FULL 全功率模式
DRV_POWER_SUSPEND 省电模式

drv_adc_get_capabilities

adc_capabilities_t drv_adc_get_capabilities(int32_t idx);
  • 功能描述:
    • 获取adc 功能列表。
  • 参数:
    • idx: adc设备号。
  • 返回值:
    • adc功能表,见adc_capabilities_t定义。
名称 定义 备注
single 单次采集模式:1支持,0不支持
continuous 连续采集模式:1支持,0不支持
scan 扫描模式:1支持,0不支持
calibration 校准模式:1支持,0不支持
comparator 比较模式:1支持,0不支持

drv_adc_config

int32_t drv_adc_config(adc_handle_t handle, adc_conf_t *config);
  • 功能描述:
    • 配置adc。
  • 参数:
    • handle: adc实例句柄。
    • config: adc配置参数,见adc_conf_t定义。
  • 返回值:
    • 0: 成功。
    • 其它: 错误码。

adc_conf_t

名称 定义 备注
clk_prescaler 时钟源
mode adc运行模式,见adc_mode_e定义
trigger adc启动触发,0软件启动,1外部中断触发启动。
intrp_mode 1:ADC中断模式;0:ADC轮询模式
channel_array 指向adc通道数组,将要启用的通道写在该数组内
channel_nbr adc通道数组的大小
conv_cnt adc数据采集次数
sampling_time 采样时间值。单位:ADC时钟周期。
offset 预留

adc_mode_e

名称 定义 备注
ADC_SINGLE 单次采集模式
ADC_CONTINUOUS 连续采集模式
ADC_SCAN 连续多通道采集模式

drv_adc_comparator_config

int32_t drv_adc_comparator_config(adc_handle_t handle, adc_cmp_conf_t *config);
  • 功能描述:
    • adc 比较器配置。
  • 参数:
    • handle: adc实例句柄。
    • config: adc比较器参数,见adc_cmp_conf_t定义。
  • 返回值:
    • 0: 成功。
    • 其它: 错误码。

adc_cmp_conf_t

名称 定义 备注
cmp_data 与转换结果进行比较的值
cmp_channel 指定比较的通道
cmp_condition 0:转换结果 < cmp_data时匹配;1:转换结果>=cmp_data时匹配
cmp_match_cnt 设置匹配计数器的阈值;匹配次数达到cmp_match_cnt时,触发标志位转换

drv_adc_start

int32_t drv_adc_start(adc_handle_t handle);
  • 功能描述:
    • adc 启动转换。
  • 参数:
    • handle: adc实例句柄。
  • 返回值:
    • 0: 成功。
    • 其它: 错误码。

drv_adc_stop

int32_t drv_adc_stop(adc_handle_t handle);
  • 功能描述:
    • adc 停止转换。
  • 参数:
    • handle: adc实例句柄。
  • 返回值:
    • 0: 成功。
    • 其它: 错误码。

drv_adc_read

int32_t drv_adc_read(adc_handle_t handle, uint32_t *data, uint32_t num);
  • 功能描述:
    • adc 读取转换结果。
  • 参数:
    • handle: adc实例句柄。
    • data: 存贮转换结果。
    • num: 读取结果的个数。
  • 返回值:
    • 0: 成功。
    • 其它: 错误码。

drv_adc_get_status

adc_status_t drv_adc_get_status(adc_handle_t handle);
  • 功能描述:
    • 获取adc状态。
  • 参数:
    • handle: adc实例句柄。
  • 返回值:
    • adc状态,见adc_status_t定义。

adc_status_t

名称 定义 备注
busy 忙碌状态,adc转换中
data_lost adc buffer溢出,数据丢失
complete 转换完毕
compare_valid 数据比较匹配

使用例程

ADC可采用单次采样模式或者连续采样模式

本示例,分别使用了单次采样模式和连续采样模式,具体如下:

#include <soc.h>
#include <drv_adc.h>
#include <stdio.h>
#include <pin_name.h>
#include <pin.h>
#include <csi_config.h>

#define TEST_ADC_SINGLE_CHANNEL         EXAMPLE_ADC_CHANNEL_USR_DEF0
#define TEST_ADC_CONTINOUS_CHANNEL      EXAMPLE_ADC_CHANNEL_USR_DEF0

#define TEST_SINGLE_CONV_TIMES        1
#define TEST_CONTINOUS_CONV_TIMES     4

#define SINGE_DATA_NUM          1
#define CONTINOUS_DATA_NUM      (1*TEST_CONTINOUS_CONV_TIMES)
#define SCAN_DATA_NUM           128

#define ADC_TEST_SUCCESS  0
#define ADC_TEST_FAIL     -1
#define ADC_DELAY         1000

static volatile uint32_t scan_complete_flag;

extern void mdelay(uint32_t ms);

static int test_adc_single(void)
{
    adc_conf_t sconfig;
    adc_handle_t hd;
    uint32_t data[SINGE_DATA_NUM] = {0x314};
    uint32_t ch_array[1] = {TEST_ADC_SINGLE_CHANNEL};
    int ret = 0;

    printf("example single mode:\n");

    sconfig.mode = ADC_SINGLE;
    sconfig.trigger = 0;
    sconfig.intrp_mode = 0;
    sconfig.sampling_time = 2;
    sconfig.channel_array = ch_array;
    sconfig.channel_nbr = TEST_SINGLE_CONV_TIMES;
#ifdef EXAMPLE_ADC_CH_PIN_USR_DEF0_FUNC
    drv_pinmux_config(EXAMPLE_ADC_CH_PIN_USR_DEF0, EXAMPLE_ADC_CH_PIN_USR_DEF0_FUNC);
#endif
    hd = drv_adc_initialize(0, NULL);

    if (!hd) {
        printf("adc initial failed\n");
        return ADC_TEST_FAIL;
    }

    ret = drv_adc_config(hd, &sconfig);

    if (ret != 0 && ret != (CSI_DRV_ERRNO_ADC_BASE | DRV_ERROR_UNSUPPORTED)) {
        printf("adc config failed\n");
        return ADC_TEST_FAIL;
    }

    if (drv_adc_start(hd) != 0) {
        printf("adc start failed\n");
        return ADC_TEST_FAIL;
    }

    ret = drv_adc_read(hd, &data[SINGE_DATA_NUM - 1], SINGE_DATA_NUM);
    if (ret) {
        printf("read ad ret = %d\n", ret);
    }

    printf("read single data from adc: 0x%x\n\n", data[SINGE_DATA_NUM - 1]);

    if (drv_adc_stop(hd) != 0) {
        printf("adc stop failed\n");
        return ADC_TEST_FAIL;
    }

    if (drv_adc_uninitialize(hd) != 0) {
        printf("adc uninitial failed\n");
        return ADC_TEST_FAIL;
    }

    return ADC_TEST_SUCCESS;
}

static int test_adc_continous(void)
{
    adc_conf_t sconfig;
    adc_handle_t hd;
    uint32_t data[CONTINOUS_DATA_NUM];
    uint32_t ch_array[16] = {TEST_ADC_SINGLE_CHANNEL, TEST_ADC_SINGLE_CHANNEL,
                            TEST_ADC_SINGLE_CHANNEL, TEST_ADC_SINGLE_CHANNEL};
    int i = 0;
    int ret = 0;

    printf("example continous mode:\n");

    sconfig.mode = ADC_CONTINUOUS;
    sconfig.trigger = 0;
    sconfig.intrp_mode = 0;
    sconfig.sampling_time = 2;
    sconfig.channel_array = ch_array;
    sconfig.channel_nbr = TEST_CONTINOUS_CONV_TIMES;
#ifdef EXAMPLE_ADC_CH_PIN_USR_DEF0_FUNC
    drv_pinmux_config(EXAMPLE_ADC_CH_PIN_USR_DEF0, EXAMPLE_ADC_CH_PIN_USR_DEF0_FUNC);
#endif

    for (i = 0; i < CONTINOUS_DATA_NUM; i++) {
        data[i] = 0x31415;
    }

    hd = drv_adc_initialize(0, NULL);

    if (!hd) {
        printf("adc initial failed\n");
        return ADC_TEST_FAIL;
    }

    ret = drv_adc_config(hd, &sconfig);

    if (ret == (CSI_DRV_ERRNO_ADC_BASE | DRV_ERROR_UNSUPPORTED)) {
        printf("continous mode unsupported\n");
        return ADC_TEST_SUCCESS;
    }

    if (ret != 0) {
        printf("adc config failed\n");
        return ADC_TEST_FAIL;
    }


    if (drv_adc_start(hd) != 0) {
        printf("adc start failed\n");
        return ADC_TEST_FAIL;
    }

    ret = drv_adc_read(hd, &data[0], CONTINOUS_DATA_NUM);
    if (ret) {
        printf("read ad ret = %d\n", ret);
    }

    printf("read a data from adc:\n");

    for (i = 0; i < TEST_CONTINOUS_CONV_TIMES; i++) {
        printf("0x%x ", data[i]);
        if (i % 4 == 3) {
            printf("\n");
        }
    }
    printf("\n");

    if (drv_adc_stop(hd) != 0) {
        printf("adc stop failed\n");
        return ADC_TEST_FAIL;
    }

    if (drv_adc_uninitialize(hd) != 0) {
        printf("adc uninitial failed\n");
        return ADC_TEST_FAIL;
    }

    return ADC_TEST_SUCCESS;
}

void example_adc_cb(int32_t idx, adc_event_e event)
{
    if (event == ADC_EVENT_CONVERSION_HALF_COMPLETE) {
        printf("event: ADC_EVENT_CONVERSION_HALF_COMPLETE\n");
    } else if (event == ADC_EVENT_CONVERSION_COMPLETE){
        scan_complete_flag = 1;
        printf("event: ADC_EVENT_CONVERSION_COMPLETE\n");
    }
}

int test_adc_scan(void)
{
    adc_conf_t sconfig;
    adc_handle_t hd;
    uint32_t data[SCAN_DATA_NUM + 16];
    uint32_t ch_array[16] = {EXAMPLE_ADC_CHANNEL_DEF1, EXAMPLE_ADC_CHANNEL_DEF1, EXAMPLE_ADC_CHANNEL_DEF2, EXAMPLE_ADC_CHANNEL_DEF2};
    int i = 0;
    int ret = 0;

    printf("example scan mode:\n");

    sconfig.mode = ADC_SCAN;
    sconfig.trigger = 0;
    sconfig.intrp_mode = 0;
    sconfig.sampling_time = 2;
    sconfig.channel_array = &ch_array[0];
    sconfig.channel_nbr = 4;
#ifdef EXAMPLE_ADC_CH_PIN_USR_DEF1_FUNC
    drv_pinmux_config(EXAMPLE_ADC_CH_PIN_USR_DEF1, EXAMPLE_ADC_CH_PIN_USR_DEF1_FUNC);
    drv_pinmux_config(EXAMPLE_ADC_CH_PIN_USR_DEF2, EXAMPLE_ADC_CH_PIN_USR_DEF2_FUNC);
#endif

    for (i = 0; i < SCAN_DATA_NUM; i++) {
        data[i] = 0x31415;
    }

    hd = drv_adc_initialize(0, example_adc_cb);

    if (!hd) {
        printf("adc initial failed\n");
        return ADC_TEST_FAIL;
    }

    ret = drv_adc_config(hd, &sconfig);

    if (ret == (CSI_DRV_ERRNO_ADC_BASE | DRV_ERROR_UNSUPPORTED)) {
        printf("continous mode unsupported\n");
        return ADC_TEST_SUCCESS;
    }

    if (ret != 0) {
        printf("adc config failed\n");
        return ADC_TEST_FAIL;
    }

    if (drv_adc_start(hd) != 0) {
        printf("adc start failed\n");
        return ADC_TEST_FAIL;
    }

    ret = drv_adc_read(hd, &data[0], SCAN_DATA_NUM);
    if (ret) {
        printf("read ad ret = %d\n", ret);
    }

    printf("read data from adc:\n");

    while (!scan_complete_flag);
    for (i = 0; i < SCAN_DATA_NUM; i++) {
        printf("0x%x ", data[i]);
        if (i % 4 == 3) {
            printf("\n");
        }
    }
    printf("\n");

    scan_complete_flag = 0;

    for (i = 0; i < SCAN_DATA_NUM; i++) {
        data[i] = 0x31415;
    }

    drv_adc_read(hd, &data[0], SCAN_DATA_NUM);

    while (!scan_complete_flag);
    for (i = 0; i < SCAN_DATA_NUM; i++) {
        printf("0x%x ", data[i]);
        if (i % 4 == 3) {
            printf("\n");
        }
    }
    printf("\n");

    if (drv_adc_stop(hd) != 0) {
        printf("adc stop failed\n");
        return ADC_TEST_FAIL;
    }

    if (drv_adc_uninitialize(hd) != 0) {
        printf("adc uninitial failed\n");
        return ADC_TEST_FAIL;
    }

    return ADC_TEST_SUCCESS;
}

int example_adc(void)
{
    int ret;
    ret = test_adc_single();

    if (ret < 0) {
        printf("test adc single mode failed\n");
        return ADC_TEST_FAIL;
    }

    ret = test_adc_continous();

    if (ret < 0) {
        printf("test adc continous mode failed\n");
        return ADC_TEST_FAIL;
    }

    ret = test_adc_scan();

    if (ret < 0) {
        printf("test adc scan mode failed\n");
        return ADC_TEST_FAIL;
    }

    printf("test adc successfully\n");
    return ADC_TEST_SUCCESS;
}

int main(void)
{
    return example_adc();
}

results matching ""

    No results matching ""