Você está na página 1de 16

임베디드 마이크로프로세서

프로그래밍 실전

제작 : 네 로 테 크
강의 : 김 종 형
Embedded AVR Programming

ATMEGA128 A/D 컨버터

1. A/D 컨버터의 개요
2. A/D 컨버터 관련 레지스터
3. 클럭의 선택 및 동작 타이밍
4. A/D 변환 결과
5. A/D 변환 오차
6. 잡음 제거 방법
7. A/D 컨버터 실습

2006-
2006-04-
04-01 -2-
Embedded AVR Programming

1-1 A/D 컨버터의 개요

⊙ 아날로그 값을 디지털 값으로 변환

⊙ 8채널 10비트 분해능의 축차비교형(successive approximation) A/D 컨버터

⊙ A/D 컨버터는 한 개이며 채널을 바꿔가며 아날로그 신호를 입력 받음

⊙ 안정된 동작을 위한 MCU의 디지털 전원과 별도의 아날로그 회로 전원단자 AVCC를 가지며,
A/D 변환에 필요한 기준전압 AREF 단자 지원

⊙ A/D 컨버젼 설정 순서
- ADMUX로 A/D 신호를 입력받을 채널을 0에서 7까지 선택
- ADCSR로 컨버전 프리스케일러 설정, 컨버전 완료 인터럽트를 설정
- 전역 인터럽트 플래그를 ‘SET’하여 인터럽트 활성화
- 아날로그 디지털 변환 완료 인터럽트 처리 루틴을 구성한 후 ADCSR의 6번 비트를 셋하여
A/D 변환을 시작
- 변환 완료 플래그를 주기적으로 점검하거나 아날로그 디지털 컨버전 완료 인터럽트를
이용하여 A/D 컨버전 이후의 데이터 처리 루틴을 구성
- 반드시 ADCL(하위 데이터)를 먼저 읽어서 저장한 다음에 ADCH(상위 데이터)를 저장

2006-
2006-04-
04-01 -3-
Embedded AVR Programming

1-2 A/D 컨버터 관련 레지스터 1

⊙ A/D 컨버터 멀티플렉서 선택 레지스터(ADMUX)


- A/D 컨버터의 아날로그 입력 채널을 선택
- A/D 컨버터의 기준 전압 소스를 선택하거나 변환결과 레지스터의 데이터 저장 형식을 지정
ADMUX ( ADC Multiplexer Selection Register )
BIT 7 6 5 4 3 2 1 0
$07($27) REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0
Value 0 0 0 0 0 0 0 0

REFS1 ~ 0 (Reference Selection Bit) : A/D 컨버터에서 사용하는 기준전압 선택


REFS1 REFS0 기준전압
0 0 AREF 단자로 입력된 전압을 사용
0 1 AVCC 단자로 입력된 전압을 사용
1 0 예약
1 1 내부의 기준전압 2.56V 사용

ADLAR (ADC Left Adjust Result) : A/D 컨버터 데이터 레지스터와 연관작동

2006-
2006-04-
04-01 -4-
Embedded AVR Programming

1-2 A/D 컨버터 관련 레지스터 1

⊙ A/D 컨버터 멀티플렉서 선택 레지스터(ADMUX)

MUX4 ~ 0 (Analog Channel and Gain Selection Bit) : 아날로그 입력 채널 선택

단일 전압 입력

2006-
2006-04-
04-01 -5-
Embedded AVR Programming

1-2 A/D 컨버터 관련 레지스터 1

⊙ A/D 컨버터 멀티플렉서 선택 레지스터(ADMUX)

2006-
2006-04-
04-01 -6-
Embedded AVR Programming

1-2 A/D 컨버터 관련 레지스터 2

⊙ A/D 컨버터 제어 및 상태 레지스터 A (ADCSRA)

- A/D 컨버터의 동작을 설정하거나 동작 상태를 표시하는 기능


ADCSRA ( ADC Control and Status Register A )
BIT 7 6 5 4 3 2 1 0
$06($26) ADEN ADSC ADFR ADIF ADIE ADPS2 ADPS1 ADPS0
Value 0 0 0 0 0 0 0 0

ADEN (ADC Enable) : A/D 컨버터 작동유무 지정


ADSC (ADC Start Coversion) : 1로 설정 시 A/D 컨버터 변환 시작
ADFR (ADC Free Running Select) : 프리런닝 모드 설정, ADSC = 1 로 설정하면 한번

