Open changheepark-dev opened 10 months ago
#define F_CPU 16000000UL // 16MHz의 오실레이터를 사용
#include <avr/io.h> //입출력 포트 사용을 위한 헤더 include
#define __DELAY_BACKWARD_COMPATIBLE__
#include <avr/delay.h> //딜레이 사용을 위한 헤더 inlcude
#include <avr/interrupt.h> //인터럽트 사용을 위한 헤더 include
#include "lcd.h" //LCD 사용을 위한 헤더 include -> " "외부의 파일을 include
// setting ///////////////////////////////////////////////////////////////////////////////
// time average
#define measurement_time 0.2 // 0.1 ~ 4 [s]
unsigned char time_average[10]; // 시간 평균 갯수
#define average_count 10 // 배렬 선언과 동일한 값
// sensor
#define TRIG 3 // PE0 (변경 불가), echo(pe1 ~ 3, pd4 ~ 7)
#define TRIG_delay 80 // 기본 80 [ms], 연산 속도에 맞춰 변경 가능, 너무 줄일 시 측정 오류
#define interval 700 // 측정 간격 5 ~ 2700 [mm]
//measurement
#define standard 50 // 0 ~ 100[%], 측정 민감도 (낮을수록 늦게 상승, 빨리 감소)
#define night_period 10 // 0 ~ 65535 [s] 전면 센서 밤에 on 시간
#define daytime_period 15 // 0 ~ 65535 [s] 전면 센서 낮에 on 시간
#define person 5 // 0 ~ 65535 [s] 동행자 인지 판단 시간
///////////////////////////////////////////////////////////////////////////////
// time average
unsigned char count = 0;
unsigned char average[7] = {0};
unsigned char av = 0;
unsigned char measurement;
// sensor
unsigned char check = 0;
// 초음파 시간 평균
ISR(TIMER1_COMPA_vect) {
unsigned char temp = time_average[count];
time_average[count] = check;
for (av = 0; av < 8; av++) {
if (((temp ^ time_average[count]) >> av) & 0x01) {
if ((temp >> av) & 0x01) {
average[av] --;
}
else {
average[av] ++;
}
}
}
count ++;
if (count == average_count) {
count = 0;
}
measurement = 1;
}
void measurement_time_Init() { // 초음파 계측 주기 타이머
TCCR1A = (0<<WGM11) | (0<<WGM10);
TCCR1B = (0<<WGM13) | (1<<WGM12) | (1<<CS12) | (0<<CS11) | (1<<CS10);
TIMSK |= (1 << OCIE1A);
OCR1A = 15624 * measurement_time;
sei();
}
unsigned char h = 12, m = 30, s = 30, l = 0;
unsigned int front[7] = {0};
ISR(TIMER3_COMPA_vect) {
// 시계
s++;
if (s > 59) {m++, s = 0;}
if (m > 59) {h++, m = 0;}
if (h > 23) {h = 0;}
// 경과 시간 측정
for (char a = 0 ; a < 7 ; a++) {
if (average[a] <= (average_count * standard / 100)) {
front[a]++;
}
else {
front[a] = 0;
}
}
}
void time_Init() { // 시간 타이머
TCCR3A = (0<<WGM11) | (0<<WGM10);
TCCR3B = (0<<WGM13) | (1<<WGM12) | (1<<CS12) | (0<<CS11) | (1<<CS10);
ETIMSK |= (1 << OCIE3A);
OCR3A = 15624;
sei();
}
// 후면 감지
char ckd = 0;
ISR(INT0_vect) {
if (ckd == 0) {ckd = 5;}
}
ISR(INT1_vect) {
if (ckd == 0) {ckd = 6;}
}
ISR(INT3_vect) {
if (ckd == 0) {ckd = 7;}
}
ISR(INT4_vect) {
if (ckd == 0) {ckd = 1;}
}
ISR(INT5_vect) {
if (ckd == 0) {ckd = 2;}
}
ISR(INT6_vect) {
if (ckd == 0) {ckd = 3;}
}
ISR(INT7_vect) {
if (ckd == 0) {ckd = 4;}
}
void INTR_Init() {
DDRD = 0x04;
PORTD = 0xfb;
EICRA = 0xff; //하강엣지 트리거
EICRB = 0xff;
EIMSK = 0xfb;
DDRE = 0x08;
PORTE = 0xf7;
sei();
}
int tNum2(unsigned int NUM) {
unsigned char Buff[3] = "0";
Buff[0] = '0'+((NUM %100)/10);
Buff[1] = '0'+(NUM %10);
LCDPuts(Buff);
}
int tNum3(unsigned int NUM) {
unsigned char Buff[4] = "0";
Buff[0] = '0'+((NUM %1000)/100);
Buff[1] = '0'+((NUM %100)/10);
Buff[2] = '0'+(NUM %10);
LCDPuts(Buff);
}
int Watch(unsigned int y) {
LCDMove(y,0);
unsigned char wc[13] = "0";
wc[0] = '0'+((h %100)/10);
wc[1] = '0'+(h %10);
wc[2] = 'h';
wc[3] = ' ';
wc[4] = '0'+((m %100)/10);
wc[5] = '0'+(m %10);
wc[6] = 'm';
wc[7] = ' ';
wc[8] = '0'+((s %100)/10);
wc[9] = '0'+(s %10);
wc[10] = 's';
LCDPuts(wc);
}
int bz(unsigned int a, unsigned int b) {
PORTG |= (1<<PG3);
_delay_ms(a);
PORTG &= ~(1<<PG3);
_delay_ms(b);
}
int main(void){
DDRB = 0xf0;
DDRG |= (1<<PG3);
MCU_Init();
LCDInit();
// 시간 설정
static char string1[]="set location";
static char string8[]="set Watch ";
unsigned char next = 5;
while (1) {
// 화면
if (next == 5) {
LCDMove(0,0);
LCDPuts(string1);
LCDMove(1,0);
tNum3(l);
}
else {
LCDMove(0,0);
if (next > 1) {
for (char a = 12 ; a < 15 ; a++) {string8[a] = ' ';}
if (next == 4) {string8[15] = 'h';}
else if (next == 3) {string8[15] = 'm';}
else {string8[15] = 's';}
}
else {
string8[12] = 'n';
string8[13] = 'e';
string8[14] = 'x';
string8[15] = 't';
}
LCDPuts(string8);
Watch(1);
}
// 버튼
if (PINB == 14) {
if (next == 5 && l != 0) {l--;}
if (next == 4 && h != 0) {h--;}
if (next == 3 && m != 0) {m--;}
if (next == 2 && s != 0) {s--;}
_delay_ms(200);
}
if (PINB == 13) {
if (next == 5 && l != 255) {l++;}
if (next == 4 && h != 23) {h++;}
if (next == 3 && m != 59) {m++;}
if (next == 2 && s != 59) {s++;}
_delay_ms(200);
}
if (PINB == 11 && next != 5) {
LCDInit();
next ++;
_delay_ms(200);
}
if (PINB == 7) {
next --;
if(next == 0){
break;
}
_delay_ms(200);
}
}
time_Init();
measurement_time_Init();
INTR_Init();
LCDInit();
static char string2[]="location : 000 ";
string2[11] = '0'+((l %1000)/100);
string2[12] = '0'+((l %100)/10);
string2[13] = '0'+(l %10);
ckd = 0;
// main
unsigned char disp = 0;
while(1){
// 초음파 측정
if (measurement == 1) {
check = 0;
TCCR0 = 7;
PORTE |= (1<<TRIG);
_delay_us(10);
PORTE &= ~(1<<TRIG);
while (!(PINE & (1<<0))) {}
TCNT0 = 0;
while (TCNT0 < ((interval + 50) / 10.88)){
for (char a = 0 ; a < 3; a++) {
if (PINE & (1<<a)) {
if (TCNT0 > ((interval) / 10.88)) {
check |= (1 << a);
}
}
}
for (char a = 4 ; a < 8; a++) {
if (PIND & (1<<a)) {
if (TCNT0 > ((interval) / 10.88)) {
check |= (1 << a - 1);
}
}
}
}
TCCR0 = 0;
measurement = 0;
}
// 전면 센서 작동
int largest = 1, secondLargest = 1;
char cc;
for (char a = 0; a < 7 ; a++) {
if (front[a] >= largest) {
secondLargest = largest;
largest = front[a];
cc = a + 1;
}
else if (front[a] > secondLargest && front[a] < largest) {
secondLargest = front[a];
}
}
if ((h >= 19) || (h < 7)) {
if ((largest > night_period) && secondLargest < person) {
PORTB = 0xf0;
// 통신
PORTD = 0xfb;
double com = 159343 + (1.5923*l + 0.152*cc)*1000;
_delay_us(com);
PORTD = 0xff;
}
else {
PORTB = 0x00;
PORTD = 0xfb;
_delay_us(100);
PORTD = 0xff;
}
}
else {
if ((largest > daytime_period) && secondLargest < person) {
PORTB = 0xf0;
// 통신
PORTD = 0xfb;
double com = 159343 + (1.5923*l + 0.152*cc)*1000;
_delay_us(com);
PORTD = 0xff;
}
else {
PORTB = 0x00;
PORTD = 0xfb;
_delay_us(100);
PORTD = 0xff;
}
}
// 후면 센서 작동
while (ckd != 0 && disp == 14) {
string2[14] = '-';
string2[15] = '0'+(ckd %10);
LCDMove(0,0);
LCDPuts(string2);
// 통신
PORTD = 0xfb;
double com = 637099 + (1.5925*l + 0.169*ckd)*1000;
_delay_us(com);
PORTD = 0xff;
for (char a = 0 ; a < 9 ; a++) {
if ((PINB & 0x0f) != 15) {
ckd = 0;
string2[14] = ' ';
string2[15] = ' ';
LCDInit();
break;
}
else if ((a > 5) || (a < 3)) {
bz(50, 200);
}
else {
bz(150, 200);
}
}
_delay_ms(200);
}
// test display
static char string3[]="sonic";
static char string4[]="filter";
static char string5[]="elapse";
static char string6[]="motion";
static char string7[]="largest : ";
static char string9[]="second : ";
unsigned char x[] = {7, 10, 13, 0, 3, 6, 9};
unsigned char y[] = {0, 0, 0, 1, 1, 1, 1};
if ((PINB & 15) != 15) {
disp = (PINB & 15);
LCDInit();
}
LCDMove(0,0);
// 초음파 테스트
if(disp == 12) {
LCDPuts(string3);
for (char a = 0 ; a < 7 ; a++) {
LCDMove(y[a], x[a]);
tNum2(!((check >> a) & 0x01));
}
LCDMove(1,12);
tNum3((~check) & 0x7f);
}
else if(disp == 10) {
LCDPuts(string4);
for (char a = 0 ; a < 7 ; a++) {
LCDMove(y[a], x[a]);
tNum2(average[a]);
}
LCDMove(1,12);
tNum3((~check) & 0x7f);
}
else if(disp == 6) {
LCDPuts(string5);
for (char a = 0 ; a < 7 ; a++) {
LCDMove(y[a], x[a]);
tNum2(front[a]);
}
LCDMove(1,12);
tNum3((~check) & 0x7f);
}
else if(disp == 5) {
LCDMove(0,0);
LCDPuts(string7);
tNum3(largest);
LCDMove(1,0);
LCDPuts(string9);
tNum3(secondLargest);
}
// 움직임 감지 테스트
else if(disp == 9) {
LCDPuts(string6);
unsigned char aa = (PINE >> 4) | ((PIND & 0x0f) << 4);
for (char a = 0 ; a < 6 ; a++) {
LCDMove(y[a], x[a]);
tNum2(!((aa >> a) & 0x01));
}
LCDMove(1, 9);
tNum2(!((aa >> 7) & 0x01));
LCDMove(1,12);
tNum3(aa);
}
else {
disp = 14;
LCDPuts(string2);
Watch(1);
}
}
}