Fogeaters, Light The World.

13

2016-Feb

[AVR] ADC (아두이노 analogread 사용)

작성자: title: MoonBlonix IP ADRESS: *.148.87.98 조회 수: 1703

아두이노에는 analogRead() 라는 편리한 함수가 있다.

입력받은 전압값을 1024등분 해서 나타내 주는 것.

가변저항 입력받을때도 그렇고 각종 세기신호를 가진 센서들을 사용할 때 반드시 필요하다.

이걸 AVR에서 구현하려면 ADC (Analog to Digital Converter) 를 사용해야 한다.


K-20160213-546950.png


출처 :: http://icbanq.tistory.com/entry/AVR-%EA%B8%B0%EC%B4%88-%EA%B0%95%EC%A2%8C-45-ATmega128%EC%9D%98-%EA%B8%B0%EB%8A%A5-%EB%B0%8F-%EC%A0%9C%EC%96%B4-5-%EC%95%84%EB%82%A0%EB%A1%9C%EA%B7%B8%EC%BB%A8%EB%B2%84%ED%84%B0


신경써서 볼만한, 좀 중요해보이는건 내가 굵게 표시해뒀다.


① A/D 컨버터의 특징

- 8채널/ 내부 아날로그 멀티플렉서 탑재
- 10비트 분해능
- 축차비교형(변환시간 수십us의 종속형A/D Convetor)
- 샘플/홀드회로 탑재로 인하여A/D 동작 동안 전압 고정화
- 단극성 아날로그 입력/ 차등입력 선택
- 차등입력에서10배~200배의 증폭A/D 가능
- 포트F는 아날로그 비교기 기능으로도 사용 가능
- 변환시간(65us~260us - 50kHz~200kHz)
 

② A/D 컨버터의 구성

- 범용PORTF의 특수 기능
  ▪ ADC0 ~ ADC7 : 8채널10비트A/D 컨버터의 아날로그 입력단자
- ADC 정확도 성능 향상을 위한 독립 전원 구성
  ▪ AVCC : Analog Supply Voltage(VCC의 전압의 ±0.3V 유지 해야함)
  ▪ AGND : Analog Ground (반드시GND와 연결)
  ▪ AREF : Analog Reference Voltage
- 입력 전압의 범위
  ▪ 일반 모드 입력전압의 범위(0V ~ Vref)
  ▪차동입력 모드 입력전압의 범위(-Vref~ Vref)
- Vref의 범위
  ▪ 전원전압VCC를 초과할 수 없다.(VREF=VGND~VCC, 내부기준전압2.56V)


④ A/D Convertor 잡음 제거 방법

: A/D Convertor의 경우에는 노이즈에 매우 민감하기 때문에ATmega128 내에서도AVCC, AREF, AGND와 같은ADC 전원 구성도 따로 하였으며 사용자 또한 몇 가지 사항을 주의하여 사용해야 한다.
-      AVCC = 독립적인 아날로그 회로 전원 단자
-      AREF = 기준 전원 입력 단자
-      AGND = 아날로그 회로 접지 단자
 
1) 아날로그 입력선은 최소한으로 짧게 하고 잡음의 영향이 없도록 회로를 구성한다.
2) 아날로그 전원단자 AVCC에 VCC를 인가할 때는LC필터를 거쳐 안정하 시킨다.
3) 아날로그 회로의 모든 접지는 AGND에 접지하여 한 포인트에서만 GND와 접속한다.
4) ADC 동작중에는 병렬I/O 포트의 논리상태를 스위칭 하지 않는다.
5) 잡음에 민감한 아날로그 소자의ADC의 경우에는 Adc Noise Reduction mode를 사용한다.
6) 잡음이 심하여 결과값의 변동이 심하면 디지털 필터를 사용하거나 평균치를 구하여 사용한다. 

K-20160213-549263.png



출처 :: http://embejide.tistory.com/17
K-20160213-553881.png

