본문 바로가기

AVR/AVR 연습, Tutorial

AVR과 BA6208 모터드라이버로 DC모터 정회전, 역회전 제어하기 - AVR 연습


드디어 LED에서 벗어나서 새로운 DC모터를 제어해 봅니다. ㅎ

역시 제가 만든 Attiny2313 모듈을 가지고 DC모터를 제어 해 봤습니다.

그럼 간단하게 DC모터 제어의 이론 부터 살피고 직접 구동시켜보도록 하지요.^


딴길로...(?!) ㅎ DSLR이 갖고 싶다고 느낄 정도의 사진이 나와버렸습니다. 사진을 보정해서 저정도로 나왔는데 파란색이 있으니까 색농도가 너무 높아져서 백열등 켜놓은줄...


DC모터 제어의 이론


기본적으로 DC모터는 + - 만 정상적으로 연결 시켜주면 회전을 합니다.

그런데 DC모터 구동시에는 거의 200mA ~ 1A정도가 흐르기 때문에 AVR 핀출력으로 나오는 전류로만은 제어에 무리가 있는데요.

그래서 트랜지스터를 이용합니다.


한쪽 방향으로만 모터를 회전 시킬 때에는 다음처럼 손쉽게 NPN트랜지스터 활용 컬렉터 드라이브로 동작시킬수 있습니다.

그리고 D1은 모터 회전후 정지시에는 내부 코일에 의해 원래 전류 흐름의 반대 방향으로 기전력(전기생성) 이 되는데 이로 인해서 트랜지스터가 파손될수 있으므로 1000V정도 견딜수 있는 Fast Recovery Diode (고속 회복 다이오드) 를 사용하도록 합니다.








그런데 로봇같은 것을 만들 때에는 로봇이 앞으로 가기도 하고 뒤로 가기도 하고 하는데 이렇게 설계해서는 전류가 VCC에서 GND로 모터의 1번 핀에서 2번핀으로 한방향으로 밖에 전류가 흐를 수 없기 때문에 정방향/역방향 제어가 되지 않습니다.

그 때는 H 브릿지라는 회로를 이용 4개의 트랜지스터를 활용해서 정역제어를 하는데요.

기본적인 설계 구조는 아래와 같습니다.


다음 처럼 상단은 

PNP트랜지스터 2개

하단은 NPN트랜지스터 

2개로 구성하고 

역시 역방향 기전력 

차단용으로 다이오드를 

붙여줍니다.












- R1, R2, R3, R4의 저항 값은 모터의 용량에 따라 변경되어야 합니다.

상단에 PNP 트랜지스터를 이용하는 이유는 NPN 트랜지스터와 같이 컬렉터에 부하를 걸어야

트랜지스터가 포화상태가 되어서 트랜지스터에서 손실되는 전류/전력이 줄어들기 때문입니다.


동작방법은 PNP 트랜지스터는 베이스가 논리 0 이 되면 동작하므로

T1과 T4를 동작시키면 모터는 정회전을 하고, T2와 T3을 동작시키면 역회전을 하게됩니다.

이 회로를 작게 칩하나로 만들어 둔것이 BA6208 같은 모터 드라이버 IC입니다.

그럼 IC를 이용해서 실제로 구성 동작시켜보겠습니다.


DC모터 제어 연습 회로도




BA6208로 구성된 간단한 모터제어 회로입니다.

BIN과 AIN에 각각 논리 1, 논리 0을 주면 BOUT과 AOUT에 정회전 논리1, 논리 0이 출력되고

BIN과 AIN에 각각 논리 0, 논리 1을 주면 역회전 논리 0, 논리 1 로 동작시킬수 있습니다.


 DC모터는 정회전, 역회전이 정확이 정해져있지 않아서 본인 기준입니다.^

본인이 논리1, 논리0 을 보냈을때를 정회전이라고 정해두면 반대는 역회전인 것이죠.!


그리고 C3 콘덴서는 모터 초기 구동시에는 많은 전류를 끌어다 쓰기 때문에 전압 안정용으로 100uF정도 달아주거나 혹은 노이즈 제거용으로 0.1uF정도 달면 됩니다.

이외에 역기전력 차단 다이오드 트랜지스터는 모두 저 IC안에 내장되어 있습니다.

회로설명도 끝났으니 코드비전 용 소스코드 부터 살펴보면서 실제로 MCU로 제어해 보겠습니다.



