changheepark-dev / Digital-System-Lab

Atmega128
0 stars 0 forks source link

전면 센서 + 후면 센서 #15

Open changheepark-dev opened 11 months ago

changheepark-dev commented 11 months ago
#define F_CPU 16000000UL        // 16MHz의 오실레이터를 사용
#include <avr/io.h>             //입출력 포트 사용을 위한 헤더 include
#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 20
#define daytime_period 30

///////////////////////////////////////////////////////////////////////////////

// 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();
}

int h = 12, m = 30, s = 30;
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 = 1;}
}
ISR(INT1_vect) {
    if (ckd == 0) {ckd = 2;}
}
ISR(INT2_vect) {
    if (ckd == 0) {ckd = 3;}
}
ISR(INT3_vect) {
    if (ckd == 0) {ckd = 4;}
}
ISR(INT4_vect) {
    if (ckd == 0) {ckd = 5;}
}
ISR(INT5_vect) {
    if (ckd == 0) {ckd = 6;}
}
ISR(INT6_vect) {
    if (ckd == 0) {ckd = 7;}
}
ISR(INT7_vect) {
    if (ckd == 0) {ckd = 8;}
}

void INTR_Init() {
    DDRD = 0x00;
    PORTD = 0xff;

    EICRA = 0xff;       //하강엣지 트리거
    EICRB = 0xff;
    EIMSK = 0xff;

    DDRE = 0x08;
    PORTE = 0xf7;
    sei();
}

int tNum(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 main(void){
    DDRB = 0xf0;
    MCU_Init();
    LCDInit();

    // 시간 설정
    static char string8[]="set Watch       ";
    unsigned char next = 4;
    while (1) {
        // 화면
        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 == 4 && h != 0) {h--;}
            if (next == 3 && m != 0) {m--;}
            if (next == 2 && s != 0) {s--;}
            _delay_ms(200);
        }
        if (PINB == 13) {
            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 != 4) {
            next ++;
            _delay_ms(200);
        }
        if (PINB == 7) {
            next --;
            if(next == 0){
                break;
            }
            _delay_ms(200);
        }
    }
    time_Init();
    measurement_time_Init();
    INTR_Init();
    LCDInit();

    // main
    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 = front[0], secondLargest;
        for (char a = 1 ; a < 7 ; a++) {
            if (front[a] > largest) {
                secondLargest = largest;
                largest = front[a];
            }
            else if (front[a] > secondLargest && front[a] < largest) {
                secondLargest = front[a];
            }
        }

        // 밤
        if ((h >= 19) || (h < 7)) {
            if ((largest > night_period) && secondLargest < 10) {
                PORTB = 0xf0;
            }
            else {PORTB = 0x00;}
        }
        // 낮
        else {
            if ((largest > daytime_period) && secondLargest < 10) {
                PORTB = 0xf0;
            }
            else {PORTB = 0x00;}
        }

        // 후면 센서 작동
        while (ckd != 0) {          
            if ((PINB & 0x0f) != 15) {
                ckd = 0;
            }
            LCDMove(1,12);
            tNum(ckd);
        }

        LCDMove(0,0);
        tNum(front[0]);
        LCDMove(0,4);
        tNum(front[1]);
        LCDMove(0,8);
        tNum(front[2]);
        LCDMove(0,12);
        tNum(front[3]);

        LCDMove(1,0);
        tNum(front[4]);
        LCDMove(1,4);
        tNum(front[5]);
        LCDMove(1,8);
        tNum(front[6]);
    }
}
// 버저 sos

// lcd 시간 + 위치

// 감지되면 버저
// 뭐 할지