본문 바로가기

디지털회로/AT91SAM7S256

A/C 컨버터(ADC)


AT91SAM7S256은 8채널 10비트 또는 8비트 분해능(정밀한 높이측정)의 축차비교형(변환이 끝남) A/D 컨터버를 가지고 있다.

8bit와 10bit 비교
 

 

8bit

10bit

번지수

(0~255)

(0~1023)

장  점

256까지 세니까 빠르다

1024까지 있어 세밀하다

전  압

3.3/256 = 0.01289.. => 12.89

3.3/1024 = 0.00322.. => 3.22




이들 8채널의 아날로그 입력신호 중 AD0~AD3은 병렬 I/O포트와 겸용으로 사용하고, AD4~AD7은 전용이다.



A/D 변환이 가능한 아날로그 입력전압의 범위는 0~ADVREF(AD:아날로그디지털, V:전압, REF:기준전압)이며, 변환은 10비트모드 또는 8비트모드를 사용할 수 있다.

A/D 변환된 디지털 데이터는 각 채널에 내장된 전용의 데이터 레지스터 ADC_CDRx(x->0~7번까지)에 저장되며 모든채널에 공통인 데이터 레지스터 ADC_LCDR(1개)에도 저장된다.

A/D 컨버터에서 사용하는 클록의 주파수는 ADC_MR 레지스터의 PRESCAL 필드에 의하여 MCK/2/(PRESCAL+1)로 결정되므로 MCK/2~MCK/128의 범위가 된다. 
 
10비트 분해능을 사용할 때는 A/D 클록으로 5MHz(10bit최대) 이하를 사용해야 하며, 8비트 분해능을 사용할 때는 A/D 클록으로 8MHz(8bit최대) 이하를 사용해야 한다.

ADC클록 주파수 = MCK/(PRESCAL+1)*2

예) 10비트일때 ADC클록은 5이하여야 하니
5 = 48/(x+1)*2        x = 5이면 ADC클록이 4가 되므로 만족한다.

그래서 ADC_MR = (5<<PRESCAL) 이렇게 나타낸다.

빛센서를 이용해 결과를 알아보기



ADC.h

#ifndef __ADC_H__
#define __ADC_H__

//#include "pio.h"
#include "pmc.h"
#include "lcd.h"

#define ADC_CR    (*((volatile unsigned int *)0xFFFD8000))
//제어 레지스터
#define ADC_MR    (*((volatile unsigned int *)0xFFFD8004)) 
//모드 레지스터
#define ADC_SR    (*((volatile unsigned int *)0xFFFD801C))
//상태 레지스터
#define ADC_CHER  (*((volatile unsigned int *)0xFFFD8010))  
//채널허용 레지스터
#define ADC_LCDR  (*((volatile unsigned int *)0xFFFD8020))  
//모든채널 공통 데이터 레지스터
#define ADC_CDR    (((volatile unsigned int *)0xFFFD8030))  
//전용의 데이터 레지스터의 주소, 배열로 해당채널을 정할 거라 *를 빼버림

#define ADC       4       //PID4 
#define START     1       //A/D 변환시작
#define SWRST     0       //리셋
#define ADC_CDR7  7       //7번핀 
#define PRESCAL   8       //8번핀
#define TRGEN     0       //트리거 활성핀
#define TRGSEL    1       //트리거 선택
#define LOWRES    4       //분해능 설정(0 = 10비트,1 = 8비트)
#define SLEEP     5       //슬립모드(0 = 정상모드,1 = 슬립모드)

#define EOC7    7

void ADC_init(void);
unsigned char * ADC_run7();

#endif  //__ADC_H__

ADC.c

#include "adc.h"

void ADC_init(void)
{
  PMC_PCER = 1<<ADC;   //주변장치 클록 허용 레지스터(1<<4);,ADC => PID4
  
  ADC_CR = 1<<SWRST;      //제어 레지스터에 리셋
  ADC_CHER = 1<<ADC_CDR7;  //7번핀을 활성화
  ADC_MR = (5<<PRESCAL) |(0<<LOWRES);  
  //MCK가 5MHz이하 (4로 게산 )  4 = 48(5+1)*2 그래서 5를 넣음

  return;
}

unsigned char * ADC_run7()
{
  static unsigned int uiResult;
  static unsigned char ucBuf[] = "0000\n\r";      //0~1023

  ADC_CR = 1<<START;  //제어 레지스터에 스타트(전압이 들어왔다는 가정하에)

  // 컨버팅완료까지 대기코드가 들어가야 한다.
(0이면 7번채널 금지거나 A/D변환이 미완료)
  while(0==(ADC_SR&(1<<EOC7)));        //폴링 (A/D변환 중...)
  
  uiResult = ADC_CDR[7];  //ADC_CDR 주소를 배열로 (7번채널에 새로운 A/D변환이 된 데이타 레지스터에 값을 결과로 저장)
  
  ucBuf[0= '0'+(uiResult%10000)/1000;  //1000단위
  ucBuf[1= '0'+(uiResult%1000)/100;    //100단위
  ucBuf[2= '0'+(uiResult%100)/10;    //10단위
  ucBuf[3= '0'+(uiResult%10);      // 1단위

  LCD_Inst(LCD_CD);  //lcd화면 클리어
    
  LCD_Data('0'+(uiResult%10000)/1000);
  LCD_Data('0'+(uiResult%1000)/100);
  LCD_Data('0'+(uiResult%100)/10);
  LCD_Data('0'+(uiResult%10));

  return ucBuf;
}


빛센서에 휴대폰에 있는 카메라 불빛으로 환하게 비춰보니 1023이란 숫자가 찍혔다.

'디지털회로 > AT91SAM7S256' 카테고리의 다른 글

SPI - 직렬통신 포트  (0) 2011.09.26
PWM 제어기  (0) 2011.09.22
초음파 SRF-05 실행시키기  (0) 2011.09.16
오늘 바꾼 TIMER / main 외 ULTRA  (0) 2011.09.09
타이머카운터  (0) 2011.09.08