질문게시판 > atmega128 dc모터정/역제어 질문드립니다.

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

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


BASIC4MCU | 질문게시판 | atmega128 dc모터정/역제어 질문드립니다.

페이지 정보

작성자 ddongew 작성일2021-09-13 17:58 조회497회 댓글10건

본문

	

ISR(INT1_vect)//정방향, 역방향

{

 

if(state==0)

{

TCCR0=0x6a;

_delay_ms(50);

PORTB=0x08;

state=(state+1)%2;

}

else

{

TCCR0=0x7a;

_delay_ms(50);

PORTB=~0x08;

state=(state+1)%2;

}

}

 

코드를 위와같이 작성하였는데

ISR에서 딜레이함수를 주는 이유가 mcu(16MHz)가 너무 빨라서 버튼이 안먹히는 경우를 방지하기위해 사용하는건가요??

 

만약 그렇다면 딜레이함수를 쓰면 프로그램이 정지되어 멀티태스킹이 불가해지때문에

void delay()

{

for(i=0; i<100; i++);

}

위와 같은 for문으로 _delay_ms()함수의 역할의 대신해도 되는건가요..?

 

  • BASIC4MCU 작성글 SNS에 공유하기
  • 페이스북으로 보내기
  • 트위터로 보내기
  • 구글플러스로 보내기

댓글 10

조회수 497

master님의 댓글

master 작성일

스위치가 외부 인터럽트에 연결되어 있고, 50ms의 딜레이를 사용하는 경우에는
스위치 채터링 방지용이라고 보시면 됩니다.
단, 인터럽트를 빠져나가기 전 마지막에 인터럽트 플래그를 claer 시켜줘야 합니다.

ddongew님의 댓글

ddongew 댓글의 댓글 작성일

답변 감사합니다 ㅜㅜ
그럼 스위치버튼을 눌렀을때 안먹히는 이유가 채터링현상 때문인가요?
채터링 방지용도로 사용한거면 저 위치에 딜레이함수를 쓰는것이 맞나요?? 왜 저 위치에 딜레이함수른 썼는지 이해가 되지 않습니다..

master님의 댓글

master 댓글의 댓글 작성일

스위치가 안 먹히는 이유는
하드웨어 문제가 있을 수도 있고, 프로그램 문제가 있을 수도 있습니다.
전체소스코드를 첨부하세요

ddongew님의 댓글

ddongew 댓글의 댓글 작성일

네,,. 전체코드 첨부했는데
한번만 봐주시면 감사하겠습니다ㅜㅜ

#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>

void UART_init();
void UART_TX0(unsigned char data);

FILE OUTPUT
=FDEV_SETUP_STREAM(UART_TX0, NULL, _FDEV_SETUP_WRITE);


volatile  unsigned int cnt=0;//엔코더 신호 발생시 증가될 변수
volatile unsigned int state=0;
volatile unsigned int time_cnt=0;
volatile int rpm=0;

void INIT_Uart()//기본 통신 설정
{
UBRR0H = 0;
UBRR0L = 207; //Baud Rate = 9600
UCSR0B |= (1<<TXEN0); //송신부 동작 활성화
UCSR0B |= (1<<RXEN0); // 수신부 동작 활성화
UCSR0C |= 0x06; //0b00000110 비동기, 8비트 데이터, 패리티 없음, 1비트 정지 모드
}
void UART_TX0(unsigned char data)
{
while(!(UCSR0A&(1<<UDRE0))); //UDR0가 안 비어있으면 무한루프
UDR0=data; //UDR0가 비었으면 WHILE을 종료하고 새로운 데이터 WRITE
}
void INIT_INT(void)
{
DDRD=0b10000000;//PD0,PD1,PD2을 출력으로 설정, PD3(INT3)엔코더 신호 입력 포트
PORTD=0b10001111;//PD3외부풀업 on, PD0,PD1,PD2 내부풀업 on
EIMSK =0b00001111;//0,1,2,3번 인터럽트 허용
EICRA =0b10101010;//INT0, INT1, INT2,INT3을 하강모서리에서 인터럽트 발생

}
void INIT_Timer(void)
{
DDRB=0xff;
PORTB=0x08;
//TCNT0 = 0x00;
TCCR0=0x6a; //0b01101010 fast pwm, clear on compare match, 8분주

TCCR2=0x01; //normal mode, 분주 안함
TIMSK=0b01000000;

}
ISR(INT1_vect)//정방향, 역방향
{

if(state==0)
{
TCCR0=0x6a;
_delay_ms(50);
PORTB=0x08;
state=(state+1)%2;
}
else
{
TCCR0=0x7a;
_delay_ms(50);
PORTB=~0x08;
state=(state+1)%2;
}
}
ISR(INT2_vect)//속도 증가
{
OCR0-=5;
_delay_ms(50);
}
ISR(INT0_vect)//속도 감소
{
OCR0+=5;
_delay_ms(50);

}