참고자료
http://tackbro.tistory.com/entry/AVR-%EA%B0%80%EB%B3%80%EC%A0%80%ED%95%AD%EC%9C%BC%EB%A1%9C-atmega-128%EC%97%90%EC%84%9C-ADC-%EC%82%AC%EC%9A%A9-%EC%98%88%EC%A0%9C
http://webnautes.tistory.com/678
http://blog.naver.com/ga1267/220111519302    << 참고추천!


  1. int adc_value=0,temp=0;
  2. float f_val=0;
  3.  
  4. void main(void)
  5. {
  6.     char str[30];
  7.    
  8.     ADMUX = 0b00000000;         // MUX(4-0):00000(ADC0 단극성 입력)
  9.     ADCSRA = 0b10000111;        // ADEN(7)-1,ADSC(6)-0,ADATE(5)-0(single conversion mode),ADIF(4)-0,ADIE(3)-0
  10.                                         // ADPS(2-0)-111(128분주:16MHz/128->125kHz) : 13cycle당 1회 샘플링 - 약 9.6kHz
  11.     SREG = 0x80;
  12.  
  13.     lcd_init(16);
  14.    
  15.     while(1)
  16.     {
  17.         ADCSRA = 0b11000111;                   // ADEN=1, ADSC = 1 변환 시작
  18.         while((ADCSRA & 0x10) == 0);        // ADIF=1이 될 때까지 대기
  19.         adc_value = (int)ADCL + ((int)ADCH << 8);    // A/D 변환값 읽기
  20.         f_val = (float)adc_value * 5.01024;    // 전압값으로 변환
  21.         temp = (int)(f_val*100);  
  22.         lcd_gotoxy(0,0);
  23.         sprintf(str,"Volt = %d.%d%d V",temp/100,(temp%100)/10,(temp%100)%10); lcd_puts(str);
  24.         delay_ms(100);
  25.     }
profile

title: MoonBlonix

2016.02.13 15:25
*.148.87.98

참고자료 :: http://newtc.co.kr/dpshop/bbs/board.php?bo_table=m52&wr_id=123007&sfl=&stx=&sst=wr_hit&sod=asc&sop=and&page=20


네, 저도 아무 문제 없이 잘 쓰고 있었습니다. 
그런데, 고객님의 말씀을 듣고 좀 더 찾아 봤습니다. 

고객님 말씀대로, AVCC는 무조건 VCC 쪽으로 안쓸 때는 그냥 다이렉트로, 쓸 때는 비드나 인덕터 같은 (LPF 필터) 하나 써서 연결하라고 되어 있네요.  하지만, 안해도 별 문제 없이 잘 동작했었습니다. 
그래도, 제품 만드시는 거라면, 나중에 꼭 연결해 주는 것이 좋겠습니다. 

또한, 참고적으로 ADC 할 때, AVCC, AREF, 내부 2.56V 이렇게 세 개 중 하나를 선택할 수 있습니다. 
이 때, AVCC는 필터 써서 VCC 에 연결되는 것이라 결국 VCC 전압과 거의같습니다. 
AREF는 최소 2.0V~AVCC-0.5V 까지 즉, AVCC가 5V 라면 2~4.5V까지 AREF를 쓸 수 있습니다. 
그런데, AVCC나 내부 2.56V를 ADC의 기준 전압으로 쓰려면, AREF는 N.C.(연결안함)으로 처리해야 합니다. 그렇지 않으면, 쇼트가 발생할 수 있다고 합니다.  

profile

title: MoonBlonix

2016.02.21 22:47
*.148.87.98

1. ADMUX

7번,6번 비트 : ADC 기준전압 설정

0 0 - 외부 AREF

0 1 - 외부 AVCC

1 1 - 내부 2.56V

 

4~0번 비트 : 입력 채널 선택

00000~00111 - 단극성 입력(ADC0~ADC7)

01001 - 차동 입력 (ADC1(+) – ADC0(-), 이득 x10)

 

 

01011 - 차동 입력 (ADC1(+) – ADC0(-), 이득 x200)

 

10000 - 차동 입력 (ADC0(+) – ADC1(-), 이득 x1)

 

 

4~0번 비트가 좀 복잡한데, 입력 핀 설정이라고 보시면 됩니다. 000이 ADC0, 001이 1, 010이 2...해서 111이 7이죠.

차동 입력은 두 핀 사이의 차이를 읽어들입니다. 알아서 이득 뻥튀기까지 시켜 주고요.

 

2. ADCSRA

7번비트 : ADC enable

1 - ADC 모듈 인에이블입니다. ADC 쓸때 1로 맞춰주시면 돼요

 

6번비트 : ADC start conversion

0 - stop

1 - start conversion

 

1로 셋 되면 ADC 변환을 시작합니다.

 

5번비트 : ADC Free running select

0 - single conversion mode

1 - free running mode

 

ADC변환 모드 설정입니다. 쪼끔있다가 설명할게요

 

4번비트 : ADC interrupt flag

single conversion mode에서 변환 다 끝나면 1로 자동으로 셋 됩니다.

 

3번비트 : ADC interrupt enable

1 - ADC interrupt enable

 

2번~0번비트 : 분주비 설정

000 - 2

001 - 2

010 - 4

011 - 8

100 - 16

101 - 32

110 - 64

111 - 128

 

..뭐 분주비 정도야

 

일단 ADC에도 두가지 모드가 있습니다.

 

single conversion mode와 free running mode인데요,

영어만 읽어봐도 대충 뉘앙스는 아시겠습니다만 한번만 하느냐 계속 변환하느냐의 차이입니다.

 

둘 다 ADCSRA 레지스터의 ADSC,ADEN(7번,6번비트)가 1로 셋 될때 변환이 시작됩니다.

 

1) single conversion mode

