본문 바로가기
임베디드

[임베디드] ADC 사용하기

by 코딩히어로 2022. 8. 25.
728x90

1


이번에 콩나물 공장 시스템을 설계하면서 온도 센서를 485 센서로 사용했지만 거리가 조금만

멀어지면 센서에 노이즈로 인해 값이 많이 튀는 증상이 생겨서 4-20m라는 조금은 생소한

ADC값을 이용해서 센서를 측정하는 방식으로 변경하게 되었습니다

이번 프로젝트에서 사용된 마이크로칩은 18F66K80으로 64핀을 사용하였습니다

 

 

ADC 알고리즘


ADC 설정을 할 때 몇비트의 ADC를 사용할 것인지 선택하게 되는데 저의 경우에는

12비트 ADC를 사용했습니다 12비트를 계산하면 0~4096까지의 범위를 측정할 수 있습니다

센서는 1v ~ 5v 까지의 범위를 가지는 온도센서로 0℃가 1v이기 때문에 1v이하의 ADC값을 보정해야

1v ~ 5v 사이를 측정했을 때 0℃ ~ 100℃까지의 값을 구할수가 있습니다

 

즉 4096의 범위에서 1v의 값을 버리도록 계산을 해야 하는데 4096의 1v당 할당되는 값을 먼저 계산합니다

4096 / 5 = 819.2

즉 1v당 ADC값은 819.2가 되고 전체 4096에서 819.2를 제외한 값이 1v ~ 5v의 범위가 됩니다

 

그럼 온도센서의 값이 0℃ ~ 100℃의 값을 가지고 ADC는 1v를 제외한 (4096 - 819) 값인 3277이므로

1℃당 값은 3277 / 100이 되기 때문에 1℃ = 32.7이라는 값이 됩니다

 

그럼 만약 여기에서 약 2v가 살짝 넘는 ADC값인 1899의 ADC값이 읽혔다고 한다면 다음과 같이 계산합니다

1899 - 819 = 1080 (측정된 값에서 기준값 1v인 819를 뺀값)

1080 / 32 (기준값을 가지는 ADC값에서 1℃당 ADC값을 나눈 값)즉 33.7℃라는 결과를 얻게 됩니다

 

측정하고자 하는 센서의 범위에 따라 위 계산식을 사용해서 계산해주기만 하면 됩니다예를 들어 0 ~ 1000까지 측정하는 센서의 경우에는 측정 센서 값 1당 값은 3.2가 됩니다

 

 

main.h


#byte ADCON0   = 0xFC2					// ADC 설정 레지스터
#bit  GO_DONE  = ADCON0.1				// ADC 변환 상태
#bit  ADON     = ADCON0.0				// ADC 변환 시작

#byte ADCON1   = 0xFC1
#bit  VNCFG    = ADCON1.3

#byte ADCON2   = 0xFC0
#bit  ADFM     = ADCON2.7

#byte ADRESL   = 0xFC3					// ADC lsb
#byte ADRESH   = 0xFC4					// ADC msb

#byte ANCON0   = 0xF5D					// ADC Analog pin 설정
#byte ANCON1   = 0xF5C					// ADC Analog pin 설정

 

 

init.c


trisa = 0x0f;

ANCON0=0x0f;
ANCON1=0x00;

ADCON0=0x02;
ADCON1=0x00;
ADCON2=0xBE;
ADFM=0;                                   // A/D bit result right shift

ADON=1;

ADC 포트는 입력으로 설정하는 것을 기본으로 합니다

그리고 해당 포트를 디지털 핀이 아닌 아날로그 핀으로 설정해야 하는데

ANCON0에서 1로 설정하면 아날로그 핀으로 셋 됩니다

 

ADC.c


ADCON0=0x02;
ADON=1;
GO_DONE=1;
while(GO_DONE);
aTodValue.bdata.lsb = ADRESL;
aTodValue.bdata.msb = ADRESH;
aTodValue.wdata = aTodValue.wdata>>4;
ADON=0;

ADCON0에 0x02로 ADC 채널을 설정합니다

그런 다음 ADON=1로 ADC 변환을 시작하고 GO_DONE이 0이 될 때까지 대기합니다.

ADC 변환이 완료되면 GO_DONE 비트가 0으로 셋 되고 ADRESL과 ADRESH를 읽습니다

12비트 ADC를 사용했기 때문에 8비트씩 두 번 읽은 16비트의 값을 오른쪽으로 4비트 시프트 합니다

마지막으로 GOON=0으로 ADC 변환을 마무리합니다

728x90
반응형

'임베디드' 카테고리의 다른 글

[임베디드] Watchdog Timer란?  (0) 2023.10.27
[임베디드] CAN 통신 Mask & Filter Bit  (6) 2022.03.25
[임베디드] PLL이란?  (4) 2022.01.10
[임베디드] ADC란?  (21) 2022.01.06
[임베디드] CAN 통신이란?  (0) 2021.12.27

댓글