ISR(INT3_vect)
{
cnt++;
}
ISR(TIMER2_OVF_vect)
{
time_cnt++;// 1/62500초마다 1씩 증가
if(time_cnt == 62500) //1초에 한 번씩 RPM계산
{
rpm = ((cnt)*60)/(13*30); //(펄스카운트 / 엔코더 사양 13pluse * (감속비 30)) x 60초
printf("cnt = %d  rpm = %d\r\n",cnt,rpm);
cnt =0;
time_cnt=0;
}
}
int main(void)
{

stdout=&OUTPUT;
INIT_INT();
INIT_Timer();
INIT_Uart();
sei();


while (1)
{

}
return 0;
}

master님의 댓글

master 작성일

for문이든 아니든 어차피 같은 시간 딜레이를 가질텐데요
인터럽트 안에서 딜레이를 사용하면 그 시간동안은 메인은 실행되지 않습니다.
인터럽트 함수를 모두 마친 후에 메인이 실행 됩니다.
//
타이머 인터럽트에서 스위치를 체크하면 딜레이 없이 처리가 가능합니다.
예를들면 50ms 주기의 타이머 인터럽트에서 스위치를 체크하면 50ms 딜레이를 사용한 효과가 생깁니다.

master님의 댓글

master 작성일

50ms 딜레이가 길다고 생각되면
1ms 주기의 타이머 인터럽트를 만들고, 같은 값이 50번이상 동일하게 입력되었을 경우마다 스위치를 체크하는 식으로 처리해도 됩니다.
물론 코드는 많이 복잡해집니다.
10ms 주기에서 5번 같은 값인 것을 체크해서 처리하면 좀 더 간단할 수도...

master님의 댓글

master 작성일

UCSR0B=0x18; UBRR0L=207; //Baud Rate = 9600
mcu 퓨즈비트 클럭 설정을 제대로 하지 못해서 내부 클럭으로 동작하므로 2배속 설정 해야지 9600이 되는겁니다.
내부 클럭은 정밀도가 없어서 통신오류가 많으므로 외부 X-TAL로 동작하려면 퓨즈비트 클럭설정을 제대로하세요

16MHz X-TAL이 아닌 내부 8MHz로 구동하는 경우
uart는 보레이트를 19200으로 속여서 설정했다 치더라도
타이머 설정도 모두 달라져야 하며, 전체 코드 실행속도가 2배로 느려집니다.

master님의 댓글

master 작성일

