天天看點

《嵌入式 - 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;
}
           

本章參考代碼