HBE-MCU-All in One 에서 ADC 모듈을 이용하면

햇빛 밝기를 측정할 수 있습니다. 광전압이라는 단어가 없긴 하지만,

햇빛 밝기가 높을 수록 전압이 세지므로 광전압이라고 합시다.


ADC 모듈을 손으로 가리면 광전압의 세기가 줄어들며, 다시 손을 치우면 광전압의 세기가 원래대로 돌아옵니다.


일반적인 환경에서는 ADC모듈로 측정된 전압이 약 2V 후반대 정도이며,

손으로 완전 햇빛을 가린 경우 1V 아래로 떨어지게 됩니다.


다음 소스 코드의 실행파일은 ADC모듈을 손으로 가리는 경우 Warning 이 뜨도록 합니다.



#include <avr/io.h> #include <avr/interrupt.h> #define TRUE 1 #define FALSE 0 #define LCD_CTRL PORTG #define LCD_DATA PORTA #define LCD_RS 0x01 // PG0 #define LCD_RW 0x02 // PG1 #define LCD_E 0x04 // PG2 volatile unsigned int AdData = 0; volatile unsigned int t2_100 = 0; volatile unsigned int count = 0; void delay(unsigned long x) { while(x--); } void EnablePulse(void) { LCD_CTRL |= LCD_E; asm("NOP"); LCD_CTRL &= ~LCD_E; } void sendLCDcommand(unsigned char command) { LCD_CTRL &= ~LCD_RS; LCD_DATA = command; EnablePulse(); delay(20); } void InitLCD(void) { delay(20000); LCD_CTRL &= ~LCD_RW; sendLCDcommand(0x38); sendLCDcommand(0x0C); sendLCDcommand(0x01); delay(1000); } void sendLCDdata(unsigned char data) { LCD_CTRL |= LCD_RS; LCD_DATA = data; EnablePulse(); delay(20); } void DispString(char * str) { while(*str) { sendLCDdata(*str); str++; } } void Locate(int x, int y) { unsigned char RamAddr; if(x==0) RamAddr = 0x80+y; else RamAddr = 0xC0+y; sendLCDcommand(RamAddr); } int main(void) { unsigned int AdData = 0; unsigned int Voltage100 = 0; unsigned char value_1 = 0, value_p1 = 0, value_p01 = 0; unsigned char temp = 0; // 포트 F - ADC, 포트 A와 G는 TextLCD에 연결. DDRF = 0x00; DDRA = 0xFF; DDRG = 0x07; // B와 G 포트를 출력으로 지정. PORTA = 0x00; PORTG = 0x00; // B와 G 포트 값의 초기값 지정. InitLCD(); /* TextLCD에 "CDS_OUT:_.__V"을 표시해줌.(_.__에 숫자가 채워짐) */ Locate(0,0); DispString("CDS_OUT"); Locate(0,7); sendLCDdata(':'); Locate(0,9); sendLCDdata('.'); Locate(0,12); DispString("V"); // AD 변환 설정 ADMUX = 0x00; // ADC0 선택 / 0번 채널 / 채널 초기 설정 ADCSRA = 0x87; // 10000111 / ADC 허가, 8KSPS 표본화 주파수 while(1) { ADCSR |= 0x40; // ADSC AD 개시(Start) while((ADCSRA & 0x10) == 0x00); // ADIF AD 다 될 때까지 기다림. AdData = ADC; // 전압이 디지털로 변환된 값 읽어오기. Voltage100 = AdData * 0.48828125; // AD값을 전압 값으로 변환. // 1의 자리수. value_1 = Voltage100 / 100; temp = Voltage100 % 100; // 소수점 이하 첫째 자리 수 value_p1 = temp / 10; // 소수점 이하 둘째 자리 수 value_p01 = temp % 10; // 숫자를 LCD에 표시하기 위해 문자 코드로 변환. value_1 = value_1 + 0x30; value_p1 = value_p1 + 0x30; value_p01 = value_p01 + 0x30; // 값들을 표시. Locate(0,8); sendLCDdata(value_1); Locate(0,10); sendLCDdata(value_p1); Locate(0,11); sendLCDdata(value_p01); count ++; // 표시할 때마다 한 번 사이클 도는 것으로 생각. if(count == 10) count = 0; if(Voltage100 <= 100) // 1.00 V 아래로 떨어진 경우, { Locate(1,0); // 두 번째 줄에 DispString("Warning..."); // 경고 표시. if(count >= 5) // 약 5번의 사이클이면 0.5초 정도로 예상. { Locate(1,0); DispString(" "); // 0.5초마다 깜빡임. } } else { Locate(1,0); DispString(" "); } delay(60000); } }


+ Recent posts