ISR(TIMER2_OVF_vect){ // 16us
가장 짧은 주기의 인터럽트는 16us입니다.
모든 인터럽트 안의 코드 실행 시간의 합이 16us보다 짧아야지 문제가 생기지 않는데
50ms 딜레이도 몇개씩 보이고, 곱하기 및 나누기 연산 등 시간이 많이 걸리는 인터럽트도 있으니 당연히 문제가 생깁니다.
예를들면 50ms 동안에는 3125번의 타이머2 인터럽트 발생을 무시하게 됩니다.
시간오차가 50ms 생기는 것이죠
딜레이 및 연산이 없다고 하더라도 코드 실행 시간의 합이 16us를 넘을 것으로 보입니다.
애당초 16us처럼 짧은 인터럽트는 만들면 안되는 것이죠

master님의 댓글

master 작성일

#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include <stdio.h>
//
volatile char flag=0;
volatile unsigned int rpm=0,cnt=0,cnt1; //엔코더
//
char U0_RX(void){ while(!(UCSR0A&0x80)); return UDR0; }
void U0_TX(char c){ while(!(UCSR0A&0x20)); UDR0=c; }
void U0_STR(char *s){ while(*s)U0_TX(*s++); }
//
ISR(INT0_vect){ TCCR0^=0x10; PORTB^=8; } // 정방향, 역방향
ISR(INT3_vect){ cnt++;                } // 엔코더 신호
//
ISR(TIMER1_COMPA_vect){ cnt1=cnt; cnt=0; flag=1; } // 1sec
//
ISR(TIMER3_COMPA_vect){  // 50ms
  if((PIND&1)==0){ if(OCR0<=250)OCR0+=5; } // PD0 속도 감소
  if((PIND&4)==0){ if(OCR0>=  0)OCR0-=5; } // PD2 속도 증가
}
//
int main(void){
  char str[50];
  DDRB=0xff; PORTB=0x08;
  DDRD=0x80; PORTD=0x8F;
  TCCR0=0x6a;                          // fast pwm
  TCCR1B=0x0C; OCR1A=62499; TIMSK=0x10; // 1sec
  TCCR3B=3;    TCNT3=53036; ETIMSK=4;  // 50ms
  UCSR0B=0x18; UBRR0L=103;              // 9600
  EICRA=0xAA;  EIMSK=0x09;              // int0,int3
  sei();
  while(1){
    if(flag){ flag=0;
      rpm=(int)((float)cnt1*0.1538461538461538); //(펄스카운트 / 엔코더 사양 13pluse * (감속비 30)) x 60초
      sprintf(str,"cnt=%d rpm=%d\r\n",cnt1,rpm); U0_STR(str);
    }
  }
  return 0;
}

ddongew님의 댓글

ddongew 작성일

답변 감사합니다!

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

MCU, AVR, 아두이노 등 전자공학에 관련된 질문을 무료회원가입 후 작성해주시면 전문가가 답변해드립니다.
ATMEGA128PWMLED초음파
아두이노AVR블루투스LCD
UART모터적외선ATMEGA
전체 스위치 센서
질문게시판 목록
제목 작성자 작성일 조회
공지 MCU, AVR, 아두이노 등 전자공학에 관련된 질문은 질문게시판에서만 작성 가능합니다. 스태프 19-01-15 3792
공지 사이트 이용 안내댓글[17] master 17-10-29 21911
질문 외부 인터럽트 사용시 버튼먹힘에 대해 질문드립니다. 새글 ddongew 21-09-18 4
질문 mcu퓨즈비트 설정 관련 문의드립니다. 이미지새글 ddongew 21-09-18 5
질문 아두이노 high side current 새글 rrldhh 21-09-18 9
질문 아두이노 IRremote, buzzer댓글[1] 새글 히이우이 21-09-17 17
질문 각각 블루투스 연결하고 물체간의 거리가 멀어지면 부저 울리는 작동하려고 하는데 도와주세요댓글[1] 새글 hiworld 21-09-17 28
질문 아두이노 스텝 모터 제어 질문입니다!!댓글[5] 새글 수민이 21-09-17 127
질문 타이머 카운터 1을 10비트 분해능의 Fast PWM 모드로 설정하고 내부 클럭을 8분주시켜 이거 혹시 어…댓글[2] 지용이용 21-09-16 18
질문 라즈베리 시리얼 질문댓글[1] 첨부파일 잘하자 21-09-16 19
질문 초음파센서 소리부저 질문입니다.댓글[7] 이미지 rrrrrr1 21-09-16 314
질문 Atmega128 관련 질문입니다.댓글[7] 이미지 허깅 21-09-16 262
질문 네오픽셀 스트립제어에대해 질문 있습니다.댓글[2] 이미지 혜인 21-09-15 14
질문 아두이노 블루투스 + 기타 센서 연결댓글[2] 이미지첨부파일 곰도리 21-09-15 44
질문 아두이노 led 스위치 제어질문이요 ㅠㅠ댓글[3] 이미지첨부파일 아두리노 21-09-14 99
질문 String 형태로 저장하고 불러오기댓글[1] 이미지첨부파일 너니미나 21-09-14 23
질문 아두이노 심박수측정모듈 sen0203댓글[1] 첨부파일 basle 21-09-14 30
질문 lcd에 숫자를 000/000 형태로 출력하기댓글[1] 스윗엘리 21-09-14 28
현재글 atmega128 dc모터정/역제어 질문드립니다.댓글[10] ddongew 21-09-13 498
질문 라인트레이서 초보 질문..댓글[2] 윤철 21-09-13 51
질문 초음파센서를 이용하여 거리 측정 질문입니다 수민이 21-09-13 35
답변 답변글 답변 : 초음파센서를 이용하여 거리 측정 질문입니다댓글[1] master 21-09-13 38
질문 uart통신 baudrate 질문드립니다.댓글[3] ddongew 21-09-13 81
질문 아두이노 이 회로는 작동에 이상 없을까요?댓글[1] 이미지첨부파일 아두리노 21-09-12 42
질문 atmega128 led 코드 관련 질문드립니다 gyulgyul 21-09-11 57
답변 답변글 답변 : atmega128 led 코드 관련 질문드립니다 master 21-09-13 49
질문 아두이노 우노 질문입니다.댓글[1] 이미지 미나리 21-09-10 45
질문 아두이노 우노 질문이요댓글[2] 곰도리 21-09-10 56
질문 UART0 시리얼 통신과 HZ 카운터 프로그램인데..?댓글[1] 명란젓코난 21-09-09 46
질문 아두이노 스텝모터 적외선 리모컨으로 제어하기댓글[9] 이미지첨부파일 아두빡치노 21-09-08 489
게시물 검색

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
모바일버전으로보기