질문게시판 > atmega128 인터럽트 입력을 통한 모드 변경

TODAY865 TOTAL2,160,876
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

아두이노 센서 ATMEGA128 PWM LED 초음파 AVR 블루투스 LCD UART 모터 적외선


BASIC4MCU | 질문게시판 | atmega128 인터럽트 입력을 통한 모드 변경

페이지 정보

작성자 수제비성애자 작성일2021-12-20 11:10 조회2,989회 댓글6건

본문

	

질문 드리고 혼자 생각해서 코드는 원하던 동작은 만들었습니다.

 

#define F_CPU 16000000

#define STOP 0

#define START 1// switch(state)를 정의해준다.

 

#include <avr/io.h>

#include <util/delay.h>

#include <avr/interrupt.h> // 여러 함수를 사용하기 위해 헤더함수 선언

 

unsigned char count_int=0;

char count=0;

 

 

void Show4Digit(int number); // Show4Digit

void ShowDigit(int i, int digit);

void Run(void);

 

void mode_1_Stop_Watch();

void mode_2_Stop_Alarm();

void mode_3_Free_Topic();

int mode_state = mode_1_Stop_Watch();

while(1)

{

switch(mode_state)

{

case 1:

mode_1_Stop_Watch;

break;

case 2:

mode_2_Stop_Alarm();

break;

case 3:

mode_3_Free_Topic();

}

}

 

const unsigned char Segment_Data[] =

{0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x27,0x7F,0x6F};

char COLUMN[4]={0,0,0,0};

// Default SHOW_NUMBER12=0, SHOW_NUMBER34=0

int SHOW_NUMBER=0, SHOW_NUMBER12=0, SHOW_NUMBER34=0; //세그먼트는 0000으로 시작한다.

int state=STOP; // 시작 state는 STOP이다.

 

ISR(TIMER0_OVF_vect) // TIMER0 has overflowed

{

if(state==START){

count_int++; // count_int값이 하나 증가

// 244번에 한번씩 seconds를 하나 증가 즉, 244.14 Hz / 244 = 1Hz, 즉 1초임.

if(count_int == 244){

PORTG ^= 0x03; //G포트 다이오드 on

SHOW_NUMBER34++; //1초가 지날 때 Seconds를 1씩 올린다.

count_int=0; //다시 count는 0부터 세어진다.

}

}

}

 

ISR(INT0_vect) {

if(state==STOP) state=START; // state가 STOP으로 시작되고, INT0을 누르면 state는 START로 바뀐다. 따라서 INT0을 1번 누르면 START가 된다.

 

}

 

ISR(INT1_vect) {

if(state==START) state=STOP; // state가 start일 때 INT1을 누르면 state는 START로 바뀐다.

}

 

ISR(INT2_vect) {

if(mode_state==2) mode_state=1;

else mode_state==2;

}

 

ISR(INT3_vect) {

if(mode_state==3) mode_state=1;

else mode_state==3;

}

 

int main(void) {

DDRC = 0xff; DDRA = 0xff; //출력으로 사용합니다.

EICRA = 0x0F; // Rising Edge detection on INT0 & INT1

EIMSK = 0x03; // Set INT0 & INT1

SREG |= 0x80; // Global Interrupt Enable

TCCR0 = 0x06; // Normal mode, prescale 256, 16M/256=62500Hz

TCNT0 = 0x00; // n=0, 256 count, 62500Hz/256=244.14Hz

TIMSK = 0x01; // timer0 OVERFLOW interrupt enable

PORTC = 0x00;

state=STOP; //시작 state는 stop

while (1) {

Run();

SHOW_NUMBER=SHOW_NUMBER12*100+SHOW_NUMBER34;

Show4Digit(SHOW_NUMBER);

} //Show_NUMBER는 세븐세그먼트 순서대로 천의자리부터 일의자리까지 각 숫자가 값을 가지는 천의자리 숫자입니다.

}

 

 

 

void Show4Digit(int number) {

COLUMN[0] = number/1000; //천의자리 표시

COLUMN[1] = (number%1000)/100; //백의자리 표시

COLUMN[2] = (number%100)/10; //십의자리 표시

COLUMN[3] = (number%10); //일의자리 표시

for(int i=0;i<4;i++) {

ShowDigit(COLUMN[i],i); //한 자릿수씩 숫자를 표현합니다.

_delay_ms(2); // wait for a second

}

}

 

