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

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

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


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

페이지 정보

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

등록된 댓글이 없습니다.

모터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
모바일버전으로보기