본문 바로가기

스터디 상생플러스 4 - 1 (ADC 이론)

반응형

임베디스 기기들은 디지털 신호를 다룰 수 있지만,

반대로 아날로그 신호도 다룰 수 있어야합니다.

 

자연에 존재하는 온도, 밝기, 소리 등의 값들은  0과 1로만 표현되는 값들이 아닌,

1.1, 2.1, 0.5453등과 같은 연속적인 값들을 갖고 있기 때문입니다.

 

이러한 이유로 임베디드 기기의 메인 칩인 MCU에는 아날로그 값을 읽을 수 있어야합니다.

하지만 MCU자체는 전자기기이기 때문에 0, 1으로만 동작하고 아날로그 값은 0.1등과 같은 값이 있기 때문에

아날로그 값을 읽을려면 아날로그 값을 디지털 값으로 바꿔주는 장치가 필요할 것입니다.

 

ADC는 Analog to Digital Converter의 약자로,

글자 그대로 아날로그 값을 디지털 값으로 변환해주는 보조 보조 모듈입니다.

 

ADC란

ADC는 위에서 설명한 것처럼 Analog to Digital Conveter의 약자입니다.

ADC에는 해상도(분해능 = 정밀도)라는 개념과 기준전압(Voltage Reference)라는 개념이 있습니다.

 


해상도

해상도는 "전압을 얼마나 정밀하게 측정할 수 있나"에 관한 개념입니다.

또는 "전압을 얼마만큼의 크기로 분해할 것인가"에 관한 개념입니다.

단위는 bit이며, 1bit, 2bit, 3bit.... 10bit등 광범위한 해상도 값이 존재합니다.

 

만약에 우리가 0v ~ 5v사이에 있는 값을 측정하려고 하고, 해상도가 10bit라면

이는 0v ~ 5v값을 1024(=2^10)개로 분해한다는 뜻입니다.

즉, 우리가 측정할 수 있는 최소한의 전압은

5v / (1024) = 0.0048828125v라는 비교적 정밀한 값을 얻을 수 있습니다.

즉 10bit해상도면 0v ~ 5v사이의 전압을 0.0048828125v단위로 측정할 수 있다는 뜻이죠

 

만약 해상도가 2bit라면

5v / (4) = 1.25v라는 비교적 부정확한 값 단위로 측정할 수 있습니다.

 

 

결론적으로 해상도가 높으면, 보다 더 정밀한 값을 측정할 수 있다는 뜻입니다.

 

기준값(Voltage Reference)

기준값은 범위라고 생각하시면 됩니다.

0v에에서 어디까지의 범위로 측정할지를 결정하는 값이라는 뜻입니다.

 

기준값이 5v라면 0v ~ 5v

2.5v라면 0v ~ 2.5v

1.1v라면 0v ~ 1.1v입니다.

 

즉 측정 범위를 설정한다는 의미이죠.


 

ADC 관련 레지스터들

Atmega328에는 ADC 관련된 정보를 갖고 있는 레지스터들이 있습니다.

관련 정보들로는

1. ADC 활성화

2. 아날로그 값을 읽을 핀 설정

3. 기준 전압 설정

4. 해상도 설정(하드웨어적으로 10bit로 설정되어 있기 때문에 딸 설정할 필요가 없다.)

5. ADC변환 주기

이 있습니다.

 

관련된 레지스터는

ADMUX : 기준전압, 핀 설정

ADCSRA : ADC활성화, ADC변환 주기 설정


ADMUX

ADMUX의 내부 구조는 다음과 같습니다.

비트 이름 REFS1 REFS0 ADLAR 사용 못함 MUX3 MUX2 MUX1 MUX0
비트 번호 7 6 5 4 3 2 1 0
초기 값 0 0 0 0 0 0 0 0

7 ~ 6번 비트는 Voltage Reference 즉, 기준 전압 설정과 관련된 비트이고,

3 ~ 0번 비트는 아날로그 핀으로 사용할 핀을 선택하는 것과 관련된 비트입니다.

 


REFS1, S0 (7, 6)

REFS1 REFS0 설명
0 0 AREF핀에 걸린 전압을 기준으로 합니다.(5V)
0 1 AVCC핀에 걸린 전압을 기준으로 합니다.(5V)
1 0 사용 못함
1 1 내부 1.1v를 기준으로합니다.

(아두이노는 회로상으로 AREF핀과 AVCC핀이 5V와 연결되어 있습니다.)

 

보통의 센서들은 0v ~ 5v사이의 값을을 출력하기 때문에

저희는 AVCC를 기준 전압으로 설정하겠습니다.

 

