13
2016-Feb
[AVR] ADC (아두이노 analogread 사용)
작성자: Blonix
IP ADRESS: *.148.87.98 조회 수: 1703
아두이노에는 analogRead() 라는 편리한 함수가 있다.
입력받은 전압값을 1024등분 해서 나타내 주는 것.
가변저항 입력받을때도 그렇고 각종 세기신호를 가진 센서들을 사용할 때 반드시 필요하다.
이걸 AVR에서 구현하려면 ADC (Analog to Digital Converter) 를 사용해야 한다.
출처 :: 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
신경써서 볼만한, 좀 중요해보이는건 내가 굵게 표시해뒀다.


- int adc_value=0,temp=0;
- float f_val=0;
- void main(void)
- {
- char str[30];
- ADMUX = 0b00000000; // MUX(4-0):00000(ADC0 단극성 입력)
- ADCSRA = 0b10000111; // ADEN(7)-1,ADSC(6)-0,ADATE(5)-0(single conversion mode),ADIF(4)-0,ADIE(3)-0
- // ADPS(2-0)-111(128분주:16MHz/128->125kHz) : 13cycle당 1회 샘플링 - 약 9.6kHz
- SREG = 0x80;
- lcd_init(16);
- while(1)
- {
- ADCSRA = 0b11000111; // ADEN=1, ADSC = 1 변환 시작
- while((ADCSRA & 0x10) == 0); // ADIF=1이 될 때까지 대기
- adc_value = (int)ADCL + ((int)ADCH << 8); // A/D 변환값 읽기
- f_val = (float)adc_value * 5.0/ 1024; // 전압값으로 변환
- temp = (int)(f_val*100);
- lcd_gotoxy(0,0);
- delay_ms(100);
- }
- }
[출처] ATmega128 강좌 - ADC - 네로라르크님께 바칩니닸|작성자 에몽이
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 순서로 읽지 않으면 쓰레기값이 들어갈 수가 있다네요..
[출처] ATmega128 강좌 - ADC - 네로라르크님께 바칩니닸|작성자 에몽이
참고자료 :: 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.(연결안함)으로 처리해야 합니다. 그렇지 않으면, 쇼트가 발생할 수 있다고 합니다.