모터 > ATmega128 - 53개의 서보모터 구동

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

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

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

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

BASIC4MCU > 모터

서보모터 | ATmega128 - 53개의 서보모터 구동

페이지 정보

작성자 키트 작성일17-09-05 17:16 조회2,541회 댓글0건

첨부파일

본문

// 

// pwm 배열 56(7byte*8bit)개 중에서 포트G가 5개라서 53개의 전체 포트에 PWM출력을 합니다.
// PORTA : 0~7
// PORTB : 8~15
// PORTC : 16~23
// PORTD : 24~31
// PORTE : 32~39
// PORTF : 40~47
// PORTG : 48~52


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
43
44
45
46
47
48
49
50
51
52
53
54
//--------------------------------------------------------
// CVAVR
//--------------------------------------------------------
#include <mega128.h>
#include <delay.h>
//
#define U_C unsigned char
// 
U_C PWM[7][241]={0,}; //7*241=1687byte
int count=0;
// 
interrupt [TIM0_COMP] void timer0_comp_isr(void){ //10usec 주기
    if(count==0){
        PORTA=0xFF; PORTB=0xFF; PORTC=0xFF; PORTD=0xFF; PORTE=0xFF; PORTF=0xFF; PORTG=0xFF;
    }
    else if(count<60){
    }
    else if(count<240){
        PORTA=PWM[0][count]; PORTB=PWM[1][count]; 
        PORTC=PWM[2][count]; PORTD=PWM[3][count]; 
        PORTE=PWM[4][count]; PORTF=PWM[5][count]; 
        PORTG=PWM[6][count]; 
    }
    else if(count==240){
        PORTA=0; PORTB=0; PORTC=0; PORTD=0; PORTE=0; PORTF=0; PORTG=0;
    }
    if(++count>1999)count=0;
}
//
void servo(U_C no,U_C angle){ // no:0~52 // angle: 0~180 //28ms
    char pos[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
    char neg[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
    U_C i,index,m;
    SREG&=~0x80;
    index=no/8; m=no%8;
    for(i=0;i<angle;i++)PWM[index][i+60]|=pos[m]; // 0    ~ angle : high
    for(   ;i<= 180;i++)PWM[index][i+60]&=neg[m]; // angle~180(2400us) : low
    SREG|=0x80;
}
//
void main(void){
  U_C i,no;
  DDRA=0xFF; DDRB=0xFF; DDRC=0xFF; DDRD=0xFF; DDRE=0xFF; DDRF=0xFF; DDRG=0x1F;
  TCCR0=0x0A; OCR0=19; TIMSK=2// 16000000/8/(1+19),10us
  SREG=0x80;
  while(1){
      for(i=0;i<180;i++){ // 600usec~2400usec까지 1도 단위로 증가
          for(no=0;no<53;no++)servo(no,i); delay_ms(20); // 53개 PWM값 설정
      }
      for(i=180;i>0;i--){ // 600usec~2400usec까지 1도 단위로 증가
          for(no=0;no<53;no++)servo(no,i); delay_ms(20); // 53개 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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
//--------------------------------------------------------
// AVRStudio
//--------------------------------------------------------
#define F_CPU 16000000UL // 16 MHz
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
//
#define U_C unsigned char
// 
volatile U_C PWM[7][241]; //7*241=1687byte
volatile int count=0;
// 
ISR(TIMER0_COMP_vect){ //10usec 주기
    if(count==0){
        PORTA=0xFF; PORTB=0xFF; PORTC=0xFF; PORTD=0xFF; PORTE=0xFF; PORTF=0xFF; PORTG=0xFF;
    }
    else if(count<60){
    }
    else if(count<240){
        PORTA=PWM[0][count]; PORTB=PWM[1][count]; 
        PORTC=PWM[2][count]; PORTD=PWM[3][count]; 
        PORTE=PWM[4][count]; PORTF=PWM[5][count]; 
        PORTG=PWM[6][count]; 
    }
    else if(count==240){
        PORTA=0; PORTB=0; PORTC=0; PORTD=0; PORTE=0; PORTF=0; PORTG=0;
    }
    if(++count>1999)count=0;
}
//
void servo(U_C no,U_C angle){ // no:0~52 // angle: 0~180 //28ms
    char pos[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
    char neg[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
    U_C i,index,m;
    SREG&=~0x80;
    index=no/8; m=no%8;
    for(i=0;i<angle;i++)PWM[index][i+60]|=pos[m]; // 0    ~ angle : high
    for(   ;i<= 180;i++)PWM[index][i+60]&=neg[m]; // angle~180(2400us) : low
    SREG|=0x80;
}
//
int main(void){
  U_C i, no; int k;
  DDRA=0xFF; DDRB=0xFF; DDRC=0xFF; DDRD=0xFF; DDRE=0xFF; DDRF=0xFF; DDRG=0x1F;
  TCCR0=0x0A; OCR0=19; TIMSK=2// 16000000/8/(1+19),10us
  for(k=0;k<1687;k++)PWM[0][k]=0//7*241=1687byte
  SREG=0x80;
  while(1){
      for(i=0;i<180;i++){ // 600usec~2400usec까지 1도 단위로 증가
          for(no=0;no<53;no++)servo(no,i); _delay_ms(20); // 53개 PWM값 설정
      }
      for(i=180;i>0;i--){ // 600usec~2400usec까지 1도 단위로 증가
          for(no=0;no<53;no++)servo(no,i); _delay_ms(20); // 53개 PWM값 설정 
      }
  }
}
cs


10us 주기의 타이머가 
250 count 루프를 돌면 
10us*250= 2500us

2500us 주기로 g_cnt가 0~7까지 증가하고
스위치 문에서 g_cnt에 해당하는 포트를 출력합니다.
2500us * 8 = 20ms

2500us --- 2500us --- 2500us --- 2500us --- 2500us --- 2500us --- 2500us --- 2500us
PA출력 --- PB출력 --- PC출력 --- PD출력 --- PE출력 --- PF출력 --- PG출력 --- 아무것도 안함

//

돌려보지 않은 예제니 문제가 있으면 덧글로 적어주세요^^

3660040649_3k5AMZHX_25C125A625B825F1_25BE25F825C025BD.PNG3Ftype3Dw740

댓글 : 0

조회수 : 2,541

등록된 댓글이 없습니다.

게시물 검색

모터 목록

게시물 검색


Privacy Policy
MCU BASIC ⓒ 2017
PC버전