1. ADC模数转换器
ADC: 模数转换器 : 将模拟量转换为数字量 的 硬件设备
DAC: 数模转换器 : 将数字量转换为模拟量
1.1 工作原理
ADC: 工作原理 主要用于测量电压
1. 逐次逼近型CMOS: 结构一般 成本一般 转换一般 稳定性较低 即对精度要求不高,转换位数一般 成本低 单片机
2. 积分微分型: 结构简单 成本低 转换速度慢 稳定性较高 精度要求高 但速度不要求的场合 电子秤 数字万用表
3. 直接比较型: 结构复杂 成本高 转速快 稳定性较高 速度快 但 精度要求不高 8bit 10bit 示波器 摄像头
1.2 ADC的工作条件
参考电压: 模拟量的量程 已知且稳定
转换位数: 数字量的量程 例如 8bit 10bit 12bit ...
数字量量程 / 参考电压 == 测量值 / 被测电压
被测电压(V) = 测量值 / ( 数字量量程/参考电压)
1.3 系统ADC的时钟
133mhz
2. ADC电压测量实验
2.1 原理图
1. 设备
旋转电位器 输出电压范围 0-1.8V
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 手动开始一次转换
ADCDAT 数据寄存器
ADCDAT 数据寄存器 存放转换的结果
ADCMUX 输入通道选择
ADCMUX 输入通道选择 = 3
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;
}