ADC模数转换器

1. ADC模数转换器

ADC: 模数转换器  : 将模拟量转换为数字量 的 硬件设备  

DAC: 数模转换器  : 将数字量转换为模拟量 

1.1 工作原理

ADC: 工作原理  主要用于测量电压  

1. 逐次逼近型CMOS: 结构一般 成本一般  转换一般   稳定性较低   即对精度要求不高,转换位数一般 成本低 单片机 

2. 积分微分型: 结构简单 成本低  转换速度慢   稳定性较高   精度要求高 但速度不要求的场合  电子秤 数字万用表

3. 直接比较型: 结构复杂 成本高    转速快   稳定性较高   速度快 但 精度要求不高  8bit 10bit 示波器 摄像头

1.2 ADC的工作条件

参考电压:   模拟量的量程  已知且稳定   

转换位数:  数字量的量程  例如 8bit  10bit  12bit  ...

数字量量程  /  参考电压   ==  测量值  / 被测电压 

被测电压(V) =  测量值 / ( 数字量量程/参考电压)

1.3 系统ADC的时钟

133mhz

ADC模数转换器_第1张图片

2. ADC电压测量实验

2.1  原理图

1. 设备 

旋转电位器 输出电压范围 0-1.8V   

ADC模数转换器_第2张图片

ADC模数转换器_第3张图片

2. 原理图 

XadcAIN3 ---   ADC输入通道3 

4412 有4个ADC输入 专用管脚 

3. 芯片手册   ADC控制器 

数字量 量程  可选  10bit 或 12bit 

逐次逼近型 ADC  

ADC 需要时钟驱动  且最大驱动时钟速度 不超过5M(所以后面要分频),最大1M转 换速度 

参考电压  典型值 1.8V 

2.2 配置之寄存器

ADCCON 控制寄存器

[16]  = 1 采用12bit转换 

[15]  只读  转换结束 标志位 只读  0正在转换  1转换结束 

[14]  = 1 预分频使能 

[13:6] = 预分值 19-255    26  =  133M / 5M - 1  (133/5-1=25.6 为了不超过最大驱动时钟所以取26m)

[2]  = 0  正常工作模式  (不能待机)

[1]  = 0 不使用  读使能转换模式   一般多用于 连续采样 快速采样  

[0]  = 1 手动开始一次转换  

ADC模数转换器_第4张图片

ADCDAT 数据寄存器 

ADCDAT  数据寄存器  存放转换的结果 

ADC模数转换器_第5张图片

ADCMUX 输入通道选择

ADCMUX  输入通道选择   = 3  

ADC模数转换器_第6张图片

2.3 写代码

adc_test----main.c


#include"exynos_4412.h"
#include"uart.h"

//ADC电压测量实验

//初始化adc
 void acd_init(){

    //选择12bit精度的ADC
    ADCCON |= 1<<16;

    //[14]  = 1 预分频使能 
    ADCCON |= 1<<14;

    // [13:6] = 预分值 19-255    26  =  133M / 5M - 1  (133/5-1=25.6 为了不超过最大驱动时钟所以取26m)
    ADCCON = (ADCCON &~(0xff<<6)) | (26<<6);

    // [2]  = 0  正常工作模式  (不能待机)
    ADCCON &= ~(1<<2);

    // [1]  = 0 不使用  读使能转换模式   一般多用于 连续采样 快速采样  
    ADCCON &= ~(1<<1);

    //ADCMUX  输入通道选择   = 3  
    ADCMUX = 3;

 }

 //手动开启adc转换
 void adc_start(){
    // [0]  = 1 手动开始一次转换  
    ADCCON |= 1;
 }

 int adc_get_value(){
    //[15]  只读  转换结束 标志位 只读  0正在转换  1转换结束 
    while(((ADCCON >> 15) & 1) == 0){//等待结束

    }

    //ADCDAT  数据寄存器  存放转换的结果
    return ADCDAT & 0xfff; //因为ADCDAT只有[11:0]有效 12个bit有效 又因为我们接收的 a 是 short 16bit类型,16bit装12bit的数够用
 }

int main()
{
    unsigned short a; //存储模拟量
    float f; // 存储电压值
    uart_init();
    printf("hello!a=%d\r\n",a);

    //初始化adc
    acd_init();
    while(1){
        adc_start();
        a = adc_get_value();
		 f = 1.8 /4096*a; // 因为我们选的是12bit精度的adc 即4096
        //因为我们移植的printf在打印小数时有点问题,所以我们将整数和小数分开打印
        //整数f=%d (int)f
        //小数.%02d(保留两位小数)  (int)((f - (int)f) *100)  先用原来的数减去整数部分 扩大100倍就是小数了,但是此时还是float类型,需要再次转为int类型
		 printf("a=%u f=%d.%02d  \r", a, (int)f, (int)((f - (int)f) *100));

    }
    return 0;
}


ADC模数转换器_第7张图片

你可能感兴趣的:(exynos4412接口编程,arm开发,嵌入式硬件,c语言)