MUX[3:0] (3 ~ 0)

MUX[3:0]은 사용할 핀을 설정(선택)하는 비트입니다.

Atmega328에는 8개의 ADC 기능이 있는 핀들이 있으며, MUX[3:0]값을 설정하여

ADC기능을 사용할 핀을 설정합니다.

MUX3..0 설명
0000 ADC0핀 사용
0001 ADC1핀 사용
0010 ADC2핀 사용
0011 ADC3핀 사용
0100 ADC4핀 사용
0101 ADC5핀 사용
0110 ADC핀 사용
0111 ADC7핀 사용

즉 ADC0번핀을 사용하고 싶을 때는 

0000으로

ADC5번 핀을 사용하고 싶을 때는

0101로 설정하면 됩니다.


저희는 AVCC를 기준전압으로,

ADC0번핀을 사용할 것이기 때문에

ADMUX = 0b001000000로 설정할 것입니다.

 

ADCSRA 레지스터

ADCSRA레지스터는 ADC기능 활성화, ADC변환 주기를 설정과 관련된 레지스터입니다.

내부 구조는 다음과 같습니다.

비트 이름 ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0
비트 번호 7 6 5 4 3 2 1 0
초기 값 0 0 0 0 0 0 0 0

우리가 관심을 가져야하는 비트는

ADEN(7) : ADC 활성화

ADSC(6) : ADC 변환 시작

ADIF(4) : ADC 변환 끝을 알려주는 비트

ADPS[2:0] (2..0) : ADC 변환 주기 설정


ADEN (7)

ADEN은 ADC를 활성화 시켜주는 비트입니다.

평소에는 ADC기능이 비활성화되어 있기 때문에 ADEN 비트를 1로 만들어 ADC 기능을 활성화 할 수 있습니다.

 

ADSC (6)

ADC 변환을 시작시킬 때 필요한 비트입니다.

 

ADC 변환은 비교적 오래걸리기 때문에(25클럭), MCU는 기본적으로 "ADC 변환 시작"을 알려줘야

변환을 시작합니다.

ADSC를 1로 만들면 변환을 시작

0으로 만들면 변환 중지를 의미합니다.

 

ADIF (4)

ADC 변환 끝났다는 것을 알려주는 비트입니다.

 

ADC 변환 중에 값을 읽으면 이상한 값이 들어오기 때문에

꼭 변환이 끝난 후에 값을 읽어야합니다.

 

ADIF 비트는 ADC 변환이 끝나면 1로 변하고

변환 중이면 0을 자동으로 변합니다.

 

즉, 저희는 ADIF가 1로 바뀔 때까지 기다렸다가 ADC 값을 읽어야합니다.

 

ADPS[2:0]

ADPS는 변환 속도를 설정해준다고 생각하시면 됩니다.

ADPS2 ADPS1 ADPS0 설명
0 0 0 8MHz
0 0 1 8MHz
0 1 0 4MHz
0 1 1 2MHz
1 0 0 1MHz
1 0 1 500KHz
1 1 0 250KHz
1 1 1 128KHz

ADC 변환을 빠르게 하고싶다면 8MHz를,

비교적 천천히 하고싶다면 500KHz정도를 선택하면 됩니다.


 

ADLAR 레지스터

ADLAR 레지스터는 ADC 변환이 끝난 후 값이 들어있는 레지스터입니다.

크기는 16bit이지만, 하위 10bit만 사용합니다.

 

하위 10bit만 사용하기 때문에 처음에 언급한 해상도는 10bit라고 할 수 있습니다.

 

 

 

 

 

 

 

예제 코드

기준 전압을 AVCC(5v)

변환 속도를 500KHz

ADC6번 핀을을 이용하는 코드는 다음과 같습니다.

void setup() {
   ADMUX = 0b01000101; //AVCC를 기준 전압으로, ADC5번 핀을 사용
   ADCSRA = 0b11000101; //ADC를 활성화 하고, 변환 시작하고, 속도는 500MHz로
   
   while(1) {
      if((ADCSRA & 0b00010000) == 1) break;  //4번 비트인 ADIF가 1이 되면 while을 부수고 나온다.
   }
   
   int value = ADLAR;
}



///계속해서 변환한다.


void loop() {
   ADCSRA = 0b11000101; //ADC를 활성화 하고, 변환 시작하고, 속도는 500MHz로
   
   while(1) {
      if((ADCSRA & 0b00010000) == 1) break;  //4번 비트인 ADIF가 1이 되면 while을 부수고 나온다.
   }
   
   int value = ADLAR;
}
반응형