一,ADC简介
ADC
即模拟数字转换器(英语:Analog-to-digital converter)是用于将模拟形式的连续信号转换为数 字形式的离散信号的一类设备。
ADC 用于将模拟值从现实世界转换为数字值,如1和0。那么这些模拟值是什么?这些是我们在日常生 活中看到的,比如温度、速度、亮度等。但是ADC 能否将温度和速度直接转换为0和1等数字值?当然 不是。ADC只能将模拟电压值转换为数字值。因此,无论我们想要测量哪个参数,都应该先将其转换为 电压,这种转换可以在传感器的帮助下完成。例如,为了将温度值转换为电压,我们可以使用热敏电 阻,同样,为了将亮度转换为电压,我们可以使用LDR。一旦转换成电压,我们就可以在ADC的帮助下读取。
二,基本原理
基本原理:
它分为
采样
,
保持
,
量化
和
编码
四个步骤
1.
采样
:这一步骤涉及周期性地采取模拟信号的瞬时值,得到一系列的脉冲样值。采样周期的长短决定了转换结果的精确度。根据奈奎斯特采样定理,采样频率应大于或等于输入模拟信号频谱中最高 频率的两倍,以确保转换的准确性。
2.
保持
:在连续两次采样之间,为了使前一次采样所得信号保持不变,以便进行量化和编码,需将
其保存起来。这通常通过采样-保持电路实现,该电路由存储样值的电容、场效应管及电压跟随运
算放大器组成,确保在采样停止期间电容上的电压基本保持不变。
3.
量化
:量化是将采样-保持电路的输出信号按照某种近似方式归并到相应的离散电平上,也就是将 模拟信号在取值上离散化的过程。离散后的电平称为量化电平,量化误差的大小取决于ADC的分辨 率。
4.
编码
:编码是将量化后的结果(离散电平)用数字代码(如二进制数)来表示。编码的本质是输出 一串数字代码,这个代码会尽可能地接近当前采样到的模拟值。不同的量化方式决定了编码的规则。

A/D转换器的主要技术指标:
1.
测量范围
。决定了外接的设备其信号输出电压范围
2.
分辨率
。输出二进制数的位数表示,位数越多,误差越小,转换精度越高。
3.
转换速度
。转换速度是指A/D转换器完成一次转换所需的时间
4.
采样时间
。保持某一时刻的外部信号,保持时间就是采样时间
5.
采样率
。在一秒的时间内采集多少次
三,I.MX6ull ADC介绍
3.1 Features(特点)
1,Up to 1MS/s sampling rate
高达1MS/s的采样率
2,Single or continuous conversion (automatic return to idle after single conversion)
单次或连续转换(单次转换后自动返回空闲)
3,Output Modes: (in right-justified unsigned format) 12-bit/10-bit/8-bit
输出模式:(右对齐无符号格式)12位/10位/8位【A/D的分辨率】
4,Configurable sample time and conversion speed/power
可配置采样时间和转换速度/功率
5,Conversion complete and hardware average complete flag and interrupt
转换完成和硬件平均完成标志和中断 【转换完成可以产生内部中断】
6,Input clock selectable from up to three sources
输入时钟可从多达三个源选择
7,Automatic compare with interrupt for less-than, greater-than or equal-to, within range, or out-of-range, programmable value
对小于、大于或等于、范围内或范围外的可编程值自动比较并产生中 断
8,Operation in low power modes for lower noise operation
在低功率模式下运行,以实现更低的噪声运行
9,Hardware average function
硬件平均函数
10,Self-calibration mode
自校准模式
3.2 ADC 状态
禁用状态:
在复位或停止模式下(如果未选择内部时钟作为时钟源),ADC模块将被禁用.
闲置状态:
当一个转换完成而另一个转换尚未启动时,模块处于空闲状态。当空 闲并且异步时钟输出使能被禁用(ADACKEN=0)时,模块处于最低功率状态。
转换状态
ADC可以在任何软件可选通道上执行模数转换。所有模式都通过逐次逼近算法执行转换
3.3ADC框图