CodeVisionAVR 용 소스코드


#include <tiny2313.h>    // Tiny2313 입출력 관련 헤더 파일을 포함합니다.

#include <delay.h>    // 지연함수 관련 헤더파일을 포함합니다.


void main(void)    // main함수를 호출합니다.

{


PORTB=0x00;    // 포트B의 초기상태는 모두 꺼짐 논리0 (0V)입니다.

DDRB=0xFF;    // 포트B의 8비트 전체를 출력으로 설정합니다.


while (1)    // 아래 구문을 무한반복합니다.

      {

        PORTB.0=1;    // 포트B의 0번 핀에 5V (논리1)출력

        PORTB.1=0;    // 포트B의 1번 핀에 0V (논리0)출력

        delay_ms(1000);    // 위 상태를 1초 동안 유지합니다.

        PORTB.0=0;    // 포트B의 0번 핀에 0V (논리0)출력

        PORTB.1=0;    // 포트B의 1번 핀에 0V (논리0)출력

        delay_ms(4000);    // 위 상태를 4초 동안 유지합니다.

        PORTB.0=0;    // 포트B의 0번 핀에 0V (논리0)출력

        PORTB.1=1;    // 포트B의 1번 핀에 5V (논리1)출력

        delay_ms(1000);    // 위 상태를 1초 동안 유지합니다.

        PORTB.0=0;    // 포트B의 0번 핀에 0V (논리0)출력

        PORTB.1=0;    // 포트B의 1번 핀에 5V (논리1)출력

        delay_ms(4000);    // 위 상태를 4초 동안 유지합니다.


      }

}


프로그램이 LED 비트제어 했던 것과 유사합니다. 회로가 약간 복잡해졌지만 소프트웨어는 어렵지 않지요.

프로그램을 설명하자면 1초 동안 DC모터를 정회전 후에 4초 동안 회전하지 않습니다.

그리고 1초 동안 DC모터를 역회전 후에 4초 동안 회전하지 않습니다. 이 것을 무한 반복합니다.


 실제로는 관성 때문에 조금 오래 돌아가서 4초 동안 지연시켰습니다.



AVR Studio 용 소스코드


#include <avr/io.h>    // AVR 입출력 관련 헤더파일을 포함합니다.

#define F_CPU 8000000UL    // 사용하는 크리스탈 주파수 값을 상수로 설정합니다.

#include <util/delay.h>    // 지연함수 관련 헤더파일을 포함합니다.


int main(void)    // main함수를 호출합니다.

{

PORTB=0x00;    // 포트B의 초기상태는 모두 꺼짐 논리0 (0V)입니다.

DDRB=0xFF;    // 포트B의 8비트 전체를 출력으로 설정합니다.


while (1)    // 아래 구문을 무한 반복합니다.

      {

PORTB = (1<<PB0) | (0<<PB1);    // 포트B의 0,1번 핀에 각각 5V, 0V출력

_delay_ms(1000);    // 위 상태를 1초 동안 유지합니다.

PORTB = (0<<PB0) | (0<<PB1);    // 포트B의 0,1번 핀에 각각 0V, 0V출력

_delay_ms(4000);    // 위 상태를 4초 동안 유지합니다.

PORTB = (0<<PB0) | (1<<PB1);    // 포트B의 0,1번 핀에 각각 5V, 0V출력

_delay_ms(1000);    // 위 상태를 1초 동안 유지합니다.

PORTB = (0<<PB0) | (0<<PB1);    // 포트B의 0,1번 핀에 각각 0V, 0V출력

_delay_ms(4000);    // 위 상태를 4초 동안 유지합니다.

      }


return 0;    // main함수에 0을 리턴합니다.

}


AVR Studio의 새로운 쉬운 비트제어 방법을 알았습니다.

시프트 연산자로 포트B의 5번 포트에 5V를 출력하고 싶다면 PORTB = (1<<PB5)라고

표현하면 쉽게 동작되는 것을 확인했습니다.

논리연산으로 비트 제어를 해도 되지만, 이 방법을 사용해도 됩니다.


DC 모터 동작영상


 

정역제어 끝... 다음 포스팅에서는 PWM으로 속도를 늘렸다 줄였다 해보겠습니다.

휴~~ 이번 포스팅은 조금 힘들었네요.^