모터 > 두개의 타이머 인터럽트를 사용한 8개의 RC 서보모터 구동

인기검색어 > 아두이노 센서 ATMEGA128

최신글 질문게시판 동영상강좌 가입하기

▼ BASIC4MCU 후원업체 신제품 정보 ▼

▲ BASIC4MCU 후원업체 신제품 정보 ▲

BASIC4MCU > 모터

서보모터 | 두개의 타이머 인터럽트를 사용한 8개의 RC 서보모터 구동

페이지 정보

작성자 키트 작성일17-09-05 17:15 조회1,689회 댓글0건

본문

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//--------------------------------------------------------
// CVAVR
//--------------------------------------------------------
#include <mega128.h>
#include <delay.h>
//
unsigned char pwm[181],angle[8]={0,};
unsigned int  cnt=0;
//
interrupt [TIM1_OVF  ] void timer1_ovf_isr(void)  { PORTA=0xFF; } // 서보모터 ON
interrupt [TIM1_COMPA] void timer1_compa_isr(void){ PORTA=pwm[cnt];  TCCR0=0x0A; cnt=0// 타이머0 ON
interrupt [TIM0_COMP ] void timer0_comp_isr(void) { PORTA=pwm[cnt]; if(++cnt>180){ PORTA=0x00; TCCR0=0; } // 타이머0 OFF
//
void save_angle(char ch,char angle){
    char pos[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
    char neg[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
    unsigned char i;
    for(i=0;i<=angle;i++){ pwm[i]|=pos[ch]; } // 1을 채우고
    for(   ;i<=180  ;i++){ pwm[i]&=neg[ch]; } // 0을 채움
}
//
void main(void){
    unsigned char i;
    unsigned int  tp;
    DDRA=0xFF;   // 서보모터
    OCR0=19;     // 16000000/8/(1+ 19),10us
    TCCR1A=0x02TCCR1B=0x1A; OCR1A=1200; ICR1=39999;
    TIMSK=0x16;
    ADCSRA=0xE7;
    SREG|=0x80;
    while(1){
        for(i=0;i<8;i++){ // 8개의 가변저항을 읽어서
            ADMUX=0x40|i; delay_ms(2); tp=ADCW;
            angle[i]=(unsigned char)( (float)tp*179.0/1023.); // 0~180도로 변환
        }
        for(i=0;i<8;i++)save_angle(i,angle[i]); // pwm 변환
    }
}
cs



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//--------------------------------------------------------
// AVRStudio
//--------------------------------------------------------
#define F_CPU 16000000UL // 16 MHz
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
//
volatile unsigned char pwm[180],angle[8]={0,};
volatile unsigned int  cnt=0;
//
ISR(TIMER1_OVF_vect)  { PORTA=0xFF; } // 서보모터 ON
ISR(TIMER1_COMPA_vect){ PORTA=pwm[cnt];  TCCR0=0x0A; cnt=0// 타이머0 ON
ISR(TIMER0_COMP_vect) { PORTA=pwm[cnt]; if(++cnt>180){ PORTA=0x00; TCCR0=0; } // 타이머0 OFF
//
void save_angle(char ch,char angle){
    char pos[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
    char neg[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
    unsigned char i;
    for(i=0;i<=angle;i++){ pwm[i]|=pos[ch]; } // 1을 채우고
    for(   ;i<=180  ;i++){ pwm[i]&=neg[ch]; } // 0을 채움
}
//
int main(void){
    unsigned char i;
    unsigned int  tp;
    DDRA=0xFF;   // 서보모터
    OCR0=19;     // 16000000/8/(1+ 19),10us
    TCCR1A=0x02; TCCR1B=0x1A; OCR1A=1200; ICR1=39999// FAST PWM
    TIMSK=0x16;
    ADCSRA=0xE7;
    SREG|=0x80;
    while(1){
        for(i=0;i<8;i++){ // 8개의 가변저항을 읽어서
            ADMUX=0x40|i; _delay_ms(2); tp=ADCW;
            angle[i]=(unsigned char)( (float)tp*179.0/1023.); // 0~180도로 변환
        }
        for(i=0;i<8;i++)save_angle(i,angle[i]); // pwm 변환
    }
}
cs

포트F에 8개의 가변저항을 연결해서
포트A의 8개의 RC 서보모터를 구동하는 예제입니다.

ADC값을 읽어서 0~180도 각도로 변환한 후
비트맵으로 만들어 두었다가 타이머 인터럽트에서 포트로 출력합니다.

동작시켜보지 않았으니 문제가 있으면 아래에 덧글로 적어주세요

댓글 : 0

조회수 : 1,689

등록된 댓글이 없습니다.

게시물 검색

모터 목록

게시물 검색


Privacy Policy
MCU BASIC ⓒ 2017
PC버전