BASIC4MCU | 질문게시판 | 코드비전 외부인터럽트
페이지 정보
작성자 HOTDOKYU 작성일2021-07-22 10:59 조회19,148회 댓글8건본문
코드비전 외부 인터럽트 관련 질문입니다.
코드를 작성해 보았으며 코드를 돌렸을시 문제가 없다고 나옵니다.
허나 나오는 화면은 페이지 전환 및 아이콘 회전 그 후 비밀번호 입력 창 대기 (무한 반복으로 나오게 됩니다.)
AVR은 내부 인터럽트 말고 외부 인터럽트를 많이 사용한다고 하여 질문합니다.처음 동작은 MCU에서 LCD로 신호를 주어 LCD를 동작하게 하는 것 이며
외부 인터럽트 동작 (0번)으로 지정하였으며LCD에서 정해진 신호가 들어오면 동작하게 끔 설계하고 싶습니다.
아래의 코드가 맞는 것 인가요 ?
아니면 따로 동작 시작이라는 코드를 추가해야 하나요 ?
여러 번 예제를 찾아보고 생각해 보았으며 고민을 해 봤는데 답이 나오지 않아 여기에 글을 남깁니다....방향성을 찾아주세요 .......
아래의 내용에 코드를 첨부하였습니다.
부탁드리겠습니다.감사합니다:)
#include <mega128.h>
#include <delay.h>
#include <stdio.h>
char rx0_char();
char rx1_char();
void tx0_char(char c);
void tx1_char(char c);
void TX0_str(char *s);
void TX1_str(char *s);
void page_ch2();
void page_ch3();
void icon_ro();
void page_ch();
char page_Change0[10]={0x5A,0xA5,0x07,0x82,0x00,0x84,0x5A,0x01,0x00,0x01};
char page_Change1[10]={0x5A,0xA5,0x07,0x82,0x00,0x84,0x5A,0x01,0x00,0x02};
char icon_roll_0[8]={0x5A,0xA5,0x05,0x82,0x10,0x80,0x00,0x00};
char icon_roll_1[8]={0x5A,0xA5,0x05,0x82,0x10,0x80,0x00,0x90};
char icon_roll_2[8]={0x5A,0xA5,0x05,0x82,0x10,0x80,0x00,0xB4};
char icon_roll_3[8]={0x5A,0xA5,0x05,0x82,0x10,0x80,0x00,0xFF};
char page_charge_1[10]={0x5A,0xA5,0x07,0x82,0x00,0x84,0x5A,0x01,0x00,0x04};
char page_charge_2[10]={0x5A,0xA5,0x07,0x82,0x00,0x84,0x5A,0x01,0x00,0x05};
char page_charge_3[10]={0x5A,0xA5,0x07,0x82,0x00,0x84,0x5A,0x01,0x00,0x0D};
char rx0_char(void){ while(!(UCSR0A&0x80)); return UDR0; }
char rx1_char(){ while(!(UCSR1A&0x80)); return UDR1; }
void tx0_char(char c){ while(!(UCSR0A&0x20)); UDR0=c; }
void tx1_char(char c){ while(!(UCSR1A&0x20)); UDR1=c; }
void TX0_str(char *s){ while(*s)tx0_char(*s++); }
void TX1_STR(char *s){ while(*s)tx1_char(*s++); }
char psw[9] = {0x5A,0xA5,0x06,0x83,0x10,0x00,0x01,0xD2,0x00};
char i=0;
interrupt [EXT_INT0] void ext_int0_isr(void)
{
rx0_char();
if (UDR0==0x5A,0xA5,0x06,0x83,0x10,0x00,0x01,0xD2,0x00)
{
page_ch2();
}
else
{
page_ch3();
}
EIFR = 0xFF; ///인터럽트 초기화
}
interrupt [EXT_INT1] void ext_int1_isr(void)
{
///아직 사용하지 X
}
/*interrupt [USART0_RXC] void usart0_rx0_isr(void){ // 내부 USART0수신 인터럽트
char r0data;
r0data=UDR0;
page_ch3();
}
interrupt [USART1_RXC] void usart1_rx1_isr(void){ // 내부 USART1 수신 인터럽트
char r1data;
r1data=UDR1;
tx1_char(rx0_char());
}
*/
void page_ch() //paage 1~2번 자동 응답
{
char cnt =0 ;
for (cnt=0;cnt<10;cnt++)
{
tx0_char(page_Change0[cnt]);
}
for (cnt=0;cnt<10;cnt++)
{
tx0_char(page_Change1[cnt]);
}
}
void icon_ro() /// 2번 page 아이콘 회전
{
char cnt =0;
for (cnt=0;cnt<8;cnt++)
{
tx0_char(icon_roll_0[cnt]);
delay_ms(50);
}
for (cnt=0;cnt<8;cnt++)
{
tx0_char(icon_roll_1[cnt]);
delay_ms(50);
}
for (cnt=0;cnt<8;cnt++)
{
tx0_char(icon_roll_2[cnt]);
delay_ms(50);
}
for (cnt=0;cnt<8;cnt++)
{
tx0_char(icon_roll_3[cnt]);
delay_ms(50);
}
}
void page_ch1() //// 비밀번호 입력창 페이지 호출
{
char cnt = 0;
for (cnt=0;cnt<10;cnt++)
{
tx0_char(page_charge_1[cnt]);
}
}
void page_ch2() // 비밀번호 맞으면 메인 페이지
{
char cnt=0;
for (cnt=0;cnt<10;cnt++)
{
tx0_char(page_charge_2[cnt]);
}
}
void page_ch3() // 비밀번호 틀리면 worring page
{
char cnt = 0;
for (cnt=0;cnt<10;cnt++)
{
tx0_char(page_charge_3[cnt]);
}
}
void main()
{
//UCSR0B=0x98;
//UCSR1B=0x98;
UCSR0B=0x18; UBRR0L=8; // baud 115200
UCSR1B=0x18; UBRR1L=8; // baud 115200
page_ch(); ///page 1~2
delay_ms(1000); //1 second delay
icon_ro(); /// 2page icon roll
delay_ms(2000); /// 2 second delay
page_ch1(); //// password page
delay_ms(5000); //// 5second delay (input password)
EIMSK = 0x01; //0번 인에이블 FF
EICRA = 0x03; // 0번 falling edge 모드 사용 AA ////03 (상승엣지)
#asm("sei") //인터럽트 인에이블
SREG=0x80;
while(1)
{
// your code
}
}
댓글 8
조회수 19,148master님의 댓글
master 작성일코드를 돌렸을시 문제가 없다고 나옵니다. <-- 컴파일 오류가 없는 것하고 원하는대로 동작하는 것 하고는 아무런 관련이 없습니다.
master님의 댓글
master 작성일AVR은 내부 인터럽트 말고 외부 인터럽트를 많이 사용한다고 하여 <-- 내부 인터럽트란 무슨 인터럽트를 말하는 것일까요?
HOTDOKYU님의 댓글
HOTDOKYU
UART0 인터럽트를 내부 인터럽트로 이해하였습니다.
그냥 현재 외부 인터트를 사용하면 될 것 같습니다.
master님의 댓글
master 작성일
LCD에서 정해진 신호가 들어오면 <-- LCD에서 무슨 신호가 들어온다는 것일까요?
LCD는 출력장치이며, 입력장치가 아닙니다.
master님의 댓글
master 작성일
if(UDR0==0x5A,0xA5,0x06,0x83,0x10,0x00,0x01,0xD2,0x00)
무슨 생각으로 작성한 코드일까요?
UART 경험이 전혀 없으신가 보군요
(UDRx) 레지스터를 직접 if()문에서 비교하는데 사용해서는 안되며
UDR0 레지스터는 수신이 완료된 후에 1바이트만 읽을 수 있습니다.
여러바이트를 수신하고 싶다면 버퍼에 차례대로 1바이트씩 저장해야 합니다.
여러 바이트의 비교는 memcmp() 함수 사용법을 공부하세요
HOTDOKYU님의 댓글
HOTDOKYU
버퍼를 차례대로 1바이트씩 저장하면 그 정해진 값을 읽어서 호출 할 수 있군요 .
여러바이트를 수신해서 읽고 응답하고 싶으니 버퍼를 만들어 저장 후 memcmp()함수를 사용해 보겠습니다.
master님의 댓글
master 작성일
#include <mega128.h>
#include <delay.h>
#include <stdio.h>
//
char page_Change0[10]={0x5A,0xA5,0x07,0x82,0x00,0x84,0x5A,0x01,0x00,0x01};
char page_Change1[10]={0x5A,0xA5,0x07,0x82,0x00,0x84,0x5A,0x01,0x00,0x02};
char icon_roll_0[8]={0x5A,0xA5,0x05,0x82,0x10,0x80,0x00,0x00};
char icon_roll_1[8]={0x5A,0xA5,0x05,0x82,0x10,0x80,0x00,0x90};
char icon_roll_2[8]={0x5A,0xA5,0x05,0x82,0x10,0x80,0x00,0xB4};
char icon_roll_3[8]={0x5A,0xA5,0x05,0x82,0x10,0x80,0x00,0xFF};
char page_charge_1[10]={0x5A,0xA5,0x07,0x82,0x00,0x84,0x5A,0x01,0x00,0x04};
char page_charge_2[10]={0x5A,0xA5,0x07,0x82,0x00,0x84,0x5A,0x01,0x00,0x05};
char page_charge_3[10]={0x5A,0xA5,0x07,0x82,0x00,0x84,0x5A,0x01,0x00,0x0D};
char psw[9]={0x5A,0xA5,0x06,0x83,0x10,0x00,0x01,0xD2,0x00};
char i=0;
//
char rx0_char(void){ while(!(UCSR0A&0x80)); return UDR0; }
char rx1_char(){ while(!(UCSR1A&0x80)); return UDR1; }
void tx0_char(char c){ while(!(UCSR0A&0x20)); UDR0=c; }
void tx1_char(char c){ while(!(UCSR1A&0x20)); UDR1=c; }
void TX0_str(char *s){ while(*s)tx0_char(*s++); }
void TX1_STR(char *s){ while(*s)tx1_char(*s++); }
//
void icon_ro(){ // 2번 page 아이콘 회전
char cnt=0;
for(cnt=0;cnt<8;cnt++){ tx0_char(icon_roll_0[cnt]); delay_ms(50); }
for(cnt=0;cnt<8;cnt++){ tx0_char(icon_roll_1[cnt]); delay_ms(50); }
for(cnt=0;cnt<8;cnt++){ tx0_char(icon_roll_2[cnt]); delay_ms(50); }
for(cnt=0;cnt<8;cnt++){ tx0_char(icon_roll_3[cnt]); delay_ms(50); }
}
//
void page_ch(){ // paage 1~2번 자동 응답
char cnt=0 ;
for(cnt=0;cnt<10;cnt++)tx0_char(page_Change0[cnt]);
for(cnt=0;cnt<10;cnt++)tx0_char(page_Change1[cnt]);
}
//
void page_ch1(){ // 비밀번호 입력창 페이지 호출
char cnt=0;
for(cnt=0;cnt<10;cnt++)tx0_char(page_charge_1[cnt]);
}
//
void page_ch2(){ // 비밀번호 맞으면 메인 페이지
char cnt=0;
for(cnt=0;cnt<10;cnt++)tx0_char(page_charge_2[cnt]);
}
//
void page_ch3(){ // 비밀번호 틀리면 worring page
char cnt=0;
for(cnt=0;cnt<10;cnt++)tx0_char(page_charge_3[cnt]);
}
//
interrupt [EXT_INT0] void ext_int0_isr(void){
rx0_char();
if(UDR0==0x5A,0xA5,0x06,0x83,0x10,0x00,0x01,0xD2,0x00)page_ch2();
else{ page_ch3(); }
EIFR=0xFF; ///인터럽트 초기화
}
//
interrupt [EXT_INT1] void ext_int1_isr(void){
// 아직 사용하지 X
}
//
/*
interrupt [USART0_RXC] void usart0_rx0_isr(void){ // 내부 USART0수신 인터럽트
char r0data; r0data=UDR0; page_ch3();
}
//
interrupt [USART1_RXC] void usart1_rx1_isr(void){ // 내부 USART1 수신 인터럽트
char r1data;
r1data=UDR1;
tx1_char(rx0_char());
}
*/
//
void main(){
//UCSR0B=0x98; UCSR1B=0x98;
UCSR0B=0x18; UBRR0L=8; // baud 115200
UCSR1B=0x18; UBRR1L=8; // baud 115200
page_ch(); delay_ms(1000); // page 1~2
icon_ro(); delay_ms(2000); // 2page icon roll
page_ch1(); delay_ms(5000); // password page
EIMSK=0x01; EICRA=0x03; // 0번 falling edge 모드 사용 AA // 03(상승엣지)
SREG=0x80;
while(1){}
}
첨부 코드 중 일부 코드는 제가 만든 예제와 비슷합니다.
https://cafe.naver.com/circuitsmanual/1222
게시판에서 "232 통신의 기초"로 검색해서 6개의 글을 읽어보세요
master님의 댓글
master 작성일
//
#include <mega128.h>
#include <delay.h>
#include <stdio.h>
#include <string.h>
//
//char psw[9]={0x5A,0xA5,0x06,0x83,0x10,0x00,0x01,0xD2,0x00};
char i=0;
bit r0_flag=0,int0_flag=0;
//
//char rx0_char(void){ while(!(UCSR0A&0x80)); return UDR0; }
char rx1_char(){ while(!(UCSR1A&0x80)); return UDR1; }
void tx0_char(char c){ while(!(UCSR0A&0x20)); UDR0=c; }
void tx1_char(char c){ while(!(UCSR1A&0x20)); UDR1=c; }
void TX0_str(char *s){ while(*s)tx0_char(*s++); }
void TX1_STR(char *s){ while(*s)tx1_char(*s++); }
//
void icon_ro(){ // 2번 page 아이콘 회전
char icon_roll_0[8]={0x5A,0xA5,0x05,0x82,0x10,0x80,0x00,0x00};
char icon_roll_1[8]={0x5A,0xA5,0x05,0x82,0x10,0x80,0x00,0x90};
char icon_roll_2[8]={0x5A,0xA5,0x05,0x82,0x10,0x80,0x00,0xB4};
char icon_roll_3[8]={0x5A,0xA5,0x05,0x82,0x10,0x80,0x00,0xFF};
char cnt=0;
for(cnt=0;cnt<8;cnt++){ tx0_char(icon_roll_0[cnt]); delay_ms(50); }
for(cnt=0;cnt<8;cnt++){ tx0_char(icon_roll_1[cnt]); delay_ms(50); }
for(cnt=0;cnt<8;cnt++){ tx0_char(icon_roll_2[cnt]); delay_ms(50); }
for(cnt=0;cnt<8;cnt++){ tx0_char(icon_roll_3[cnt]); delay_ms(50); }
}
//
void page_ch(){ // paage 1~2번 자동 응답
char page_Change0[10]={0x5A,0xA5,0x07,0x82,0x00,0x84,0x5A,0x01,0x00,0x01};
char page_Change1[10]={0x5A,0xA5,0x07,0x82,0x00,0x84,0x5A,0x01,0x00,0x02};
char cnt=0 ;
for(cnt=0;cnt<10;cnt++)tx0_char(page_Change0[cnt]);
for(cnt=0;cnt<10;cnt++)tx0_char(page_Change1[cnt]);
}
//
void page_ch1(){ // 비밀번호 입력창 페이지 호출
char page_charge_1[10]={0x5A,0xA5,0x07,0x82,0x00,0x84,0x5A,0x01,0x00,0x04};
char cnt=0;
for(cnt=0;cnt<10;cnt++)tx0_char(page_charge_1[cnt]);
}
//
void page_ch2(){ // 비밀번호 맞으면 메인 페이지
char page_charge_2[10]={0x5A,0xA5,0x07,0x82,0x00,0x84,0x5A,0x01,0x00,0x05};
char cnt=0;
for(cnt=0;cnt<10;cnt++)tx0_char(page_charge_2[cnt]);
}
//
void page_ch3(){ // 비밀번호 틀리면 worring page
char page_charge_3[10]={0x5A,0xA5,0x07,0x82,0x00,0x84,0x5A,0x01,0x00,0x0D};
char cnt=0;
for(cnt=0;cnt<10;cnt++)tx0_char(page_charge_3[cnt]);
}
//
interrupt [EXT_INT0] void ext_int0_isr(void){ int0_flag=1; }
//
//interrupt [EXT_INT1] void ext_int1_isr(void){}
//
interrupt [USART0_RXC] void usart0_rx0_isr(void){
char r_msg[9]={0x5A,0xA5,0x06,0x83,0x10,0x00,0x01,0xD2,0x00};
char r0;
r0=UDR0; UDR1=r0;
if(r0_cnt==0){
if(r0==0x5A)rx0_buf[r0_cnt++]=r0; else r0_cnt=0;
}
else if(r0_cnt==1){
if(r0==0xA5)rx0_buf[r0_cnt++]=r0; else r0_cnt=0;
}
else{
if(r0_cnt<15)rx0_buf[r0_cnt++]=r0; else r0_cnt=0;
if(r0_cnt==(rx0_buf[2]+3)){
if(!memcmp(rx0_buf,r_msg,9))r0_flag=1;
}
}
}
//
//interrupt [USART1_RXC] void usart1_rx1_isr(void){ UDR0=UDR1; }
//
void main(){
UCSR0B=0x98; UBRR0L=8; // baud 115200
UCSR1B=0x18; UBRR1L=8; // baud 115200
page_ch(); delay_ms(1000); // page 1~2
icon_ro(); delay_ms(2000); // 2page icon roll
page_ch1(); delay_ms(5000); // password page
EICRA=0xFF; EIFR=0xFF; EIMSK=1; // 상승엣지
SREG=0x80;
while(1){
if(int0_flag){ int0_flag=0;
if(r0_flag){ r0_flag=0; page_ch2(); }
else{ page_ch3(); }
}
}
}