void Run(void) {

switch(state) {

case STOP : break; // state가 STOP일 때 멈춘다.

case START: TIMER0_OVF_vect;

if(SHOW_NUMBER34>59){

SHOW_NUMBER12++;

if(SHOW_NUMBER12>59) SHOW_NUMBER12=0;

SHOW_NUMBER34=0; // state가 STATRT일 때 34자리는 1씩 올라가고, 34가 59보다 클 때, 12는 1씩 증가한다. 12가 59보다 크게되면 00.00이 된다.

}

break;

}

}

void ShowDigit(int i, int digit) {

PORTC=~(0x01<<digit);

if(digit==1)

PORTA = Segment_Data[i]|0x80; // 두 번째 세븐세그먼트의 dp포인트에 LED가 들어오게 함

else

PORTA = Segment_Data[i];

}


이 상태에서 어떤 모드에서든 int2를 누르면 알람모드로 변경해서 int0을 눌렀을 때 모드에 맞는 기능 수행,
int2를 다시 누르면 모드 1로 변경.
어떠 모드에서든 int3을 누르면 자유주제로 변경해서 int0을 눌렀을 때 모드에 맞는 기능 수행을 하려고 하는데 모드 변경이 안됩니다.
int3을 다시 누르면 모드1로 변경
case를 사용해서 모드에 값을 입력해주려고 했는데 아무래도 while, swicth를 잘못 쓴것으로 보이는데 어디를 수정하면 모드를 변경할 수 있을까요?
  • BASIC4MCU 작성글 SNS에 공유하기
  • 페이스북으로 보내기
  • 트위터로 보내기
  • 구글플러스로 보내기

댓글 6

조회수 2,989

master님의 댓글

master 작성일

뭘 하려는지 이해가 안됩니다.
제가 적어드린 답변코드를 수정해서 다시 만들어보시고
뭘 원하는지 명확하게 작성해보세요

수제비성애자님의 댓글

수제비성애자 댓글의 댓글 작성일

첫 실행모드에서는 다음과 같이 작동하고
INT3을 누르면 다른 모드로 변경하여 INT0을 눌렀을 때 첫 모드와 다른 기능을 수행하고
INT4를 누르면 또 다른 모드로 변경하여 INT0을 눌렀을 때 또 다른 기능을 수행하게 하고 싶습니다.
#define F_CPU 16000000
#define STOP 0
#define START 1
#define INIT 2 // switch(state)를 정의해준다.
#define mode_0_Stop_Watch 3
#define mode_1_Alarm 4
#define mode_2_Free_Topic 5

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h> // 여러 함수를 사용하기 위해 헤더함수 선언

unsigned char count_int=0;
char count=0;

void Show4Digit(int number); // Show4Digit
void ShowDigit(int i, int digit);
void Run(void);

const unsigned char Segment_Data[] =
{0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x27,0x7F,0x6F};
char COLUMN[4]={0,0,0,0};
// Default SHOW_NUMBER12=0, SHOW_NUMBER34=0
int SHOW_NUMBER=0, SHOW_NUMBER12=0, SHOW_NUMBER34=0; //세그먼트는 0000으로 시작한다.
int state=STOP; // 시작 state는 STOP이다.
int mode=mode_0_Stop_Watch;

ISR(TIMER0_OVF_vect) // TIMER0 has overflowed
{
if(state==START){
count_int++; // count_int값이 하나 증가
// 244번에 한번씩 seconds를 하나 증가 즉, 244.14 Hz / 244 = 1Hz, 즉 1초임.
if(count_int == 244){
PORTG ^= 0x03; //G포트 다이오드 on
SHOW_NUMBER34++; //1초가 지날 때 Seconds를 1씩 올린다.
count_int=0; //다시 count는 0부터 세어진다.
}
}
}

ISR(INT0_vect) {
if(state==STOP) state=START; // state가 STOP으로 시작되고, INT0을 누르면 state는 START로 바뀐다. 따라서 INT0을 1번 누르면 START가 된다.

}

ISR(INT1_vect) {
if(state==START) state=STOP; // state가 start일 때 INT1을 누르면 state는 START로 바뀐다.
}

