9.1 Exynos4412 A/D转换器概述
9.1.1简述
10位或12位CMOS再循环式模拟数字转换器,它具有10通道输入,并可将模拟量转换至10位或12位二进制数。5Mhz A/D 转换时钟时,最大1Msps的转换速度。A/D转换具备片上采样保持功能,同时也支持待机工作模式。
9.1.2特性
ADC接口包括如下特性。
1)10bit/12bit输出位可选。
2)微分误差 1.0LSB。
3)积分误差 2.0LSB。
4)最大转换速率5Msps.
5) 功耗少,电压输入1.8V。
6)电压输入范围 0~1.8V。
7)支持偏上样本保持功能。
8)通用转换模式。
9.1.3模块图
4412A/D转换器的控制器接口框图如下:

图1
9.2 Exynos4412 A/D 控制器寄存器
9.2.1 A/D控制寄存器ADCCON
表1
9.2.2 A/D转换数据寄存器ADCDAT0
表2
9.2.3 A/D转换的转换时间计算
例如: PCLK为100MHz,PRESCALER = 65 ;所有10位转换时间为
100MHz/(99+1) = 1MHz
转化时间为1/(1MHz/5 cycles) = 5us。
完成一次A/D转换需要5个时钟周期。A/D转换器的最大工作时钟为5MHz,所以最大采样率可以达到1Mit/s.
9.3 A/D转换器实例
9.3.1电路连接如下:
利用一个电位计输出电压到4412的AIN3管脚。输入的电压范围为0~1.8V。
图2
9.3.2程序编写
9.3.2.1相关寄存器定义
/*********************** ADC ******************************************/
#define ADC_CFG __REG(0x10010118)
#define ADCCON __REG(0x126C0000)
#define ADCDLY __REG(0x126C0008)
#define ADCDAT __REG(0x126C000C)
#define CLRINTADC __REG(0x126C0018)
#define ADCMUX __REG(0x126C001C)
9.3.2.2具体代码
#include "exynos_4412.h"
#include "uart.h"
/*
*If A/D conversion start by read
* /
//#define __READ_START_
/**********************************************************************
* @brief mydelay_ms program body
* @param[in] int (ms)
* @return None
**********************************************************************/
void mydelay_ms(int time)
{
int i, j;
while(time--)
{
for (i = 0; i < 5; i++)
for (j = 0; j < 514; j++);
}
}
/*-------------------------MAIN FUNCTION------------------------------*/
/**********************************************************************
* @brief Main program body
* @param[in] None
* @return int
**********************************************************************/
int main(void)
{
unsigned int temp_adc = 0, temp_mv;
GPX2.CON = 0x1 << 28;//GPX2CON[7]: Output drive LED
uart_init();
ADC_CFG &= ~(0x1 << 16); //Bit_16:Select ADC Mux 0:General 1:MTCADC
ADCMUX = 0x3; //0x3: 0011 = AIN3
#ifdef __READ_START_
//12bit A/D conversion; enable A/D converter prescaler; prescaler value:255; A/D conversion start by read
ADCCON = (0x1<<16) | (0x1<<14) | (0xff<<6) | 0x1<<1;
#else
//12bit A/D conversion; enable A/D converter prescaler; prescaler value:255
ADCCON = (0x1<<16) | (0x1<<14) | (0xff<<6);
#endif
#ifdef __READ_START_
temp_adc = ADCDAT & 0xfff;
#endif
printf("\n************ ADC test ************\n");
while(1)
{
//Turn on LED
GPX2.DAT |= 0x1 << 7;
#ifndef __READ_START_
ADCCON |= 0x1;//start ADC conversion
#endif
mydelay_ms(100);
while(!(ADCCON & (0x1<<15)));
temp_adc = ADCDAT & 0xfff;
temp_mv = 1800 * temp_adc / 4095;
printf("adc value: %d mv\n", temp_mv);
mydelay_ms(500);
//Turn off LED
GPX2.DAT &= ~(0x1 << 7);
mydelay_ms(500);
}
return 0;
}