ARM接口技术——ADC

ADC简介

ADC

ADC(Analog to Digital Converter)即模数转换器,指一个能将模拟信号转化为数字信号的电子元件。

ADC分辨率

ADC的分辨率一般以输出二进制数的位数来表示,当最大输入电压一定时,位数越高,分辨率越高;

n位的ADC能区分输入电压的最小值为满量程输入的1/2^n;

比如一个12位的ADC,最大输入电压为1.8v,那么该ADC能区分的最小电压为1.8v/2^12≈0.00044v;

当转换的结果为m时,则实际的电压值为m*(1.8v/2^12);

SOC下的ADC实验

实验分析

实验使用的是一个滑动变阻改变电压的模拟信号输入;

SOC芯片使用的是Exynos4412,它集成了ADC转换器,无需再加装ADC转换器,只需要把模拟信号输入与ADC功能的引脚相连即可。

(Exynos4412没有集成DAC模块,如果需要输出模拟信号,要自己添加DAC芯片,或者使用PWM的方法)

电路原理图:

外围电路:

 

VDD1V8_EXT就是SOC外围电路的电源1.8V,5号导线位置是一个滑动变阻器,滑动可以改变XadcAIN3端的电压值(0-1.8V)。

XadcAIN3与SOC核心板ADC模块连接。

 

核心板:

 

 

Exynos4412大部分引脚都是有复用功能,而提供的这4个ADC引脚是专用输入模拟信号的引脚,只有一个名字XadcASINn,所以不需要对引脚功能进行设置;

我们使用的是XadcASIN3。

芯片手册ADC模块的说明:

Overview:

主要有三个关键信息:

它的模拟精度可以配置成10为和12位;

ADC最大转换速度是1MSPS;

输入的电压范围为0-1.8V。


 

ADC的转换速度:

ADC的转换需要一个时钟,以说明为例,66MHz的时钟分频成1MHz给ADC,ADC每5个周期转换一次,所以转换频率是200MSPS,转换一次的时间是5us。

(实际使用的是PCLK = 100MHz)

前面提到ADC的最大转换速度是1MSPS,对应的时钟频率是5MHz,所以给ADC的时钟频率不能超过5MHz,使用的是PCLK,那么需要至少分频20。


芯片手册ADC相关寄存器

寄存器摘要:

 本实验主要使用3个寄存器,分别是ADC配置寄存器、ADC存放数据的寄存器和ADC通道选择寄存器(前面提到有4个ADC通道)。

 1). ADCCON

  • RES位用于选择转换精度,我们选择12位,RES=1;
  • ECFLG用于查看转换是否完成,这里用于读;
  • PRSCEN用于打开时钟分频,PRSCEN=1;
  • PRSCVL用于设置分频的大小,我们使用的时钟与例子相同,所以19分频是极限值,我们设大一点,PRSCVL=25;
  • STANDBY用于设置功耗模式,我们就设置为正常工作,STANDBY=0;
  • READ_START和ENABLE_START用于设置ADC的触发方式。
    • READ_START设为1,ADC会自动进行一次转换,但是它不会进行下一次转换,而是被读了之后,才会自动进行一次转换;
    • ENABLE_START设为1,ADC就会开始一次转换,转换完以后,它会自动变成0,进行下次转换需要写1。

 2). ADCDAT

存放了ADC转换的结果,只需要读即可,需要注意的是读取时高位要清0,因为它是无效位,可能会有随机值。

3). ADCMUX

芯片只有1ADC转换器,但是有多个模拟输入引脚,它使用的是分时复用;

所以需要告诉ADC转换哪个模拟输入的引脚,ADCMUX = 0011。


 

实验代码

#include "exynos_4412.h"

void ADC_Init(unsigned int channel)
{
    /* 设置ADC转换精度 */
    ADCCON |= (1<<16);
    /* 打开分频器 */
    ADCCON |= (1<<14);
    /* 设置20分频 */
    ADCCON = ADCCON & (~(0xFF<<6)) | (19<<6);
    /* 关闭待机模式 */
    ADCCON = ADCCON & (~(1<<2));
    /* 关闭读触发AD转换的方式 */
    ADCCON = ADCCON & (~(1<<1));
    /* 设置AD转换通道 */
    ADCMUX = channel;
}


int main()
{
    unsigned int value;
    ADC_Init(3);
    while(1)
    {
        ADCCON |= 1;     /* ADC开始一次转换 */
        while(!(ADCCON & (1<<15)));
        value = ADCDAT & 0xFFF;     /* 读取相对电压 */
        value *= 0.44;    /* 转换成实际电压,单位为mV */
        printf("%d mV\n", value); /* 重定向到UART的printf,在另一个文件实现 */
    }
    return 0;
}

 


 

实验现象

 


END

 

posted @ 2022-04-27 23:37  zj城城城城  阅读(701)  评论(0编辑  收藏  举报