ISR(INT2_vect) {
if(state==START) state==STOP;
if(mode==mode_1_Alarm)
mode=mode_0_Stop_Watch;
else mode==mode_1_Alarm;
}

ISR(INT3_vect) {
if(state==START) state==STOP;
if(mode==mode_2_Free_Topic)
mode==mode_0_Stop_Watch;
else mode==mode_2_Free_Topic;
}

int main(void) {
DDRC = 0xff; DDRA = 0xff; //출력으로 사용합니다.
EICRA = 0xFF; // Rising Edge detection on INT0 & INT1
EIMSK = 0x0F; // Set INT0 & INT1
SREG |= 0x80; // Global Interrupt Enable
TCCR0 = 0x06; // Normal mode, prescale 256, 16M/256=62500Hz
TCNT0 = 0x00; // n=0, 256 count, 62500Hz/256=244.14Hz
TIMSK = 0x01; // timer0 OVERFLOW interrupt enable
PORTC = 0x00;
state=STOP; //시작 state는 stop
while (1) {
Run();
SHOW_NUMBER=SHOW_NUMBER12*100+SHOW_NUMBER34;
Show4Digit(SHOW_NUMBER);
} //Show_NUMBER는 세븐세그먼트 순서대로 천의자리부터 일의자리까지 각 숫자가 값을 가지는 천의자리 숫자입니다.

}




void Show4Digit(int number) {
COLUMN[0] = number/1000; //천의자리 표시
COLUMN[1] = (number%1000)/100; //백의자리 표시
COLUMN[2] = (number%100)/10; //십의자리 표시
COLUMN[3] = (number%10); //일의자리 표시
for(int i=0;i<4;i++) {
ShowDigit(COLUMN[i],i); //한 자릿수씩 숫자를 표현합니다.
_delay_ms(2); // wait for a second
}
}

void Run(void)
{
switch(state)
{
case STOP : break; // state가 STOP일 때 멈춘다.
case START: TIMER0_OVF_vect;
if(SHOW_NUMBER34>59)
{
SHOW_NUMBER12++;
if(SHOW_NUMBER12>59) SHOW_NUMBER12=0;
SHOW_NUMBER34=0; // state가 STATRT일 때 34자리는 1씩 올라가고, 34가 59보다 클 때, 12는 1씩 증가한다. 12가 59보다 크게되면 00.00이 된다.
}
break;
case INIT : SHOW_NUMBER12=0, SHOW_NUMBER34=0, state=STOP; //state가 INIT일 때 모두 0000으로 초기화하고 state=STOP으로 돌아간다.
break;

}
}
void ShowDigit(int i, int digit) {
PORTC=~(0x01<<digit);
if(digit==1)
PORTA = Segment_Data[i]|0x80; // 두 번째 세븐세그먼트의 dp포인트에 LED가 들어오게 함
else
PORTA = Segment_Data[i];
}
INT3을 누르면 stop이 되어야 하는데 안되는 상황입니다. 이해 가실까요?
mode가 stopwatch,freetopic일 때, INT2를 누르면 alarm으로 가고, mode가 alarm일 때 INT2를 다시 누르면 stopwatch.
mode가 stopwatch,alarm일 때, INT3를 누르면 freetopic으로 가고, mode가 freetopic일 때 INT3를 다시 누르면 stopwatch.
다음과 같이 작동하기 위해 INT2, INT3에 If를 다음과 같이 넣어준 것 입니다.

master님의 댓글

master 작성일