변환을 시작하고 나면 그 다음부터는 자동 반복적으로 변환동작을 수행한
다.
ADIF (ADC Interrupt Flag) : A/D 변환이 완료되어 A/D 컨버터 데이터 레지스터 값이
갱신되고 나면 이것이 1로 셋트되면서 변환완료 인터럽트를 요청
ADIE (ADC Interrupt Enable) : A/D 변환완료 인터럽트를 개별적으로 허용
ADPS2~0(ADC Preslcaler Select Bit) : A/D 컨버터의 변환시간 설정을 위한 Prescaler
설정
2006-
2006-04-
04-01 -7-
Embedded AVR Programming

1-2 A/D 컨버터 관련 레지스터 2

⊙ A/D 컨버터 제어 및 상태 레지스터 A (ADCSRA)

- ADPS2~0(ADC Preslcaler Select Bit)


분주비 ADPS2 ADPS1 ADPS0

2 0 0 0

2 0 0 1

4 0 1 0

8 0 1 1

16 1 0 0

32 1 0 1

64 1 1 0

128 1 1 1

2006-
2006-04-
04-01 -8-
Embedded AVR Programming

1-2 A/D 컨버터 관련 레지스터 3

⊙ A/D 컨버터 데이터 레지스터 (ADCH, ADCL)

- ADMUX 레지스터의 ADLAR = 0 인 경우


BIT 15 14 13 12 11 10 9 8
ADCH - - - - - - ADC9 ADC8
ADCL ADC7 ADC6 ADC5 ADC4 ADC3 ADC2 ADC1 ADC0
BIT 7 6 5 4 3 2 1 0

- ADMUX 레지스터의 ADLAR = 1 인 경우


BIT 15 14 13 12 11 10 9 8
ADCH ADC9 ADC8 ADC7 ADC6 ADC5 ADC4 ADC3 ADC2
ADCL ADC1 ADC0 - - - - - -
BIT 7 6 5 4 3 2 1 0

단극성 입력 사용시 변환결과가 10비트 양의 정수로 표시된다(0~1023)


차동입력을 사용할 경우 변환 결과가 10비트 2의 보수로 표현(-512~+511)
반드시 ADCL(하위 데이터)를 먼저 읽어서 저장한 다음에 ADCH(상위 데이터)를 저장

2006-
2006-04-
04-01 -9-
Embedded AVR Programming

1-2 A/D 컨버터 관련 레지스터 3

⊙ A/D 컨버터 데이터 레지스터 (ADCH, ADCL)

- ADMUX 레지스터의 ADLAR = 0 인 경우


BIT 15 14 13 12 11 10 9 8
ADCH - - - - - - ADC9 ADC8
ADCL ADC7 ADC6 ADC5 ADC4 ADC3 ADC2 ADC1 ADC0
BIT 7 6 5 4 3 2 1 0

- ADMUX 레지스터의 ADLAR = 1 인 경우


BIT 15 14 13 12 11 10 9 8
ADCH ADC9 ADC8 ADC7 ADC6 ADC5 ADC4 ADC3 ADC2
ADCL ADC1 ADC0 - - - - - -
BIT 7 6 5 4 3 2 1 0

단극성 입력 사용시 변환결과가 10비트 양의 정수로 표시된다(0~1023)


차동입력을 사용할 경우 변환 결과가 10비트 2의 보수로 표현(-512~+511)
반드시 ADCL(하위 데이터)를 먼저 읽어서 저장한 다음에 ADCH(상위 데이터)를 저장

2006-
2006-04-
04-01 -10-
10-
Embedded AVR Programming

1-3 클럭의 선택 및 동작 타이밍

⊙ 클럭의 선택
- 10비트 분해능으로 정상적인 동작을 위해서는 50kHz~200kHz 범위의 클럭 사용
- ADCSRA 레지스터의 ADPS2~0 비트에 의하여 2,4,8,16,32,64,128 중의 1가지로 선택
- 프리스케일러는 ADCSRA레지스터에서 ADEN=1로 설정한 경우에만 동작

⊙ A/D 컨버터의 동작 시간
조 건 샘플/홀드 시간(사이클) A/D 변환 시간(사이클)
ADEN=1 설정후 최초 변환 13.5 25
그 이후의 일반적인 A/D 변환(단극성 입력) 1.5 13
그 이후의 일반적인 A/D 변환(차동입력) 1.5~2.5 13~14

2006-
2006-04-
04-01 -11-
11-
Embedded AVR Programming

1-4 A/D 변환 결과

⊙ 단극성 입력 채널의 변환 결과
- 변환 결과는 ADCH 및 ADCL에 저장

⊙ 차동입력 채널의 변환 결과

2006-
2006-04-
04-01 -12-
12-
Embedded AVR Programming

1-5 A/D 변환 오차

⊙ 양자화 오차(Quantization error)


- 1비트의 디지털 값의 변화를 일으키는 아날로그 값의 한계
항상 ±0.5LSB로서 일정하며 A/D 컨버터가 가지는 불가피한 오차(분해능 높은 A/D 사용)

