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

TODAY138 TOTAL2,227,468
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

아두이노 센서 ATMEGA128 PWM LED 초음파 AVR 블루투스 LCD UART 모터 적외선


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

페이지 정보

작성자 키트 작성일2017-09-05 17:15 조회1,642회 댓글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,642

등록된 댓글이 없습니다.

모터HOME > 모터 > 서보모터 목록

게시물 검색

2022년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2021년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2020년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2019년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2018년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
Privacy Policy
MCU BASIC ⓒ 2020
모바일버전으로보기