A/D 컨버터(Analog Digital Converter)
AT91SAM7S256은 8채널 10비트 또는 8비트 분해능의 축자비교형 A/D 컨버터를 가지고 있다. 각 채널의 입력은 내부의 아날로그 멀티플렉서에 의하여 선택되며, 이들 8채널의 아날로그 입력신호 중에서 AD0~AD3은 병렬 I/O 포트와 겸용으로 사용하고 있고, AD4~AD7은 전용핀을 가지고 있다.
A/D 컨버터에서 사용하는 클럭의 주파수는 ADC_MR 레지스터의 PRESCAL 필드에 의하여 MCK/2/(PRESCAL+1)로 결정되므로 MCK/2 ~ MCK/128의 범위가 된다. 10비트 분해능을 사용할 때는 A/D 클럭으로 5MHz 이하를 사용해야 하며, 8비트 분해능을 사용할 때는 A/D 클럭으로 8MHz 이하를 사용해야 한다.
각 채널에서 10비트 또는 8비트 분해능으로 A/D 변환을 수행하는데는 ADC_MR 레지스터에서 SHTIM 필드로 지정한 샘플/홀드에 필요한 클럭 주기와 10주기의 A/D 변환 클럭 사이클이 소요 된다. 샘플/홀드 시간은 최소 600ns 이상이 필요하다.
ex) 10비트 분해능 5MHz 클럭에서 최소 3주기의 샘플/홀드 시간과 10주기의 A/D 변환 시간이 소요
: 최대 384kSPS(sampling/sec)
8비트 분해능 8MHz 클럭에서 최소 5주기의 샘플/홀드 시간과 10주기의 A/D 변환 시간이 소요
: 최대 533kSPS(sampling/sec)
A/D 컨버터에는 외부 단자 ADVREF를 통하여 기준전압이 공급되어야 한다. 이 기준전압은 2.6V ~ VDDIN의 범위를 가져야 하며, 이에 따라 각 채널에서의 아날로그 신호 입력의 범위는 0.0V ~ ADVREF로 결정된다.
8비트 분해능을 사용할 경우에는 이중에서 하위 8비트만 유효하며 사용하지 않는 상위 2비트는 0으로 읽혀진다.
A/D 컨버터가 변환을 완료하면 상태 레지스터 ADC_SR 에서 EOCx 비트와 DRDY 비트가 1로 세트된다. 사용자 프로그램으로 ADC_CDRx 레지스터를 읽으면 EOCx 비트는 0으로 클리어되며, ADC_LCDR 레지스터를 읽으면 EOCx 비트와 DRDY 비트가 모두 0으로 클리어 된다.
새로운 A/D 변환이 왼료될 때까지 ADC_CDRx 레지스터에 저장되어 있는 이전의 A/D 변환 결과를 읽지 않으면 오버런 에러가 되고 ADC_SR 레지스터에서 대응하는 채널의 OVREx 비트가 세트된다. 마찬가지로 ADC_LCDR 레지스터를 읽지 않아 오버런 에러가 발생하면 ADC_SR 레지스터에서 GOVRE 비트가 세트된다. 이들 에러 비트는 ADC_SR 레지스터를 읽으면 자동으로 클리어된다.
A/D 변환 트리거는 여러 개의 채널을 사용하더라도 오직 1번만을 필요로 한다. 즉 A/D 변환을 시작하도록 트리거하면 동작이 허용된 모든 채널에서 A/D 변환이 시작된다.
A/D 컨버터를 슬립 모드로 하면 클럭의 공급을 차단하고 동작을 저지시킴으로써 소비전력을 크게 절약할 수 있다. A/D 컨버터가 슬립 모드에 있더라도 A/D 컨버터 내부의 로직 회로는 정상으로 동작하여 모든 I/O 레지스터의 액세스가 가능하다.
// ADC 예제 소스
// 변환 값 입력에 가변저항을 연결하여 저항을 바꿔가면서 입력값에 변화를 준다.
// 이때 입력된 아날로그 신호에 대응하는 변환된 디지털 값들을 시리얼 통신을 이용하여 PC의 터미널에 보여준다.
// ADC_CR 에 START 비트는 변환할 때마다 1로 세트 해주어야 한다.
AT91SAM7S256은 8채널 10비트 또는 8비트 분해능의 축자비교형 A/D 컨버터를 가지고 있다. 각 채널의 입력은 내부의 아날로그 멀티플렉서에 의하여 선택되며, 이들 8채널의 아날로그 입력신호 중에서 AD0~AD3은 병렬 I/O 포트와 겸용으로 사용하고 있고, AD4~AD7은 전용핀을 가지고 있다.
A/D 컨버터에서 사용하는 클럭의 주파수는 ADC_MR 레지스터의 PRESCAL 필드에 의하여 MCK/2/(PRESCAL+1)로 결정되므로 MCK/2 ~ MCK/128의 범위가 된다. 10비트 분해능을 사용할 때는 A/D 클럭으로 5MHz 이하를 사용해야 하며, 8비트 분해능을 사용할 때는 A/D 클럭으로 8MHz 이하를 사용해야 한다.
각 채널에서 10비트 또는 8비트 분해능으로 A/D 변환을 수행하는데는 ADC_MR 레지스터에서 SHTIM 필드로 지정한 샘플/홀드에 필요한 클럭 주기와 10주기의 A/D 변환 클럭 사이클이 소요 된다. 샘플/홀드 시간은 최소 600ns 이상이 필요하다.
ex) 10비트 분해능 5MHz 클럭에서 최소 3주기의 샘플/홀드 시간과 10주기의 A/D 변환 시간이 소요
: 최대 384kSPS(sampling/sec)
8비트 분해능 8MHz 클럭에서 최소 5주기의 샘플/홀드 시간과 10주기의 A/D 변환 시간이 소요
: 최대 533kSPS(sampling/sec)
A/D 컨버터에는 외부 단자 ADVREF를 통하여 기준전압이 공급되어야 한다. 이 기준전압은 2.6V ~ VDDIN의 범위를 가져야 하며, 이에 따라 각 채널에서의 아날로그 신호 입력의 범위는 0.0V ~ ADVREF로 결정된다.
8비트 분해능을 사용할 경우에는 이중에서 하위 8비트만 유효하며 사용하지 않는 상위 2비트는 0으로 읽혀진다.
A/D 컨버터가 변환을 완료하면 상태 레지스터 ADC_SR 에서 EOCx 비트와 DRDY 비트가 1로 세트된다. 사용자 프로그램으로 ADC_CDRx 레지스터를 읽으면 EOCx 비트는 0으로 클리어되며, ADC_LCDR 레지스터를 읽으면 EOCx 비트와 DRDY 비트가 모두 0으로 클리어 된다.
새로운 A/D 변환이 왼료될 때까지 ADC_CDRx 레지스터에 저장되어 있는 이전의 A/D 변환 결과를 읽지 않으면 오버런 에러가 되고 ADC_SR 레지스터에서 대응하는 채널의 OVREx 비트가 세트된다. 마찬가지로 ADC_LCDR 레지스터를 읽지 않아 오버런 에러가 발생하면 ADC_SR 레지스터에서 GOVRE 비트가 세트된다. 이들 에러 비트는 ADC_SR 레지스터를 읽으면 자동으로 클리어된다.
A/D 변환 트리거는 여러 개의 채널을 사용하더라도 오직 1번만을 필요로 한다. 즉 A/D 변환을 시작하도록 트리거하면 동작이 허용된 모든 채널에서 A/D 변환이 시작된다.
A/D 컨버터를 슬립 모드로 하면 클럭의 공급을 차단하고 동작을 저지시킴으로써 소비전력을 크게 절약할 수 있다. A/D 컨버터가 슬립 모드에 있더라도 A/D 컨버터 내부의 로직 회로는 정상으로 동작하여 모든 I/O 레지스터의 액세스가 가능하다.
// ADC 예제 소스
#include "MyArm.h"
//--------- Global Variable�
void Delayms(unsigned int ms) //Delay Function..
{
volatile unsigned int count, countmax = (MASTERCLOCK / 10000) * ms;
for(count = 0; count < countmax; count++);
}
void DBGU_write(char *d)
{
while(0 != *d)
{
while(0 == (DBGU_SR & 0x0002));
DBGU_THR = *d;
++d;
}
}
void intToChar(char *buf, unsigned int num)
{
int i, j;
int target; // 각 자리수
int value = 1; // 숫자 크기 확인
while(value <= num)
{
value *= 10;
}
for(i = 0, j = value/10 ; j >= 10 ; j /= 10)
{
target = num / j;
num = num % j;
buf[i++] = target + 48; // buf에 문자값 저장
}
buf[i++] = num + 48;
buf[i] = '\0';
}
int main(void)
{
unsigned int data;
unsigned int tmp;
char buf[10];
DBGU_CR = (1 << P2) | (1 << P3); // TX,RX reset & disable
// PMC setting
PMC_PCER = (1 << PID4);
// PIO setting
PIO_PDR = (1 << P10);
PIO_ASR = (1 << P10);
// DBGU setting
DBGU_MR = (1 << P11); // No Parity
DBGU_BRGR = 313; // Baud rate = 9600
DBGU_CR = (1 << P6); // TX enable
// ADC setting
ADC_MR = (23 << P8) | (1 << P4) | (1 << P24); // PRESCAL = 23(1Mhz), 8 bit Low Resolution, SHTIM = 1
ADC_CHER = (1 << P4); // Channel 4
while(1)
{
ADC_CR = (1 << P1); // Start Conversion
while(0 == (ADC_SR & (1 << P16)));
data = ADC_LCDR;
intToChar(buf, data);
DBGU_write(buf);
DBGU_write("\r\n");
Delayms(50);
tmp = ADC_SR;
}
return 0;
} // End Main...
// 이때 입력된 아날로그 신호에 대응하는 변환된 디지털 값들을 시리얼 통신을 이용하여 PC의 터미널에 보여준다.
// ADC_CR 에 START 비트는 변환할 때마다 1로 세트 해주어야 한다.