天天看点

《嵌入式 - ARM》第9章 ARM AD转换

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转换器的控制器接口框图如下:

《嵌入式 - ARM》第9章 ARM AD转换

图1

9.2 Exynos4412 A/D 控制器寄存器

9.2.1 A/D控制寄存器ADCCON

表1

《嵌入式 - ARM》第9章 ARM AD转换

9.2.2 A/D转换数据寄存器ADCDAT0

表2

《嵌入式 - ARM》第9章 ARM AD转换

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;
}
           

本章参考代码