3. --33--20062006--0404--0101
Embedded AVR ProgrammingEmbedded 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(상위 데이터)를 저장
4. --44--20062006--0404--0101
Embedded AVR ProgrammingEmbedded AVR Programming
1-2 A/D 컨버터 관련 레지스터 1
⊙ A/D 컨버터 멀티플렉서 선택 레지스터(ADMUX)
- A/D 컨버터의 아날로그 입력 채널을 선택
- A/D 컨버터의 기준 전압 소스를 선택하거나 변환결과 레지스터의 데이터 저장 형식을 지정
REFS1 ~ 0 (Reference Selection Bit) : A/D 컨버터에서 사용하는 기준전압 선택
ADLAR (ADC Left Adjust Result) : A/D 컨버터 데이터 레지스터와 연관작동
ADMUX ( ADC Multiplexer Selection Register )
Value
$07($27)
BIT
00000000
MUX0MUX1MUX2MUX3MUX4ADLARREFS0REFS1
01234567
내부의 기준전압 2.56V 사용11
예약01
AVCC 단자로 입력된 전압을 사용10
AREF 단자로 입력된 전압을 사용00
기준전압REFS0REFS1
7. --77--20062006--0404--0101
Embedded AVR ProgrammingEmbedded AVR Programming
1-2 A/D 컨버터 관련 레지스터 2
⊙ A/D 컨버터 제어 및 상태 레지스터 A (ADCSRA)
- A/D 컨버터의 동작을 설정하거나 동작 상태를 표시하는 기능
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
설정
ADCSRA ( ADC Control and Status Register A )
Value
$06($26)
BIT
00000000
ADPS0ADPS1ADPS2ADIEADIFADFRADSCADEN
01234567
8. --88--20062006--0404--0101
Embedded AVR ProgrammingEmbedded AVR Programming
1-2 A/D 컨버터 관련 레지스터 2
⊙ A/D 컨버터 제어 및 상태 레지스터 A (ADCSRA)
- ADPS2~0(ADC Preslcaler Select Bit)
1
1
1
1
0
0
0
0
ADPS2
11128
0164
1032
0016
118
014
102
002
ADPS0ADPS1분주비
9. --99--20062006--0404--0101
Embedded AVR ProgrammingEmbedded AVR Programming
1-2 A/D 컨버터 관련 레지스터 3
⊙ A/D 컨버터 데이터 레지스터 (ADCH, ADCL)
- ADMUX 레지스터의 ADLAR = 0 인 경우
- ADMUX 레지스터의 ADLAR = 1 인 경우
단극성 입력 사용시 변환결과가 10비트 양의 정수로 표시된다(0~1023)
차동입력을 사용할 경우 변환 결과가 10비트 2의 보수로 표현(-512~+511)
반드시 ADCL(하위 데이터)를 먼저 읽어서 저장한 다음에 ADCH(상위 데이터)를 저장
BIT
ADCL
ADCH
BIT
01234567
ADC0ADC1ADC2ADC3ADC4ADC5ADC6ADC7
ADC8ADC9------
89101112131415
BIT
ADCL
ADCH
BIT
01234567
------ADC0ADC1
ADC2ADC3ADC4ADC5ADC6ADC7ADC8ADC9
89101112131415
10. --1010--20062006--0404--0101
Embedded AVR ProgrammingEmbedded AVR Programming
1-2 A/D 컨버터 관련 레지스터 3
⊙ A/D 컨버터 데이터 레지스터 (ADCH, ADCL)
- ADMUX 레지스터의 ADLAR = 0 인 경우
- ADMUX 레지스터의 ADLAR = 1 인 경우
단극성 입력 사용시 변환결과가 10비트 양의 정수로 표시된다(0~1023)
차동입력을 사용할 경우 변환 결과가 10비트 2의 보수로 표현(-512~+511)
반드시 ADCL(하위 데이터)를 먼저 읽어서 저장한 다음에 ADCH(상위 데이터)를 저장
BIT
ADCL
ADCH
BIT
01234567
ADC0ADC1ADC2ADC3ADC4ADC5ADC6ADC7
ADC8ADC9------
89101112131415
BIT
ADCL
ADCH
BIT
01234567
------ADC0ADC1
ADC2ADC3ADC4ADC5ADC6ADC7ADC8ADC9
89101112131415
11. --1111--20062006--0404--0101
Embedded AVR ProgrammingEmbedded 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 변환(차동입력)
그 이후의 일반적인 A/D 변환(단극성 입력)
ADEN=1 설정후 최초 변환
조 건
13~141.5~2.5
131.5
2513.5
A/D 변환 시간(사이클)샘플/홀드 시간(사이클)
13. --1313--20062006--0404--0101
Embedded AVR ProgrammingEmbedded 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비트의 변화를 발생하는 아날로그 값이 이상적인 경우에서 가장 크게 벗어나는 양
14. --1414--20062006--0404--0101
Embedded AVR ProgrammingEmbedded 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 변환 결과를 읽어들인 것을 평균 처리하여 사용
15. --1515--20062006--0404--0101
Embedded AVR ProgrammingEmbedded AVR Programming
1-7 A/D 컨버터 실습
☞ ADC0 에 저항을 연결한 후 전원 입력을 조정하며 시리얼통신을 통해 전압값 표시하는 프로그램
void main(void)
{
unsigned int adc_value,adc_dig1,adc_dig2,adc_dig3;
float adc_temp;
// Ports init
DDRB = 0xff; // output Port
DDRF = 0x00; // input Port
// USART init
UCSR0A=0x00;
UCSR0B=0x18;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x67;//(xtal - 16MHz)
//UBRR0L=0x33;//(xtal - 8MHz)
putsf(TITLE);
while(1)
{
다음 페이지
}
}
#include <mega128.h>
#include <stdio.h>
#include <delay.h>
#define ADC_START ADCSRA.6=1
#define ADC_CHECK ADCSRA.6=0
#define ADC_EOC ADCSRA.4
char flash TITLE[] = "₩n₩rM128KIT V2.0 ADC TEST1";
unsigned int adc_data[7]; // ADC Value variable
// ADC Single Mode
void ADC_Init(int channel)
{
ADMUX = channel;
ADCSRA = 0x86; //ADCEN, xtal/64
}
void adconversion(int ch)
{
ADC_Init(ch);
ADC_START; //ADC_START
while(!(ADC_EOC)); //ADC_Convertion
adc_data[ch]=ADCW; //ADCH, ADCL
}
16. --1616--20062006--0404--0101
Embedded AVR ProgrammingEmbedded 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);
}
}