3.4 ADC时钟选择和分频控制
ADC数字块通过内部分割IPG时钟产生IPG时钟/2。最终时钟从以下时钟中选择
IPG clock (IPG时钟)
This is the default selection following reset.(这是重置后 的默认选择)
IPG clock divided by 2 (IPG时钟除以2)
For higher IPG clock rates, this allows a maximum divide by 16 of the IPG clock using the ADIV bits. (对于更高的 IPG时钟速率,这允许最大使用ADIV位除以IPG时钟的16)
ADACK
This clock is generated from a clock source within the ADC module. Conversions are possible using ADACK as the input clock source while the MCU is in stop mode(该时钟由 ADC模块内的时钟源生成。当MCU处于停止模式时,可以使用ADACK作 为输入时钟源进行转换)
从上面列出的三个时钟中,选择一个取决于ADC_CFG的ADICLK[1:0]位的
配置。所选时钟根据ADC_CFG的ADIV[1:0]位的配置进行划分。最后生成
的时钟用作ADC的转换时钟。

3.5 硬件平均函数
可启用硬件平均功能(AVGE=1),对多次转换进行硬件平均。转换次数由 AVGS[1:0]位决定,选择4、8、16或32个转换进行平均。当硬件平均功能 正在进行时,将设置ADACT位。

在所选择的输入进行采样和转换后,将结果放入累加器中, 一旦完成所选 择的转换次数,就从累加器中计算平均值。当选择硬件平均时,完成一次 转换不会设置COCOn位

如果关闭比较功能或计算结果为true,则在所选择的转换次数完成后, 将转换结果的平均值传输到数据结果寄存器ADC_Rn中,并设置COCOn位。 如果相应的ADC中断被启用(AIENn=1),则在设置COCOn时产生ADC中断。

3.6 自动比较功能
比较函数配置为检查结果是否小于或大于或等于单个比较值,或者结果是 否在由两个比较值确定的范围内或之外。比较模式由ACFGT、ACREN和比 较值寄存器(ADC_CV)中的值决定。在对输入进行采样和转换后,比较值 (CV1和CV2)的使用如下表所示。有六种比较模式,如下表所示。

3.7 校准功能
(要完成校准,用户必须遵循以下程序):
1,ADC_CFG配置为实际操作值,以获得最大的精度
2, 配置ADC_GC值和CAL位
3,检查ADC_GS中CALF位和ADC_GC中CAL位的状态
4,当CAL位变为’0’时,检查CALF状态和COCO[0]位状态

四,代码实现
#include "adc.h"
/*
ADC1_IN6 --- GPIO1_IO06
*/
void adc_gpio_init(){
//GPIO初始化
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO06 &= ~(0xf<<0);
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO06 |= (0x5<<0);
GPIO1->GDIR |= (0x1<<6);
//使能ADC模块时钟
CCM->CCGR1 |=(0x3 << 16);
//设置ADC控制器,ADC转换的精度和选择时钟源
ADC1->HC[0] |= (0x1<<7) |(0x6<<0);
ADC1->CFG &= ~(0xf<<0);
//设置adc精度
ADC1->CFG &= ~(0x3<<5);
}
//配置自动校准
int auto_calibration(){
ADC1-> GC |= (0x1<<7) ;
while((ADC1->GC)& (0x1<<7)){
//判断校验是否失败
if((ADC1->GS) & (0x1<<1)){
uart_printf("auto_calibration fail \r\n");
return -1;
}
}
if( (ADC1->HS & (0x1<<0))==1){
uart_printf("auto_calibration successful");
return 0;
}
return -1;
}
void adc_start_interrupt(){
ADC1->HC[0] |=(0x1<<7);
}
//选通道
void adc_select_channel(){
ADC1->HC[0] &=~( 0x1f<<0);
ADC1->HC[0] |= (0x6<<0);
}
void adc_start_conversion(){
adc_select_channel();
adc_start_interrupt();
}
int adc_handler(int irq_num){
//拿到值
uint32_t value =ADC1->R[0] & (0xff<<0);
//转换成mv八位分辨率 256 总电压为3.3v即3300mv
uint32_t adc_mv=value*3300/256;
uart_printf("value :%d,adc_mv :%d \r\n",value,adc_mv);
adc_start_conversion();
delay_s(1);
}
void adc_test(){
adc_gpio_init();
int ret= auto_calibration();
if(ret==-1){
uart_printf("adc failure\r\n");
return;
}
//注册中断
request_irq(ADC1_IRQn,adc_handler);
enable_irq();
adc_start_conversion();
}
ADC简单来说就是一种将模拟信号转换为数字信号的一中操作.因为数字信号十分容易操作,存储和传输。