BASIC4MCU | 질문게시판 | ATMEGA128 혹시 여기서 왜 인터럽트 기능이 안되는지 알 수 있나요
페이지 정보
작성자 IEEE 작성일2023-06-04 11:02 조회507회 댓글1건본문
#include <avr/io.h> // ATmega128 register 정의
#include <avr/interrupt.h> // interrupt 관련
#define F_CPU 16000000UL
#define __DELAY_BACKWARD_COMPATIBLE__
#include <util/delay.h>
unsigned char digit[10]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7c, 0x07,0x7f, 0x67};
unsigned char fnd_sel[4]={0x01, 0x02, 0x04, 0x08};
unsigned char fnd[4];
volatile int count1=0,count=0,count2=0, i =0,k=0, j=0,hour=0, MODE=0, order=0;
#define DO 0
#define RE 1
#define MI 2
#define FA 3
#define SO 4
#define RA 5
#define SI 6
#define DDO 7
#define si 8
#define RRE 9
unsigned char table[]={17,43,66,77,97,114,117,137,3,143};
int song[]={si, RE, SO, si, RE ,RE ,DO,DO,MI,MI ,MI,MI,RE,FA,RA,DDO,SI,RA,SO,SO,SO,SO, SO,SO,SI,SI,RRE,RRE,DDO,DDO,SI,RA,RA,RE,RE,FA,RA,DDO,DDO,SI,SI,RA,SO,SO,si,RE,SO,si,RE,RE,DO,DO,MI,MI,RE,FA,RA,DDO,SI,RA,SO,SO,SO,SO};
int count_1=0,count_2;
#define lux_1 900
unsigned short read_adc()
{
unsigned char adc_high, adc_low;
unsigned short adc_value;
ADCSRA|=(1<<ADSC);
adc_high = ADCH;
adc_low = ADCL;
adc_value = adc_high + adc_low;
return adc_value;
}
ISR(INT4_vect)
{
MODE++;
count2 = count;
if(MODE==6)
{
MODE=0;
}
}
ISR(INT5_vect)
{
if(MODE==0)
{
}
if(MODE==1)
{
hour++;
}
if(MODE==2)
{
hour++;
}
if(MODE==3)
{
count++;
}
if(MODE==4)
{
count++;
}
if(MODE==5)
{
MODE++;
}
}
void buzzer(int hz, int count_buzzer)
{
if (hz <= 0)
return;
double ms = 500.0 / hz;
int k;
for (k = 0; k < count_buzzer; k++)
{
PORTB |= 0b00010000; // 부저 ON
_delay_ms(ms);
PORTB &= 0b11101111; // 부저 OFF
_delay_ms(ms);
}
}
int main()
{
DDRB = 0b00010000;
ADMUX = 0b0000000;
ADCSRA = 0b11100111;
DDRA = 0xff;
int adc_digit = 0;
DDRC = 0xff; // FND Data
DDRG = 0x0f; // FND Select
DDRE = 0x00; // INT4, 5
EIMSK = 0b00110000;
EICRB = 0b00001111;
SREG |= 1<<7;
while(MODE!=5)
{
EIMSK = 0b000000000;
adc_digit = ADC;
if(adc_digit>=lux_1)
{
MODE = 5;
}
if(MODE==0)
{
count++;
}
else if(MODE==1)
{
}
if(count==60)
{
count=0;
hour++;
}
if(hour==24)
{
hour=0;
}
fnd[3] = (hour/10)%10; // 천 자리
fnd[2] = (hour/1)%10; // 백 자리
fnd[1] = (count/10)%10; // 십 자리
fnd[0] = count%10; // 일 자리
for (j=0; j<40; j++)
{
if ((MODE==1)||(MODE==2))
{
for(i=2;i<4;i++)
{
PORTC = digit[fnd[i]];
PORTG = fnd_sel[i];
_delay_ms(2);
_delay_us(100);
}
for(i=0;i<4;i++)
{
PORTC = digit[fnd[i]];
PORTG = fnd_sel[i];
_delay_us(100);
}
}
if ((MODE==3)||(MODE==4))
{
for(i=0;i<2;i++)
{
PORTC = digit[fnd[i]];
PORTG = fnd_sel[i];
_delay_ms(2);
_delay_us(100);
}
for(i=0;i<4;i++)
{
PORTC = digit[fnd[i]];
PORTG = fnd_sel[i];
_delay_us(100);
}
}
if (MODE == 5)
{
buzzer(587.3295,500);//레
buzzer(987.7666,500);//시
buzzer(987.7666,500);//시
buzzer(1046.502,250);//도
buzzer(987.7666,250);//시
buzzer(880.0,250);//라
buzzer(783.9909,250);//솔
buzzer(659.2551,500);//미
buzzer(587.3295,500);//레
buzzer(783.9909,500);//솔
buzzer(739.9888,250);//파#
buzzer(783.9909,250);//솔
buzzer(880.0,1000);//라
}
else if(MODE==6)
{
MODE = 0;
}
else
for(i=0;i<4;i++)
{
PORTC = digit[fnd[i]];
PORTG = fnd_sel[i];
_delay_us(100);
}
}
EIMSK = 0b00110000;
}
}
이 코딩에서 저희 MODE 5 상태가 되면 스위치를 눌러( 인터럽트 발생) mode 6으로 만들고 싶은데 그게 안 되네요 혹시 뭐가 문제일까요?
댓글 1
조회수 507master님의 댓글
master 작성일
if(MODE==5){ MODE++; }
ISR(INT5_vect)에서 위 코드는 왜 넣었을까요?
//
SREG |= 1<<7;
while(1){ // while(MODE!=5){
메인함수의 무한루프에서 MODE를 왜 사용했을까요?
이 루프를 벗어나면 먹통 됩니다.
//
else if(MODE==6){ MODE = 0; }
MODE=6이면 0으로 clear 시키는 곳이 몇군데 있습니다.
MODE=6을 사용하려면 MODE=7에서 clear 시켜야겠죠