제어할 모터 스팩






RA-20GM 03TYPE (12V) with 2channel Encoder

● 감속비 : 1/10 ~1/866 (감속비율 총 20종)
● 정격 토크 : 160gf-cm ~ 1800gf-cm
● 정격회전수 : 670 rpm ~ 8.5 rpm
● 장착된모터 : DC 12V / 8,000 rpm / 1.5 W Motor
● 엔코더사양 : 6P/R 






 (출처 : http://www.dnj.co.kr/2013_html/spur_ra20gm_03_en.html)



(회로도는 나중에에 올림)


ATmega128 로 DC motor 제어


 DC motor 를 제어하기 위해서는 pwm 신호로 적당한 고주파를 만들어 주어야 한다. pwm 신호를 만드는 방법은 타이머 인터럽트에 여러가지 모드가 있는데 그중에 normal mode를 사용하겠다. 


  타이머 인터럽트 normal mode 라 하면 다른 기능은 아무것도 쓰지 않고 내가 정해준 타이밍이 되면 알아서 인터럽트가 발생하기만 하는 것이다. 참고로 인터럽트 처리과정은 다음과 같다.



(출처 : http://cafe.naver.com/openrt)


 위 과정 중 인터럽트 처리에서 하나의 변수를 만들어놓고 그 변수를 카운트를 한다. 변수의 값이 일정 수준으로 되면 모터 신호를 ON. 그리고 변수가 다시 어느정도 되면 모터 신호를 OFF. 하고 이과정을 같은 주기로 반복 시키면 이것이 바로 pwm 신호이다.


 먼저 타이머 인터럽트를 설정할 것이다. 설정하기에 앞서 모터 고주파는 10 kHz 로 할 것이다. 10 kHz 의 역수는 100 us. 타이머 인터럽트 발생 주기를 10us 로 하고 인터럽트가 10번 발생할 때 pwm 신호를 조작하면 되겠다.


#include <mega128.h>


// *****************비트제어***************


#define sbi(PORTX, BitX) PORTX |= (1 << BitX)

#define cbi(PORTX, BitX) PORTX &= ~(1 << BitX)


// ************전체 인트럽트 설정*************


#define DISABLE_ISR cbi(SREG, 7)

#define ENABLE_ISR sbi(SREG, 7)



static unsigned int cnt;


void interupt_init()

{

  DISABLE_ISR;


  TIMSK = 0x01; // TImer0 overflow interrupt 활성화 

  TCCR0 = 0x02; // 8분주 

  TCNT0 = 236;   // TCNT0 시작

               

  ENABLE_ISR;

}


  /* (1/16)us * (8분주비) * (256 - 236) = 10 us */


 다음은 인터럽트 루틴 소스이다.


interrupt [TIM0_OVF] void timer_int0(void)

{

  TCNT0 = 236;


  cnt++;

  if(cnt == 6) PORTC &= ~0x30;  // PORTC.4 와 PORTC.5 모터 인에이블 핀

  

  else if(cnt == 9){

    PORTC |= 0x30;

    cnt = 0;

  }

}


 코드를 설명하면, 인터럽트가 발생하면 TCNT0 의 값이 0 으로 초기화 된다. 그런데 우리는 계속해서 10us 를 얻어야 하므로 TCNT0 = 236; 으로 다시 설정 함으로써 앞으로도 계속 인터럽트 발생 주기는 10 us 가 된다. cnt 라는 변수는 전역변수로 선언 되었고 카운트를 하기 위한 변수이다. TCNT0 값이 계속 상승하다가 TOP 값을 만나서 overflow 가 되면서 인터럽트가 발생한다. 그러면 위 인터럽트 루틴을 실행하게 되는데 cnt 변수를 증가 시킨다. 미리 PORTC.4 번과 PORTC.5 번을 ON 시켜 놓았다가 cnt 가 6 이 되면 다른 핀을 제외하고 PORTC.4 번과 PORTC.5 번을 OFF 시킨다. 그리고 계속 카운트. cnt 가 9 가 되는 순간 다른 핀을 제외하고 PORTC.4 번과 PORTC.5 번을 ON 시킨다.  여기서 다른핀을 제외하고 원하는 핀만 ON 시키고 OFF 시키는 방법을 익혀두길 바란다( &= ~, |= )


문제점


 여기까지 하는 과정 중에는 큰 문제가 발생하지 않았다. 하지만 다음에 사용할 UART 수신 완료 인터럽트를 사용하는 과정에서 문제가 생겼었다. 그 문제는 UART 수신완료 인터럽트가 아무리 잘 설정해도 실행이 되질 않았었는데 그 이유는 타이머 인터럽트가 너무 빠른 시간에 많이 발생하였기 때문이다.

 

 처음에 타이머 인터럽트 발생 주기를 2 us 로 했었다. 참고로 인터럽트에도 우선순위가 있다. ATmega128 에는 35 개의 인터럽트가 있는데 이러한 인터럽트들이 동시에 발생했을 때 누가 먼저 실행할 것인가를 미리 정해 둔 것이다. 아무튼 이러한 우선순위 때문에 UART 수신완료 인터럽트와 타이머 인터럽트가 동시에 발생하면 타이머 인터럽트를 먼저 실행하게 된다. (근데 타이머 인터럽트를 먼저 실행하면 그다음 UART 수신 완료 인터럽트를 실행하면 되는것 아닌가..? .. 아예 인터럽트가 씹혀버렸었는데 왜 그런지는 모르겠다.) 그렇다 보니 타이머 인터럽트 주기를 너무 빠르게 하면 안된다!

'project > 스마트폰으로 avr 제어' 카테고리의 다른 글

step3. UART 통신 (비동기 통신)  (0) 2013.11.19
step2-1. DC Motor pwm control  (2) 2013.11.19
step1. 모터드라이브 L298N 제어  (0) 2013.11.19
step0. project 목차  (0) 2013.11.19
RF 용어 설명  (0) 2013.11.16
Posted by 나무길 :