Did you know that you can navigate the posts by swiping left and right?

타이머 및 서보모터 원리

16 Jan 2018 . category: tech . Comments
#interrupt #servo motor #mechatronics #science knowledge

인터럽트 개념을 배웠고 그 다음으로 타이머/카운터를 이용하는 것을 배웠는데 이를 이용하기 위해서 어떤 모드를 사용할 것인지를 우선적으로 생각하고 코딩을 해야했다. 이 모드에는 일반모드, CTC모드, Fast PWM모드, PC PWM모드가 있는데 나는 주로 일반모드와 CTC모드를 사용했는데 TCNTx로 인터럽트 주기를 정해주고 OCRx(비교값)로 어느지점에서 조건을 또 수행할지 정해준다. 제어, 마스크, 상태 레지스터는 전에 배운대로 지정해주고 이렇게 자신이 원하는 타이머를 쓸 수 있게 된다.

이후에 직접 서보모터를 테스트보드에 연결해 모터를 돌려보았는데 신호선은 PORTC에 연결해 PORTC = HIGH와 PORTC = LOW로 모터수행을 할 수 있도록 하였다. 초기에 특정한 값을 지정해주고 임의의 변수로 증가값을 받는 변수를 지정해줘서 두 값을 비교하면서 위의 HIGH와 LOW로 모터를 돌려준다. (이건 익숙해질때까지 직접 코딩해보는게 좋을 것 같다.)

다음은 avr책에서 본 코딩을 내 test board에 맞게 코딩해본것이다.

#include <mega128.h>
#include <delay.h>
#include <alcd.h>

#define Switch_1 (!PINE.4)
#define Switch_2 (!PINE.5)
#define Switch_3 (!PINE.6)

unsigned int tim0_cnt, mot_pos, change;
unsigned int rc_time[3] = {56, 152, 252};

void main()
{        
    DDRC = 0xFF;     //포트 C 출력 설정
    
    tim0_cnt = 0;    //타이머/카운터0 오버플로우 횟수 리셋
    mot_pos = 0;     //모터 위치 = 0도
    change = 0;      //각도 변화 주기 리셋
    
    TIMSK = 0x01;    //TOIE0 = 1;
    TCCR0 = 0x02;    //일반모드, 프리스케일 = CK/8
    TCNT0 = 238;     //타이머/카운터0 레지스터 초기값
    SREG = 0x80;     //전역 인터럽트 인에이블 비트 셋
    
    tim0_cnt = 0;
    PORTC = 0xFF; //모터 HIGH 출력
    
    while(1)
    {
        if(tim0_cnt >= 2000)
        {
            tim0_cnt = 0;
            PORTC = 0xFF; //모터 HIGH 출력
            change++;
            
            if(change == 100)
            {
                mot_pos = (mot_pos + 1) % 3;
                change =0;
            }
        }
        if(tim0_cnt >= rc_time[mot_pos]) PORTC = 0x0; // 모터 LOW 출력
    }  
}

interrupt [TIM0_OVF] void timer_int0(void)
{
    tim0_cnt++;
    TCNT0 = 238;
}

출처: 알기쉽게 배우는 AVR Atmega 128


Me

github를 이용해 만들어본 블로그입니다.