⊙ 오프셋 오차(Offset error)


- 이상적인 디지털 값에서 일정한 양만큼 벗어나는 오차
(일정치를 빼거나 더함으로써 S/W적으로 보정)

⊙ 이득 오차(Gain error)
- 이상적인 값에서 일정한 비율만큼 벗어나는 것인데, 이는 디지털 값이 최대치인 경우의
아날로그 입력과 최대 아날로그 입력인 VREF의 차이로 표현
(디지털 값에서 일정치를 곱하거나 나눔으로써 S/W적으로 쉽게 보정)

⊙ 비선형 오차(INL ; integral non-linearity error)


- 오프셋 오차나 이득 오차를 보상한 후에 디지털 값이 이상적인 값에서 가장 크게 벗어남
(A/D 컨버터의 사용자가 보정하기 어려움)

⊙ 차동 비선형 오차(DNL ; differential non-linearity error)


- 1비트의 변화를 발생하는 아날로그 값이 이상적인 경우에서 가장 크게 벗어나는 양

2006-
2006-04-
04-01 -13-
13-
Embedded AVR Programming

1-6 잡음 제거 방법

⊙ 아날로그 입력 신호선은 최소한으로 짧게 설계

⊙ AVCC는 디지털 전원 VCC를 LC 필터로 안정화시켜 인가

⊙ A/D 컨버터의 근처에서는 접지 단자 GND와 디지털 전원 VCC 사이에 바이패스 콘덴서를 담

⊙ A/D 변환이 수행되는 동안에는 병렬 I/O포트의 논리상태를 스위칭하지 않는 것이 좋음

⊙ 잡음에 대하여 극도의 안정적인 A/D 변환이 필요한 경우에는 Idle mode(ADC Noise
Reduction Mode)에서 A/D변환을 수행하는 것도 권장

⊙ 디지털 필터를 사용하거나 여러 번 A/D 변환 결과를 읽어들인 것을 평균 처리하여 사용

2006-
2006-04-
04-01 -14-
14-
Embedded AVR Programming

1-7 A/D 컨버터 실습

☞ ADC0 에 저항을 연결한 후 전원 입력을 조정하며 시리얼통신을 통해 전압값 표시하는 프로그램


#include <mega128.h> void main(void)
#include <stdio.h> {
#include <delay.h> unsigned int adc_value,adc_dig1,adc_dig2,adc_dig3;
float adc_temp;
#define ADC_START ADCSRA.6=1
#define ADC_CHECK ADCSRA.6=0 // Ports init
#define ADC_EOC ADCSRA.4 DDRB = 0xff; // output Port
DDRF = 0x00; // input Port
char flash TITLE[] = "₩n₩rM128KIT V2.0 ADC TEST1";
unsigned int adc_data[7]; // ADC Value variable // USART init
UCSR0A=0x00;
// ADC Single Mode UCSR0B=0x18;
void ADC_Init(int channel) UCSR0C=0x06;
{ UBRR0H=0x00;
ADMUX = channel; UBRR0L=0x67;//(xtal - 16MHz)
ADCSRA = 0x86; //ADCEN, xtal/64 //UBRR0L=0x33;//(xtal - 8MHz)
}
putsf(TITLE);
void adconversion(int ch)
{ while(1)
ADC_Init(ch); {
ADC_START; //ADC_START 다음 페이지
while(!(ADC_EOC)); //ADC_Convertion }
adc_data[ch]=ADCW; //ADCH, ADCL }
}

2006-
2006-04-
04-01 -15-
15-
Embedded AVR Programming

1-7 A/D 컨버터 실습 1

☞ ADC0 에 저항을 연결한 후 전원 입력을 조정하며 시리얼통신을 통해 전압값 표시하는 프로그램


while(1)
{
adconversion(0);
printf("₩n₩rad ch0 value : %02d",adc_data[0]);

adc_temp = (((float)(adc_data[0]) / 1024)*500); // Vref가 5V이며 소수점 2째자리까지 표현하기 위해 100을 곱해줌
adc_value = (unsigned int)adc_temp;

adc_dig1 = adc_value / 100; // 정수값


adc_dig2 = (adc_value % 100) / 10; // 소수점 첫째자리
adc_dig3 = adc_value % 10; // 소수점 둘째자리
//adc_dig3 = (adc_value % 100) %10; // 소수점 둘째자리

printf("₩n₩rad ch0 voltage : %d.%d%dV",adc_dig1,adc_dig2,adc_dig3); // 입력 전압값을 소수점 둘째자리까지 표현

delay_ms(2000);
}
}

2006-
2006-04-
04-01 -16-
16-

Você também pode gostar