답변 : atmega128a 외부인터럽트 두개와 7segment의 연결
페이지 정보
작성자 master 작성일23-12-02 18:58 조회825회 댓글0건본문
#define F_CPU 16000000
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
//
#define B0 458
#define C1 523 // 도
#define C1_ 554
#define D1 587 // 레
#define D1_ 622
#define E1 659 // 미
#define F1 699 // 파
#define F1_ 740
#define G1 784 // 솔
#define G1_ 831
#define A1 880 // 라
#define A1_ 932
#define B1 988 // 시
#define C2 C1*2 // 도
#define C2_ C1_*2
#define D2 D1*2 // 레
#define D2_ D1_*2
#define E2 E1*2 // 미
#define F2 F1*2 // 파
#define F2_ F1_*2
#define G2 G1*2 // 솔
#define G2_ G1_*2
#define A2 A1*2 // 라
#define A2_ A1_*2
#define B2 B1*2 // 시
//
#define DLY_0 32 // 온음표*2
#define DLY_1 16 // 온음표
#define DLY_2 8 // 2분 음표
#define DLY_4 4 // 4분 음표
#define DLY_8 2 // 8분 음표
#define DLY_16 1 // 16분 음표
//
volatile int santa[100]={E1,F1,G1,G1,A1,B1,C2,C2,E1,F1,G1,G1,G1,G1,G1,A1,G1,F1,F1,F1,E1,G1,C1,E1,D1,F1,F1,C1,B1};
volatile int santa_length[100]={DLY_8,DLY_8,DLY_4,DLY_2,DLY_8,DLY_8,DLY_4,DLY_2,DLY_8,DLY_8,DLY_8,DLY_8,DLY_8,DLY_8,DLY_4,DLY_8,DLY_8,DLY_8,DLY_8,DLY_4,DLY_2,DLY_2,DLY_2,DLY_2,DLY_2,DLY_2,DLY_1,DLY_2,DLY_1,};
char COLUMN[4]={0,0,0,0};
//
volatile unsigned char Segment_Data[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x27,0x7F,0x6F};
volatile char calender[0]={0};
volatile char flag0=0,flag1=0,flag2=0;
volatile int freq=1000,i;
volatile int count;
volatile unsigned char TIMERvalue=0xFF;
volatile unsigned char keyin=0; // Declare and initialize keyin
volatile unsigned char keyold=0; // Declare and initialize keyold
volatile unsigned char change=0; // Declare and initialize change
volatile int SHOW_1=1; // Declare and initialize SHOW_1
volatile int SHOW_2=1; // Declare and initialize SHOW_2
volatile int number;
//-------------------------------------------------------
void Shimpyo(int time){ for(int i=0;i<time;i++)_delay_ms(50); }
//
void Cutoff_Play(void){ _delay_ms(20); TIMERvalue=1; _delay_ms(20); }
//
void ShowDigit(int i,int digit){ PORTC=~(0x01<<digit); PORTA=Segment_Data[i]; }
//
void Show4Digit(void){
COLUMN[0]=(SHOW_1)/10; COLUMN[1]=(SHOW_1)%10;
COLUMN[2]=(SHOW_2)/10; COLUMN[3]=(SHOW_2)%10;
for(int i=0;i<4;i++){ ShowDigit(COLUMN[i],i); _delay_ms(2); }
}
//
void sum(void){ PORTC=0x00; PORTA=0xff; PORTE=0xff; }
//
void santasong(void){
for(int i=0;i<40;i++){ freq=santa[i]; TIMERvalue=1000000/(8*freq); Shimpyo(santa_length[i]); Cutoff_Play(); }
}
//-------------------------------------------------------
ISR(INT0_vect){ flag0=1; }
ISR(INT1_vect){ flag1=1; }
ISR(INT2_vect){ flag2=1; }
//
ISR(TIMER0_COMP_vect){ OCR0=TIMERvalue; }
//-------------------------------------------------------
int main(void){
DDRA=0xff; DDRC=0xff; DDRG=0x03;
TCCR0=0x04; TCNT0=0x05; TIMSK=0x01;
EICRA=0xFF; EIMSK=0x07; SREG=0x80;
while(1){
if(flag0){ flag0=0;
number=SHOW_1*100+SHOW_2;
count=calender[number];
COLUMN[0]=(SHOW_1)/10; COLUMN[1]=(SHOW_1)%10;
COLUMN[2]=(SHOW_2)/10; COLUMN[3]=(SHOW_2)%10;
if(SHOW_1==12 && SHOW_2==25){ santasong(); _delay_ms(100); }
else { PORTG=0x03; }
}
//------------------------------------
if(flag1){ flag1=0;
Show4Digit();
keyin=(PING &0x0c)>>2;
if(keyin){ _delay_ms(200); keyin=(PING & 0x0C)>> 2; }
if(keyold!=keyin)change=1;
else change=0;
//
if(change==1 && keyin==1){ if(++SHOW_1>12)SHOW_1=1; }
if(change==1 && keyin==2){ if(++SHOW_2>31)SHOW_2=1; }
if(change==1 && keyin==3){ keyin=0; }
}
//------------------------------------
if(flag2){ flag2=0;
COLUMN[0]=(SHOW_1)/10; COLUMN[1]=(SHOW_1)%10;
COLUMN[2]=(SHOW_2)/10; COLUMN[3]=(SHOW_2)%10;
number=SHOW_1*100+SHOW_2;
if(change==1 && keyin==2){ calender[number]++; PORTG=0x02; _delay_ms(200); PORTG=0x00; }
}
}
}
//-------------------------------------------------------
DDRD=0x07;
입력핀을 출력으로 설정하면 고장납니다.
//
EIMSK=0x0f;
인터럽트를 4개 이네이블 시키고 함수를 3개만 만들면 오동작하게 됩니다.
//
ISR(INT1_vect){
while(1){
인터럽트 함수 안에서 무한루프를 사용하면 안됩니다.
//
_delay_ms(200);
가급적 인터럽트 함수 안에서는 딜레이를 사용하지 않는 것이 좋습니다.
//
댓글 : 0
조회수 : 825
등록된 댓글이 없습니다.