ADC(Analog-to-Digital Converter) 사용하기 - 4
ADC에 전원공급을 했으니 이제 타이밍 다이어그램을 참고하여 ADC를 이용하여
LCD에 출력할 수 있는 ADC_run()함수를 구현해보자.
위의 다이어그램은 특정 레지스터에 특정 값이 들어왔을 때 ADC_SR레지스터의 EOCx비트와 DRDY비트가 변화하는 것을 보여준다.
좌측과 우측의 ①, ②, ③은 모두 동일하나 ④에서 다른 모습을 보여준다.
① ADC_CR의 START 비트를 1로 설정하면 ADC에서 값을 읽어오는 ② Conversion Time이 시작된다.
Conversion Time이 완료되면 ③에서 처럼 ADC_SR레지스터의 EOCx와 DRDY비트가 HIGH로 설정되는데
④ ADC_CDRx 레지스터를 읽을 경우 EOCx의 값은 LOW로 내려가지만 DRDY의 값은 변화가 없다.
하지만 ④에서 처럼 ADC_LCDR의 값을 읽어올 경우 EOCx와 DRDY 모두 LOW로 바뀌는 것을 알 수 있다.
이제 각 레지스터들의 기능을 알아본다.
위의 표에서 타이밍 다이어그램에서 보았던 레지스터들의 기능을 알 수 있다.
ADC_CR : 컨트롤 레지스터
ADC_SR : 상태 표시 레지스터
ADC_LCDR : 마지막에 값이 변한 핀을 알려주는 레지스터
ADC_CDR0~7 : 8개의 ADC 핀을 각각 지정한 레지스터
ADC_CR은 32비트중 첫 두비트만 사용하는 것을 알 수 있다.
0번 비트는 리셋을 해주는 비트고
1번 비트는 1로 세팅했을 때 아날로그-디지털 변환 시작을 지시한다.
#define ADC_CR (*((volatile unsigned int *)0xFFFD8000)) // Control Register :546P
#define START 1
ADC_CR = 1 << START;
위 코드는 ADC_CR레지스터의 스타트 비트인 1번째 비트에 1을 대입해주는 코드이다
ADC_SR 레지스터는 이름대로 상태를 표시하는 레지스터인데
그 중 EOC0~7 비트는 0~7번핀의 아날로그-디지털 변환이 끝났음을 알려주고
DRDY비트는 ADC_SR의 16번째 비트이며, 0~7번핀중 하나라도 값이 변했을 경우 사용가능함을 알리는 비트이다.
DRDY비트는 ADC_LCDR이 데이터를 읽어오면 값이 다시 초기화 된다.
#define ADC_SR (*((volatile unsigned int *)0xFFFD801C)) // Status Register
#define DRDY 16
#define EOC0 0
#define EOC1 1
#define EOC2 2
#define EOC3 3
#define EOC4 4
#define EOC5 5
#define EOC6 6
#define EOC7 7
while(0 == ADC_SR & (1 << DRDY)); // 값이 바뀔때 까지 delay 목적: conversion time 대기
위 코드는 ADC_SR의 DRDY비트가 1로 바뀔때 까지,
즉 컨버전 타임이 끝날때 까지 대기해주는 코드이다.
ADC_LCDR은 아날로그-디지털 변환이 끝난 데이터가 이 레지스터에 저장되며
다시 아날로그-디지털 변환이 처리될 때 까지 그 데이터가 남아있게 된다.
만약 ADC_LCDR에서 데이터를 읽어올 경우 ADC_SR레지스터의 DRDY비트와 EOCx비트가 모두 Low로 클리어된다.
#define ADC_LCDR (*((volatile unsigned int *)0xFFFD8020)) // Last Converted Data Register
return (ADC_LCDR & 0x3FF);
위의 코드는 LCDR레지스터의 값에 0~9비트이상을 0으로 클리어 해준 후
그 값을 리턴해주는 코드이다.
즉, 0000 0000 0000 0000 0000 0011 1111 1111로 AND연산을 해주므로써
0~9비트까지는 원래의 값을 보존하고 그 이상의 비트는 모두 0으로 클리어 해준다.
오동작을 방지하기 위한 코드이다.
ADC_CDR0~7는 0~7번핀 중 해당 핀에 아날로그-디지털 컨버팅이 끝난 데이터가 입력되는 레지스터다.
ADC_CDR0~7 레지스터에서 데이터를 읽어올 경우 ADC_SR레지스터의 EOCx비트만 Low로 클리어 된다.
다음은 define문을 이용하여 레지스터와 비트의 값을 지정해 놓은 adc.h 헤더파일이다.
#ifndef _ADC_H_ |
아래 함수는 타이밍 다이어그램 대로 작성하여
ADC를 통해 센서의 값을 읽어 올 수 있는 ADC_run()함수의 본체이다.
unsigned int ADC_run() |