ISR(INT3_vect) {
if(state==START) state==STOP;
if(mode==mode_2_Free_Topic)mode==mode_0_Stop_Watch;
else mode==mode_2_Free_Topic;

대입은 == 가 아니고 = 입니다.
한 두군데가 아니군요

수제비성애자님의 댓글

수제비성애자 댓글의 댓글 작성일

진짜 기본적인 실수를 하고 있었네요.. 바쁘신 와중에 감사합니다.

master님의 댓글

master 작성일

EIMSK = 0x1F; // Set INT0 & INT1
INT4를 이네이블 시켰는데 INT4 함수는 안보입니다.
이네이블 시키고 함수가 없는 경우 엉뚱하게 동작하거나 먹통이 될 수도 있습니다.

수제비성애자님의 댓글

수제비성애자 댓글의 댓글 작성일

방금 확인해서 수정했습니다.. INT4도 쓰려다가 안쓰기로 바꿔서 실수한 것으로 보입니다. 친절한 답변 감사합니다.

질문게시판HOME > 질문게시판 목록

MCU, AVR, 아두이노 등 전자공학에 관련된 질문을 무료회원가입 후 작성해주시면 전문가가 답변해드립니다.
ATMEGA128PWMLED초음파
아두이노AVR블루투스LCD
UART모터적외선ATMEGA
전체 스위치 센서
질문게시판 목록
제목 작성자 작성일 조회
질문 atmega128 서보모터와 초음파센서댓글[1] 새글 tmiae 12:53 4
질문 아두이노 millis ->atmega128에서 사용하고 싶습니다. 새글 akmong413 22-05-19 23
답변 답변글 답변 : 아두이노 millis ->atmega128에서 사용하고 싶습니다. 새글 master 22-05-19 26
질문 ATMEGA128 TCCR2 = 0X0B가 의미하는것은 무엇인지 궁금합니다. dfas123 22-05-12 129
답변 답변글 답변 : ATMEGA128 TCCR2 = 0X0B가 의미하는것은 무엇인지 궁금합니다.댓글[1] master 22-05-12 141
질문 ATMEGA128 0번핀과1번핀 스위치를 누르면 LED점등 속도 제어댓글[3] dfas123 22-05-11 166
질문 Atmega128 led 왕복 점등 및 스위치 방향 전환댓글[1] MaeuM 22-05-06 287
질문 ATmega128 모터 질문드립니다댓글[6] zzammo 22-05-03 290
질문 Atmega128 led 점등 Eleccc 22-05-01 232
답변 답변글 답변 : Atmega128 led 점등댓글[8] master 22-05-01 338
질문 ATMEGA128 에 MQ-135 질문입니다댓글[4] 학생 22-04-30 247
질문 ATMEGA128 buzzer(스피커) 질문입니다.댓글[4] 이미지첨부파일 XOXO 22-04-29 231
질문 (ATmega128 LED점등)이 부분이 왜 오류가 뜨는건가요?댓글[3] 이미지첨부파일 isdpolicy 22-04-29 223
질문 Atmega128 UART 통신 관련 질문입니다.댓글[3] 현화 22-04-28 204
질문 ATmega128 lcd 관련 질문 있습니다.댓글[1] 첨부파일 순머 22-04-27 242
질문 Atmega128 공부중에 질문 있습니다댓글[4] 겔젠키르헨 22-04-27 231
질문 ATMEGA128 CTC MODE 모터조종 질문입니다댓글[2] 킹드나인 22-04-18 129
질문 AVR, atmega128에서 led 점등 코드댓글[5] 제발도와주세요 22-04-14 526
질문 atmega128 코딩중 잘 모르겠는 부분이 있어서 질문합니다.댓글[1] toemm 22-04-10 330
질문 atmega128 N초후 다른 동작 실행댓글[2] 킹드나인 22-04-10 274
질문 아두이노 코드를 atmega128 코드로 변환해주세요...댓글[2] toemm 22-04-09 328
질문 아두이노 코드를 atmega128 코드로 변환해주세요...댓글[1] toemm 22-04-09 224
질문 Avr atmega128 led 제어 질문드리겠습니다 임연수구이 22-04-04 420
답변 답변글 답변 : Avr atmega128 led 제어 질문드리겠습니다댓글[1] master 22-04-04 382
질문 Atmega128과 QR코드 호환에 대해댓글[1] 무뇌공돌이 22-03-24 663
질문 ATmega128 LoRa 통신 관련 질문드립니다.댓글[2] 부리부리이션 22-02-25 437
질문 ATMEGA128 음성인식 질문있습니다댓글[2] 학생 22-02-24 492
질문 atmega128 i2c통신관련질문입니다댓글[1] 학생 22-02-17 399
질문 ATmega128 질문있습니다댓글[1] 학생 22-02-15 413
질문 ATmega128 vs STM32F4댓글[1] 미미쨩 22-01-24 870
게시물 검색

2022년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2021년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2020년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2019년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2018년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
Privacy Policy
MCU BASIC ⓒ 2020
모바일버전으로보기