BASIC4MCU | 질문게시판 | 알람 시계
페이지 정보
작성자 나난나 작성일2020-12-12 12:47 조회18,326회 댓글11건본문
밑에 있는 코드에 알람 시간을 나타나기 위해 외부 인터럽트를 하나 또는 두개를 추가하고원래 코드는 LED가 1초마다 깜빡이는데 알람시간과 시간이 맞으면 LED가 1분동안 켜지게하라(PORTC = 0;)이 두가지를 적용 시키면 코드는 어떻게 변하는지 제발 알려주세요// 설 명 : 타이머/카운터1 이용 시계 제작#include <mega128.h>#include <delay.h>char seg_pat[16]= {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};char N1 = 0, N10 = 0, N100 = 2, N1000 = 1;char pos = 0; // 0 : 1자리, 1 : 10자리 , 2 : 100자리 , 3 : 1000자리char hour, min, sec = 0;void Time_out(void); // 시간 출력 함수void main(void){DDRB = 0xFF; // 포트 B 출력 설정DDRF = 0b11110000; // PF4-PF7 출력 설정DDRC = 0xFF; // 포트 C 출력 설정PORTC = 0;// 인터럽트 초기화EICRB = 0b00001010; // 외부 인터럽트 4 : 하강 에지EIMSK = 0b00110000; // 외부 인터럽트 0 인에이블'// 타이머 카운터 1 1/16us * 1024 * (65536 - 49911) = 1 secTIMSK = 0x04; // TOIE1 = '1';TCCR1A = 0x00;TCCR1B = 0x05; // 일반모드, 프리스케일 = CK/1024TCNT1 = 49911; // 타이머/카운터1 레지스터 초기값SREG = 0x80; // 전역 인터럽트 인에이블 비트 I 셋.hour = N1000 * 10 + N100;min = N10 * 10 + N1;while(1) {Time_out(); // 시간 출력if(sec >= 60){sec = 0;min = min + 1;if(min == 60) {min = 0;hour = (hour + 1) % 24;}}}}// 시간 출력 함수void Time_out(void){PORTF = 0b11100000; // SEG 1(분 1단위)PORTB = seg_pat[min % 10];delay_ms(5);PORTF = 0b11010000; // SEG 2(분 10단위)PORTB = seg_pat[min / 10];delay_ms(5);PORTF = 0b10110000; // SEG 3(시간 1단위)PORTB = seg_pat[hour % 10];delay_ms(5);PORTF = 0b01110000; // SEG 4(시간 10단위)PORTB = seg_pat[hour / 10];delay_ms(5);}// 외부 인터럽트 요구 4 서비스 루틴(SW1 처리)interrupt [EXT_INT4] void external_int4(void){if(pos == 0) N1 = (N1 + 1) % 10; // 분 1단위 +1else if(pos == 1) N10 = (N10 + 1) % 6; // 분 10단위 +1else if(pos == 2) { // 시간 1단위 +1if(N1000 == 2) N100 = (N100 + 1) % 4;else N100 = (N100 + 1) % 10;}else { // 시간 10단위 +1if(N100 >= 4) N1000 = (N1000 + 1) % 2;else N1000 = (N1000 + 1) % 3;}hour = N1000 * 10 + N100; // 시간 계산min = N10 * 10 + N1; // 분 계산}// 외부 인터럽트 요구 5 서비스 루틴(SW2 처리)interrupt [EXT_INT5] void external_int5(void){pos = (pos + 1) % 4; // 입력 자리 이동}// 타이머/카운터1 오버플로우 인터럽트 처리// 주기 = 1/16us * 1024 * (65536 - 49911) = 1 secinterrupt [TIM1_OVF] void timer1_int(void){sec = sec + 1;PORTC = PORTC ^ 0xFF; // LED 반전 표시TCNT1 = 49911;}
댓글 11
조회수 18,326master님의 댓글
master 작성일
// 설 명 : 타이머/카운터1 이용 시계 제작
//
#include <mega128.h>
#include <delay.h>
//
char seg_pat[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
char pos=0; // 0:1자리,1:10자리,2:100자리,3:1000자리
char h=12,m=0,s=0; // 시간
char ah=12,am=0; // 알람시간
char mode=0; // 시계모드
//
interrupt [EXT_INT4] void external_int4(void){
if (pos==0){ if(m%10<9)m++; else m=m/10*10; } // 분 1단위+1
else if(pos==1){ if(m<50 )m+=10; else m=m%10; } // 분 10단위+1
else if(pos==2){ if(h%10<9){ h++; if(h>23)h=20; } else h=h/10*10; } // 시간 1단위+1
else { if(h<14 )h+=10; else h=h%10; } // 시간 10단위+1
mode=0; // 시계모드
}
//
interrupt [EXT_INT5] void external_int5(void){
if (pos==0){ if(am%10<9)am++; else am=am/10*10; } // 알람분 1단위+1
else if(pos==1){ if(am<50 )am+=10; else am=am%10; } // 알람분 10단위+1
else if(pos==2){ if(ah%10<9){ ah++; if(ah>23)ah=20; } else ah=ah/10*10; } // 알람시간 1단위+1
else { if(ah<14 )ah+=10; else ah=ah%10; } // 알람시간 10단위+1
mode=1; // 알람모드
}
//
interrupt [EXT_INT6] void external_int6(void){
if(++pos>3)pos=0; // 입력 자리 이동
}
//
interrupt [TIM1_OVF] void timer1_int(void){ //1s
TCNT1=49911;
//
if(++s>=60){ s=0;
if(++m>=60){ m=0; if(++h>=24)h=0; }
if(ah==h && am==m)PORTC|=1; else PORTC&=~1; // 알람 LED 표시 PA0
}
//
if(mode==0){ PORT&=~4; PORTA^=2; } // 시계모드 PA1 점멸
else { PORT&=~2; PORTA^=4; } // 알람모드 PA2 점멸
}
//
void main(void){
DDRB=0xFF; // 포트 B 출력 설정
DDRF=0xF0; // PF4-PF7 출력 설정
DDRC=0xFF; // 포트 C 출력 설정
//
EICRB=0xAA; EIMSK=0x70; // 외부 인터럽트 4,5,6:하강 에지
TCCR1B=0x05; CNT1=49911; TIMSK=4; // 1 s
SREG=0x80;
while(1){
if(mode==0){ // 시계모드
PORTF=~0x10; PORTB=seg_pat[m%10]; delay_ms(5); // SEG 1(분 1단위)
PORTF=~0x20; PORTB=seg_pat[m/10]; delay_ms(5); // SEG 2(분 10단위)
PORTF=~0x40; PORTB=seg_pat[h%10]; delay_ms(5); // SEG 3(시간 1단위)
PORTF=~0x80; PORTB=seg_pat[h/10]; delay_ms(5); // SEG 4(시간 10단위)
}
else{ // 알람모드
PORTF=~0x10; PORTB=seg_pat[am%10]; delay_ms(5); // SEG 1(분 1단위)
PORTF=~0x20; PORTB=seg_pat[am/10]; delay_ms(5); // SEG 2(분 10단위)
PORTF=~0x40; PORTB=seg_pat[ah%10]; delay_ms(5); // SEG 3(시간 1단위)
PORTF=~0x80; PORTB=seg_pat[ah/10]; delay_ms(5); // SEG 4(시간 10단위)
}
}
}
//
제대로 동작하는지 체크해 보세요
나난나님의 댓글
나난나
int 5를 눌러도 숫자가 안변합니다.
master님의 댓글
master
PA0 : 알람용 LED
PA1 : 시계모드
PA2 : 알람모드
수정했으니 다시 돌려보세요
나난나님의 댓글
나난나
if(mode==0){ PORT&=~4; PORTA^=2; } // 시계모드 PA1 점멸
else { PORT&=~2; PORTA^=4; } // 알람모드 PA2 점멸
이 부분 PORT 맞나요?
master님의 댓글
master
PORTA로 수정하세요
간단한 오류는 수정할 수 있지 않나요?
나난나님의 댓글
나난나
앗 죄송 합니다. 수정 했었는데 답변 수정하는 것을 안했네요
LED는
interrupt [TIM1_OVF] void timer1_int(void){ //1s
TCNT1=49911;
//
if(++s>=60){ s=0;
if(++m>=60){ m=0; if(++h>=24)h=0; }
if(ah==h && am==m)PORTC|=1; else PORTC&=~1; // 알람 LED 표시 PA0
}
저 조건이 이해는가는데 원래 시간이 같아야만 불이 들어와야 되는데 계속해서 불이 들어 옵니다.
master님의 댓글
master 작성일
LOW에서 LED가 켜지는지 HIGH에서 LED가 켜지는지 저는 알 길이 없습니다.
LED 키는 정도는 할 수 있지 않나요?
나난나님의 댓글
나난나
이 글 삭제 가능한가요?
master님의 댓글
master 작성일
if(mode==0){ PORT&=~4; PORTA^=2; } // 시계모드 PA1 점멸
else { PORT&=~2; PORTA^=4; } // 알람모드 PA2 점멸
PORTC가 LED 포트라면 위 PORTA도 PORTC로 수정하세요
나난나님의 댓글
나난나 작성일이 글 삭제 가능한가요?
master님의 댓글
master
(질문/답변 포함) 기술자료는 삭제하지 못합니다.