driver-platform-adc-des.md 6.1 KB
Newer Older
1 2 3 4
# ADC<a name="1"></a>

## 概述<a name="section1"></a>

5 6
### 功能简介<a name="section2"></a>

7
ADC(Analog to Digital Converter),即模拟-数字转换器,是一种将模拟信号转换成对应数字信号的设备。
8

9 10 11
ADC接口定义了完成ADC传输的通用方法集合,包括:
-  ADC设备管理:打开或关闭ADC设备。
-  ADC读取转换结果:读取AD转换结果。
12

13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
### 基本概念<a name="section3"></a>

ADC主要用于将模拟量转换成数字量,从而便于存储与计算等。

ADC的主要技术参数有:

- 分辨率
  分辨率指的是ADC模块能够转换的二进制位数,位数越多分辨率越高。

- 转换误差
  转换误差通常是以输出误差的最大值形式给出。它表示A/D转换器实际输出的数字量和理论上的输出数字量之间的差别。常用最低有效位的倍数表示。

- 转换时间
  转换时间是指A/D转换器从转换控制信号到来开始,到输出端得到稳定的数字信号所经过的时间。

### 运作机制<a name="section4"></a>

在HDF框架中,同类型设备对象较多时(可能同时存在十几个同类型配置器),如果采用独立服务模式则需要配置更多的设备节点,且相关服务会占据更多的内存资源。相反,采用统一服务模式可以使用一个设备服务作为管理器,统一处理所有同类型对象的外部访问(这会在配置文件中有所体现),实现便捷管理和节约资源的目的。ADC模块接口适配模式采用统一服务模式。

ADC模块各分层的作用为:接口层提供打开设备,写入数据,关闭设备的接口。核心层主要提供绑定设备、初始化设备以及释放设备的能力。适配层实现其他具体的功能。

除电源线和地线之外,ADC只需要1根线与被测量的设备进行连接,其物理连线如[图1](#fig1)所示:

**图 1**  ADC物理连线示意图<a name="fig1"></a>  
![](figures/ADC物理连线示意图.png "ADC物理连线示意图")

### 约束与限制<a name="section5"></a>

ADC模块当前仅支持轻量和小型系统内核(LiteOS) 。

## 使用指导<a name="section6"></a>
44

45 46 47 48 49 50 51
### 场景介绍<a name="section7"></a>

ADC设备通常用于将模拟电压转换为数字量,如与咪头搭配进行声音采集、与NTC电阻搭配进行温度测量,或者将其他模拟传感器的输出量转换为数字量的场景。

### 接口说明<a name="section8"></a>

ADC模块提供的主要接口如[表1](#table1)所示,更多关于接口的介绍请参考对应的API接口文档。
52 53 54 55 56

**表 1**  ADC驱动API接口功能介绍

<a name="table1"></a>

57 58 59 60 61 62 63
| 接口名   | 描述             |
| -------- | ---------------- |
| AdcOpen  | 打开ADC设备      |
| AdcClose | 关闭ADC设备      |
| AdcRead  | 读取AD转换结果值 |

### 开发步骤<a name="section9"></a>
64 65 66 67 68 69

使用ADC设备的一般流程如[图2](#fig2)所示。

 **图 2**  ADC使用流程图<a name="fig2"></a>  
![](figures/ADC使用流程图.png "ADC使用流程图") 

70 71

#### 打开ADC设备
72 73 74 75 76 77 78 79 80 81 82

在进行AD转换之前,首先要调用AdcOpen打开ADC设备。

```c
DevHandle AdcOpen(int16_t number);
```

**表 2**  AdcOpen参数和返回值描述

<a name="table2"></a>

83 84 85 86 87 88
| 参数       | 参数描述          |
| ---------- | ----------------- |
| number     | ADC设备号         |
| **返回值** | **返回值描述**    |
| NULL       | 打开ADC设备失败   |
| 设备句柄   | 打开的ADC设备句柄 |
89 90 91 92 93 94 95 96 97

假设系统中存在2个ADC设备,编号从0到1,那么我们现在打开1号设备。

```c
DevHandle adcHandle = NULL;  /* ADC设备句柄 /

/* 打开ADC设备 */
adcHandle = AdcOpen(1);
if (adcHandle == NULL) {
98
    HDF_LOGE("AdcOpen: fail\n");
99 100 101 102
    return;
}
```

103
#### 读取AD转换结果
104 105 106 107 108 109 110 111 112

```c
int32_t AdcRead(DevHandle handle, uint32_t channel, uint32_t *val);
```

**表 3**  AdcRead参数和返回值描述

<a name="table3"></a>

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| 参数       | 参数描述       |
| ---------- | -------------- |
| handle     | ADC设备句柄    |
| channel    | ADC设备通道号  |
| val        | AD转换结果     |
| **返回值** | **返回值描述** |
| 0          | 读取成功       |
| 负数       | 读取失败       |

读取转换结果示例(以通道1为例):

```c
uint32_t value;
int32_t ret;

ret = AdcRead(adcHandle, 1, &value);
if (ret != 0) {
    HDF_LOGE("ADC read fail!\n");
    return;
}
```

#### 关闭ADC设备
136 137 138 139 140 141 142 143 144

ADC通信完成之后,需要关闭ADC设备。
```c
void AdcClose(DevHandle handle); 
```
**表 4**  AdcClose参数和返回值描述

<a name="table4"></a>

145 146 147 148 149
| 参数   | 参数描述    |
| ------ | ----------- |
| handle | ADC设备句柄 |
| 返回值 | 返回值描述  |
| 无     | 无          |
150 151 152 153 154 155 156

关闭ADC设备示例:

```c
AdcClose(adcHandle); /* 关闭ADC设备 */
```

157
### 使用实例<a name="section10"></a>
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197

本例程以操作开发板上的ADC设备为例,详细展示ADC接口的完整使用流程。

本例拟对Hi3516DV300某开发板上ADC设备进行简单的读取操作,基本硬件信息如下:

-   SOC:hi3516dv300。

-   原理图信息:电位器挂接在0号ADC设备1通道下。

本例程对测试ADC进行连续读取操作,测试ADC功能是否正常。

示例如下:

```c
#include "adc_if.h"          /* ADC标准接口头文件 */
#include "hdf_log.h"         /* 标准日志打印头文件 */

/* 设备号0,通道号1 */ 
#define ADC_DEVICE_NUM 0
#define ADC_CHANNEL_NUM 1

/* ADC例程总入口 */ 
static int32_t TestCaseAdc(void)
{
    int32_t i;
    int32_t ret;
    DevHandle adcHandle;
    uint32_t Readbuf[30] = {0};

    /* 打开ADC设备 */ 
    adcHandle = AdcOpen(ADC_DEVICE_NUM);
    if (adcHandle == NULL) {
        HDF_LOGE("%s: Open ADC%u fail!", __func__, ADC_DEVICE_NUM);
        return -1;
    }

    /* 连续进行30次AD转换并读取转换结果 */ 
    for (i = 0; i < 30; i++) {
        ret = AdcRead(adcHandle, ADC_CHANNEL_NUM, &Readbuf[i]);
        if (ret != HDF_SUCCESS) {
198
            HDF_LOGE("%s: ADC read fail!:%d", __func__, ret);
199 200 201 202 203 204 205 206 207 208 209 210
            AdcClose(adcHandle);
            return -1;
        }
    }
    HDF_LOGI("%s: ADC read successful!", __func__);

    /* 访问完毕关闭ADC设备 */ 
    AdcClose(adcHandle);

    return 0;
}
```