- 첫 변환에 25클럭이 요구된다네요

- AD변환 완료시 ADIF(4번비트)가 셋됩니다.

- 변환이 끝난 뒤 ADSC(7번비트)가 자동으로 클리어됩니다. 그래서 한번만 변환하고 끝나요.

 

2) free running mode

- 변환을 다 하면 자동으로 다음 변환을 시작합니다.

- ADSC 비트는 계속 high입니다.

 

요런 차이입니다.


 

3. ADCH,ADCL

변환 결과가 저장되는 10비트 레지스터입니다. 읽을 때 ADCL,H 순서로 읽지 않으면 쓰레기값이 들어갈 수가 있다네요..

List of Articles
번호 제목 글쓴이 날짜 조회 수
공지 [Web] 클라우드 IDE + 2 title: MoonBlonix 2017-06-25 15118
52 OP Amp - 연산 증폭기 title: MoonBlonix 2016-03-07 1741
51 [아두이노] RC용 ESC(변속기) 작동방법 title: MoonBlonix 2016-03-06 1763
50 [AVR/아두이노] 수광 센서 file title: MoonBlonix 2016-03-06 1759
49 [리눅스] 정적, 공유, 동적 라이브러리 사용 title: MoonBlonix 2016-03-05 1325
48 [C/C++] Makefile 만들기 title: MoonBlonix 2016-03-05 1778
47 [C/C++] OS 구분 전처리기 매크로 title: MoonBlonix 2016-03-05 1562
46 [C++ STL] std::unique_ptr + 1 title: MoonBlonix 2016-03-05 1755
45 [AVR] 퓨즈비트 옵션 file + 1 title: MoonBlonix 2016-03-04 1454
44 [AVR] 외부클럭, 리셋회로 설계 file + 1 title: MoonBlonix 2016-03-04 1739
43 [AVR] 소프트웨어 UART 통신(Software Serial) file + 1 title: MoonBlonix 2016-03-04 1739
42 [AVR/아두이노] PIR 인체감지 센서 file title: MoonBlonix 2016-03-03 1912
41 [리눅스] 파일관리 라이브러리 함수 title: MoonBlonix 2016-03-03 1650
40 [리눅스] 리눅스 커널 API 모음 title: MoonBlonix 2016-03-03 1950
39 [리눅스/윈도우/C/C++] 플러그인 시스템 구현 title: MoonBlonix 2016-03-03 1991
38 [라즈베리파이] UART 통신 file title: MoonBlonix 2016-02-25 1621
37 [리눅스] vi 편집기 명령어 title: MoonBlonix 2016-02-25 1520
36 [AVR] 서보모터 제어 file title: MoonBlonix 2016-02-21 1669
35 [AVR] 16MHz 클럭의 연산자별 연산속도 측정 title: MoonBlonix 2016-02-16 1687
34 [AVR] 입력받기 (풀업저항, 외부인터럽트) file + 1 title: MoonBlonix 2016-02-13 1995
» [AVR] ADC (아두이노 analogread 사용) file + 2 title: MoonBlonix 2016-02-13 1703