BASIC4MCU | 질문게시판 | 알람시계 만드는 중입니다.. FND 결선 문제가 있어보여서 질문드립니다...,
페이지 정보
작성자 Busan 작성일2019-12-26 22:25 조회2,804회 댓글0건본문
#include
#include
// 스탑워치에서 사용되는 값
#define RESET 0
#define GO 1
#define STOP 2
//7-세그먼트 설정
int seg_number[10] = {0x3F, 0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6f};
int seg_count = 0;
// 스탑워치 변수 설정
int stopwatch_count = 0, stopwatch_count_control = 0;
int number_count = 0, number_count_temp = 0;
int N1000, N100, N10, N1;
//모드 변수
char mode = 0;
//시계 변수
int watch_count = 0;
int second = 0, minute = 0, hour = 0, M1 = 0, M10 = 0, H1 = 0, H10 = 0;
// 알람 변수
int alarm_minute = 0, alarm_hour = 0, alarm_M1 = 0, alarm_M10 = 0, alarm_H1 = 0, alarm_H10 = 0;
// 처음에 현재 시간과 알람 시간을 세팅하는 함수
void time_and_alarm_init(void)
{
hour = 23;
minute = 59;
alarm_hour = 0;
alarm_minute = 0;
}
// PG2 눌렀을 때의 함수 (시간-알람 바꾸기, 스탑워치 시작-정지)
void switch_1(void)
{
//현재 시간 바꾸기
/*----------------------------------------------------------------------*/
if(mode < 5)
{
if(mode == 1)
{
M1 = (M1 + 1)%10;
}
else if(mode == 2)
{
M10 = (M10 + 1) % 6;
}
else if(mode == 3)
{
if(H10 <2) H1 = (H1 + 1)%10;
else if(H10 == 2) H1 = (H1 + 1)%4;
}
else if(mode == 4)
{
if(H1 > 3)
{
H10 = (H10 + 1)%2;
}
else H10 = (H10 + 1)%3;
}
//세팅한 값을 현재 시간에 업데이트 한다. 이렇게 하지 않으면 스위치로 바꾸는 시간과 저장되어있는 시간이 일치하지 않는다.
minute = M10 * 10 + M1;
hour = H10 * 10 + H1;
}
// 스탑워치 동작시 스위치의 동작을 결정
/*--------------------------------------------------------------------------------------*/
if(mode == 5)
{
if((stopwatch_count_control == STOP) || (stopwatch_count_control == RESET))
{
stopwatch_count_control = GO;
}
else if(stopwatch_count_control == GO)
{
stopwatch_count_control = STOP;
}
}
// 알람시간 바꾸기
/*--------------------------------------------------------------------------------------*/
if(mode > 5)
{
if(mode == 6)
{
alarm_M1 = (alarm_M1 + 1)%10;
}
else if(mode == 7)
{
alarm_M10 = (alarm_M10 + 1) % 6;
}
else if(mode == 8)
{
if(alarm_H10 <2) alarm_H1 = (alarm_H1 + 1)%10;
else if(alarm_H10 == 2) alarm_H1 = (alarm_H1 + 1)%4;
}
else if(mode == 9)
{
alarm_H10 = (alarm_H10 + 1)%3;
}
// 알람 시간 업데이트
alarm_minute = alarm_M10 * 10 + alarm_M1;
alarm_hour = alarm_H10 * 10 + alarm_H1;
}
delay_ms(200);
}
// PG3 눌렀을 때의 함수 (모드 바꾸기, 스탑워치 리셋)
void switch_2(void)
{
//스탑워치 리셋 구문
if(mode == 5)
{
// 스탑워치가 STOP인 상태에서는 모드가 바뀌지 않는다.
if(stopwatch_count_control == STOP)
{
stopwatch_count_control = RESET;
}
// 스탑워치가 GO나 RESET 상태에서는 모드가 바뀐다.
else if((stopwatch_count_control == GO) || (stopwatch_count_control == RESET))
{
mode = 6;
}
}
else mode++; // 스탑워치 이외의 모드에서는 모드 바꾸기 동작
delay_ms(200);
if(mode == 10) mode = 0; //모드 변수 리셋
}
// 타이머/카운트 레지스터
void timer_init(void)
{
TIMSK = 0x01;
TCCR0 = 0x05;
TCNT0 = 6; // 2ms마다 인터럽트 발생 인터럽트 주기는 메뉴얼 참고.
}
void main()
{
timer_init();
time_and_alarm_init();
DDRG = 0x03;
DDRC = 0xff;
DDRA = 0xff;
SREG = 0x80;
while(1)
{
if((PING & 0x04) == 0x04)
{
switch_1();
}
if((PING & 0x08) == 0x08)
{
switch_2();
}
//알람시간과 현재 시간이 맞을 때 행동
if((alarm_hour == hour) && (alarm_minute == minute))
{
if(watch_count < 250) PORTG = 0x01;
else if(watch_count > 250) PORTG = 0x02;
}
else PORTG = 0x00;
}
}
interrupt[TIM0_OVF] void timer_int0(void)
{
TCNT0 =6;
// 7-세그먼트
/*-------------------------------------------------------------*/
seg_count++;
if(seg_count == 5) seg_count = 1;
//시계 동작 세팅
/*----------------------------------------------------------*/
watch_count++;
if(watch_count == 500) //1초
{
second++;
watch_count = 0;
}
if(second == 60)
{
minute++;
second = 0;
}
if(minute == 60)
{
hour++;
minute = 0;
}
if(hour == 24) hour = 0;
H10 = hour / 10;
H1 = hour % 10;
M10 = minute / 10;
M1 = minute % 10;
if(mode < 5)
{
if(seg_count == 1)
{
PORTC = 0b00001110;
if(mode == 4)
{
//0.5초마다 깜빡임.
if(watch_count > 250) PORTA = seg_number[H10];
else if(watch_count < 250) PORTA = 0x80;
}
else PORTA = seg_number[H10];
}
else if(seg_count == 2)
{
PORTC = 0b00001101;
if(mode == 3)
{
if(watch_count > 250) PORTA = seg_number[H1] | 0x80;
else if(watch_count <250) PORTA = 0x80;
}
else PORTA = seg_number[H1] | 0x80;
}
else if(seg_count == 3)
{
PORTC = 0b00001011;
if(mode == 2)
{
if(watch_count > 250) PORTA = seg_number[M10];
else if(watch_count < 250) PORTA = 0x80;
}
else PORTA = seg_number[M10];
}
else if(seg_count ==4)
{
PORTC = 0b00000111;
if(mode == 1)
{
if(watch_count > 250) PORTA = seg_number[M1];
else if(watch_count < 250) PORTA = 0x80;
}
else PORTA = seg_number[M1];
}
}
//초시계 동작 세팅
/*----------------------------------------------------------*/
N1000 = number_count / 1000;
number_count_temp = number_count % 1000;
N100 = number_count_temp / 100;
number_count_temp = number_count_temp % 100;
N10 = number_count_temp / 10;
number_count_temp = number_count_temp %10;
N1 = number_count_temp;
//0.01초 간격일 때. 0.1초로 하려면 stopwatch_count를 50으로.
if(stopwatch_count == 5)
{
number_count++;
stopwatch_count = 0;
}
if(mode == 5)
{
if(seg_count == 1)
{
PORTC = 0b00001110;
PORTA = seg_number[N1000];
}
else if(seg_count == 2)
{
PORTC = 0b00001101;
PORTA = seg_number[N100] | 0x80; //0x80은 자리수 표시
}
else if(seg_count == 3)
{
PORTC = 0b00001011;
PORTA = seg_number[N10];
}
else if(seg_count ==4)
{
PORTC = 0b00000111;
PORTA = seg_number[N1];
}
}
if(stopwatch_count_control == GO) stopwatch_count++;
else if(stopwatch_count_control == STOP) stopwatch_count = stopwatch_count;
else if(stopwatch_count_control == RESET) stopwatch_count = 0, number_count = 0;
//알람동작 세팅
/*-----------------------------------------------------------------------------------*/
if(mode > 5)
{
if(seg_count == 1)
{
PORTC = 0b00001110;
if(mode == 9)
{
if(watch_count > 250) PORTA = seg_number[alarm_H10];
else if(watch_count < 250) PORTA = 0x80;
}
else PORTA = seg_number[alarm_H10];
}
else if(seg_count == 2)
{
PORTC = 0b00001101;
if(mode == 8)
{
if(watch_count > 250) PORTA = seg_number[alarm_H1] | 0x80;
else if(watch_count <250) PORTA = 0x80;
}
else PORTA = seg_number[alarm_H1] | 0x80;
}
else if(seg_count == 3)
{
PORTC = 0b00001011;
if(mode == 7)
{
if(watch_count > 250) PORTA = seg_number[alarm_M10];
else if(watch_count < 250) PORTA = 0x80;
}
else PORTA = seg_number[alarm_M10];
}
else if(seg_count ==4)
{
PORTC = 0b00000111;
if(mode == 6)
{
if(watch_count > 250) PORTA = seg_number[alarm_M1];
else if(watch_count < 250) PORTA = 0x80;
}
else PORTA = seg_number[alarm_M1];
}
}
}
댓글 0
조회수 2,804등록된 댓글이 없습니다.