BASIC4MCU | 질문게시판 | 모터 엔코더 제어 질문드립니다.
페이지 정보
작성자 oreoreo 작성일2022-05-27 18:06 조회414회 댓글0건본문
안녕하세요 최근 들어 ATmega128 을 공부 시작하여 모터엔코더 를 통해 각도 제어를 해보려고 하는데요
현재 외부인터럽트를 사용하여 스위치 한개는 방향전환 , 한개는 PWM 출력을 통한 속도제어를 하였습니다
그에 추가하여 엔코더 카운터를 사용하여 한바퀴를 돌리고 엔코더 카운트 값을 시리얼 통신 터미널을 통해 출력을 해보려고 하는데요 .
제가 사용하는 모터 엔코더가 counts per turn 이 128 인 엔코더인데 1체배로 돌리고 있음에도 불구하고 약 엔코더카운트가 13200으로 설정을 하여야 한바퀴에서 멈추고 터미널에서는
엔코더 카운트 통신값도 매번 다르게 나오더라구요. 제가 공부한 바에 따르면 따르면 엔코더 카운트 값이 128에서 한바퀴가 되어야 하는걸로 알고 있는데 어디서 틀린지 모르겠네요ㅠ..
만약 한바퀴에 엔코더 카운트 값이 13200이라 하더라도 13200 의 값이 항상 나오도록 하려는 의도로 작성하였는데 혹시 잘못된 부분이 있다면 지적 가능할까요?
시작한지 얼마안되어 굉장히 지저분하고 부족한 점 죄송합니다.
______________메인________________________________________
#include <mega128.h>
#include <delay.h>
#include <stdio.h>
char flag = 0, flag2 = 0;
signed long encodercount = 0;
void main(void)
{
DDRB = 0xff; // 모터 출력 설정
DDRE = 0x00; // 스위치 입력 설정
DDRD = 0x00;
UCSR0A = 0x0; //통신 인터럽트 설정
UCSR0B = 0b00011000;
UCSR0C = 0b00000110;
UBRR0H = 0;
UBRR0L = 103;
EIMSK = 0b11000010; // 외부 인터럽트 인에이블
TIMSK = 0x04;
//타이머 설정
TCCR1A = 0x00;
TCCR1B = 0x03;
TCCR1C = 0x0;
TCNT1 = 0;
TCCR0 = 0x6f; //PWM 모드 설정 , 1024 분주비
TCNT0 = 100;
TCCR2 = 0x6d;
TCNT2 = 100;
OCR0 = 0;
OCR2 = 0;
EICRA = 0b00001000;
EICRB = 0b10100000; //하강엣지
DDRC = 0xff;
PORTC = 0xff;
SREG = 0x80; //전역인터럽트 인에이블
while(1);
}
_______________________________메인 ____________________________
_________________________인터럽트 핸들러_________________________
#include <mega128.h>
#include <stdio.h>
#include <delay.h>
extern char flag, flag2;
extern signed long encodercount;
interrupt [EXT_INT6] void SW_0(void)
{
flag = ++flag%4;
if(flag2 == 0) // 스위치 정방향 회전중 동작
{
if(flag == 0)
{
OCR0 = 70;
PORTC = 0b01111110;
encodercount = 0;
}
if(flag == 1)
{
OCR0 = 130;
PORTC = 0b01111101;
encodercount = 0;
}
if(flag == 2)
{
OCR0 = 180;
PORTC = 0b01111011;
encodercount = 0;
}
if(flag == 3)
{
OCR0 = 240;
PORTC = 0b01110111;
encodercount = 0;
}
}
else // 스위치 역방향 회전중 동작
{
if(flag == 0)
{
OCR2 = 70;
PORTC = 0b10111110;
encodercount = 0; //
}
if(flag == 1)
{
OCR2 = 130;
PORTC = 0b10111101;
encodercount = 0;
}
if(flag == 2)
{
OCR2 = 180;
PORTC = 0b10111011;
encodercount = 0;
}
if(flag == 3)
{
OCR2 = 240;
PORTC = 0b10110111;
encodercount = 0;
}
};
}
interrupt [EXT_INT7] void SW_1(void) // 정회전, 역회전 변환
{
flag2=++flag2%2;
if(flag2 == 0)
{
PORTB = 0b10000001;
OCR2 = 0;
encodercount = 0;
}
if(flag2 == 1)
{
PORTB = 0b00010001;
OCR0 = 0;
encodercount = 0;
}
}
interrupt [EXT_INT1] void enc_0(void) // 엔코더 카운터 동작
{
if(PIND.0) //정방향시 카운터 1상승
encodercount--; //역방향 카운터 1하강
else
encodercount++;
if (encodercount >30000)
encodercount = 0;
if (encodercount <-30000)
encodercount = 0;
if(encodercount == 13200) PORTB = 10010001,OCR0 = 0,OCR2 = 0; // 정방향 약 한바퀴 제어
if(encodercount == -13200) PORTB = 10010001,OCR0 = 0,OCR2 = 0; // 역방향 약 한바퀴 제어
}
interrupt [TIM1_OVF] void enc_1(void) //타이머 오버플로우 인터럽트마다 통신
{
while(!(UCSR0A & 0x20));
UDR0 = encodercount;
}
_____________________________인터럽트 핸들러__________________________________________
댓글 0
조회수 414등록된 댓글이 없습니다.