서보모터 | 두개의 타이머 인터럽트를 사용한 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=0x02; TCCR1B=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 ); // 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 ); // 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
등록된 댓글이 없습니다.