Skip to content

ADC设备

ADC简介

ADC(Analog-to-Digital Converter)模数转换器,是指将连续变化的模拟信号转换为离散的数字信号的器件。真实世界的模拟信号,例如温度、压力、声音或者图像等,需要转换成更容易储存、处理和发射的数字形式,模数转换器可以实现这个功能。ADC位宽为12bit,最高采样率可以到360KSPS(360K、180K,90K,45K四个档位可选)。

IOTE板子上与ADC相关的有:ADC_A、ADC_B、ADC_C三个外部ADC输入脚,电池电压以及芯片温度。

驱动支持

访问ADC设备前,需要保证相关驱动配置已选中。

Windows环境:利用RT-Thread官方env工具直接在代码根目录下执行menuconfig进入配置。

Linux环境:在代码根目录下执行scons --menuconfig进入配置。

ADC驱动所在路径如下:

RT-Thread Components -> Device Drivers -> Using ADC device drivers

访问ADC设备接口

访问ADC设备,库中提供了以下接口:

函数 描述
rt_device_find() 根据ADC名称查找设备获取设备句柄
rt_adc_enable() 使能ADC设备
rt_adc_read() 读取ADC设备数据
rt_adc_disable() 关闭ADC设备

查找ADC设备

查找ADC设备,函数原型如下所示:

rt_device_t rt_device_find(const char* name);
  • 参数

    [IN]name:ADC设备名称,目前注册到的系统中的ADC设备名称为"adc"。

  • 返回值

    RT_NULL:失败,设备不存在。

    非RT_NULL:成功,该返回值是操作ADC设备的句柄,在后续的接口中作为函数入参。

使能ADC设备

使能指定ADC设备,函数原型如下所示:

rt_err_t rt_adc_enable(rt_adc_device_t dev, rt_uint32_t channel);
  • 参数

    [IN]dev:ADC设备句柄,查找设备函数的返回值。

    [IN]channel:ADC通道,支持的通道对应枚举ADC_CHANNEL_CONFIG中定义的值,详细如下:

    // 所在头文件相对路径 "libraries/UC8288_HAL_Driver/inc/uc_adda.h"
    typedef enum
    {
        ADC_CONFIG_CHANNEL_A = 1,       // 对应板子ADC_A引脚
        ADC_CONFIG_CHANNEL_B,           // 对应板子ADC_B引脚
        ADC_CONFIG_CHANNEL_C,           // 对应板子ADC_C引脚
        ADC_CONFIG_CHANNEL_BAT1,        // 电池电压通道
        ADC_CONFIG_CHANNEL_TEMP_A1,     // 不支持
        ADC_CONFIG_CHANNEL_TEMP_A2,     // 不支持
        ADC_CONFIG_CHANNEL_TEMP_B,      // 不支持
        ADC_CONFIG_CHANNEL_CHIP_TEMP,   // 芯片温度通道
    } ADC_CHANNEL_CONFIG;
    
  • 返回值

    0:正常。

    其他:错误,RT-Thread定义的错误类型。

读取ADC数据

读取ADC采样的数据,函数原型如下所示:

rt_uint32_t rt_adc_read(rt_adc_device_t dev, rt_uint32_t channel);
  • 参数

    [IN]dev:ADC设备句柄,查找设备函数的返回值。

    [IN]channel:ADC通道,支持的通道对应枚举ADC_CHANNEL_CONFIG中定义的值

    注:调用时,需要与前述使能ADC设备的channel保持一致。

  • 返回值

    返回ADC数值,0或非零。

关闭ADC设备

关闭ADC设备,函数原型如下所示:

rt_err_t rt_adc_disable(rt_adc_device_t dev, rt_uint32_t channel);
  • 参数

    [IN]dev:ADC设备句柄,查找设备函数的返回值。

    [IN]channel:ADC通道,支持的通道对应枚举ADC_CHANNEL_CONFIG中定义的值

    注:调用时,需要与前述使能ADC设备的channel保持一致。

  • 返回值

    0:正常。

    其他:错误,RT-Thread定义的错误类型。

ADC使用示例

使用示例需要配置menuconfig,使能例程与外设,步骤如下:

  1. 使能例程
Application Example Config -> Enable ADC Example
  1. 使能外设驱动
Hardware Drivers Config -> On-chip Peripheral Drivers -> Enable ADC

以下提供ADC测试实例,测试步骤如下:

  1. 根据ADC设备名称,获取ADC设备句柄。
  2. 使能ADC设备,指定采样通道。
  3. 读取ADC数据。
  4. 关闭ADC设备。
#include <rtthread.h>

#ifdef APP_EXAMPLE_ADC

#ifndef RT_USING_ADC
#error "Please enable rt-thread adc device driver"
#endif

#ifndef BSP_USING_ADC
#error "Please enable on-chip peripheral adc config"
#endif

#include <rtdevice.h>
#include <drv_adc.h>
#include "uc_adc_app.h"

#define THREAD_STACK_SIZE 512
#define THREAD_PRIORITY 5
#define THREAD_TIMESLICE 5

#define ADC_DEVICE_NAME "adc"
#define ADC_DEV_CHANNEL ADC_CONFIG_CHANNEL_A

static rt_adc_device_t adc_dev = NULL;

static int adc_app_read_value(rt_adc_device_t adc_dev, rt_uint32_t *value)
{
    rt_adc_enable(adc_dev, ADC_DEV_CHANNEL);
    *value = rt_adc_read(adc_dev, ADC_DEV_CHANNEL);
    rt_adc_disable(adc_dev, ADC_DEV_CHANNEL);

    return RT_EOK;
}

static void adc_thread_entry(void *parameter)
{
    rt_uint32_t value = 0, value_old = 0;

    while (1)
    {
        adc_app_read_value(adc_dev, &value);
        if (value_old != value)
        {
            rt_kprintf("adc value = %d\n", value);
            value_old = value;
        }
        rt_thread_mdelay(100);
    }
}

int adc_app_sample(void)
{
    rt_thread_t thread = RT_NULL;

    rt_kprintf("adc_app_sample\n");

    adc_dev = (rt_adc_device_t)rt_device_find(ADC_DEVICE_NAME);
    if (adc_dev == RT_NULL)
    {
        rt_kprintf("find %s failed!\n", ADC_DEVICE_NAME);
        return -RT_EEMPTY;
    }

    /* 创建 serial 线程 */
    thread = rt_thread_create("adc_app",
                              adc_thread_entry,
                              RT_NULL,
                              THREAD_STACK_SIZE,
                              THREAD_PRIORITY,
                              THREAD_TIMESLICE);
    /* 创建成功则启动线程 */
    if (RT_NULL == thread)
    {
        return -RT_ERROR;
    }
    else
    {
        rt_thread_startup(thread);
    }

    return RT_EOK;
}

#endif
Back to top