실험에서는 AVCC 를 단순히 5V에 연결하고 AREF는 연결을 하지 않았으며 [그림 1] 에 A/D변환기의 전원부를 도시하였다. 데이터쉬트에 의하면 AVCC는 LC필터를 이용하여 안정화시킬 것을 권장하고 있다.(여기에서는 사용하지 않음) 또한 앞으로의 실습에서는 기준전압을 AVCC로 사용할 것이기 때문에 AREF핀은 연결하지 않았다. 데이터쉬트에서는 AREF핀을 사용하지 않을 경우 GND와 0.1uF의 커패시터를 연결할 것을 권하고 있으나 이 역시 A/D변환 회로부에 들어가게 될지도 모르는 전원 잡음을 조금이라도 줄이기 위한 방편이며, 연결하지 않아도 실습하는데 있어서 크게 문제될 것은 없다.

[그림 1] 그림 8.3.1 데이터쉬트의 권장 회로(좌)와 실험키트의 회로(우)


Cds광센서를 이용한 ADC 실험

 여기에서는 Cds광센서를 이용하여 A/D변환 실험을 수행해 보겠다. 설명의 편의를 위해 회로도를 [그림2]에 도시하였다.


[그림 2] CdS 셀 회로도


Cds는 빛의 양에 따라 저항값이 반비례하는 가변 저항으로 보면 된다. 따라서 내부 풀업 저항을 연결한다면 광량에 따라서 PC4핀의 전압값이 달라질 것이다. 극단적인 경우로 Cds의 저항이 무한대라면(빛이 하나도 없는 경우) PC4핀의 전압은 5V일 것이다. 반대로 저항이 0이라면 (빛이 매우 많은 경우이다) PC4핀의 전압은 0V일 것이고 그 중간의 경우는 광량에 따라서 PC4핀의 전압값이 반비례할 것이다. 즉, 광량이 많으면 PC4핀의 전압은 낮아지고, 광량이 적어질수록 전압은 높아진다.


 이러한 특성을 이용하여 밝으면 LED가 꺼지고 어두워질수록 LED가 더 많이 켜지는 프로그램을 작성해 보자.


#define F_CPU 16000000
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "Am8USBasp.h"
int main(void) {
   uint uiA;
   uchar ucB;
   InitAM8();
   ADMUX = 0b01000100; // AVCC, right-align, ADC4
   ADCSRA = 0b10100111; // free running, no interrupt, Div128
   sbi(ADCSRA, ADSC); // start conversion
   while(1) {
       uiA = ADC;// read ADC register value
       if (uiA < 256)
           ucB = 0b00000000;
       else if (uiA < 384)
           ucB = 0b00000011;
       else if (uiA < 512)
           ucB = 0b00001111;
       else
           ucB = 0b11111111;
       LED(ucB);
   }
}


이 예제에서는 기준전압을 AVCC로, 변환 데이터 저장 방식은 우측 정렬로 그리고 핀은 ADC4번 핀으로 선택하여 ADMUX레지스터에 설정하였다. 그리고 인터럽트는 사용하지 않고 연속 변환 모드와 128분주된 클럭으로 선택하여 ADCSRA레지스터에 설정하였다. 그리고 ADCSRA레지스터의 ADSC비트를 세트시켜서 변환을 시작시켰으며 그 이후에는 자동으로 A/D변환을 수행하여 ADC레지스터의 값이 실시간으로 갱신이 된다. 따라서 while(1) 반복문 안에는 단순히 ADC레지스터 값을 읽어서 그것의 범위에 따라서 LED의 숫자를 조절하는 프로그램이 작성되어 있다. A/D변환값이 10비트이기 때문에 그 값의 범위는 0~1023일 것이다.

 

 이 프로그램을 컴파일 한 후에 실행시켜서 만약 밝은 환경이라면 LED가 하나도 안 켜지지만 손바닥으로 센서를 많이 가릴수록 LED가 더 많이 켜지는 것을 확인할 수 있을 것이다.



Posted by 살레시오
,