//--------------------------------------------------------
// CVAVR
//--------------------------------------------------------
#include <mega2560.h>
#include <delay.h>
//
#define U_C unsigned char
//
U_C PWM[11][241]={0,}; //11*241=2651byte
U_C g_cnt=0,count=0;
//
interrupt [TIM0_COMPA] void timer0_compa_isr(void){ //10usec 주기
if(count<=240){ count++;
switch(g_cnt){
case 0: PORTA=PWM[ 0][count]; PORTB=PWM[ 1][count]; break;
case 1: PORTC=PWM[ 2][count]; PORTD=PWM[ 3][count]; break;
case 2: PORTE=PWM[ 4][count]; PORTF=PWM[ 5][count]; break;
case 3: PORTG=PWM[ 6][count]; break;
case 4: PORTH=PWM[ 7][count]; break;
case 5: PORTJ=PWM[ 8][count]; break;
case 6: PORTK=PWM[ 9][count]; break;
case 7: PORTL=PWM[10][count]; break;
}
}
else if(count<250){
switch(g_cnt){
case 0: PORTA=0; PORTB=0; break;
case 1: PORTC=0; PORTD=0; break;
case 2: PORTE=0; PORTF=0; break;
case 3: PORTG=0; break;
case 4: PORTH=0; break;
case 5: PORTJ=0; break;
case 6: PORTK=0; break;
case 7: PORTL=0; break;
}
if(++count>=250){ count=0; if(++g_cnt>7)g_cnt=0; }
}
}
//
void servo(U_C no,U_C angle){ // no:0~87 // angle: 0~180
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;
index=no/8; m=no%8;
for(i=0;i< 60;i++)PWM[index][i ]|=pos[m]; // 0 ~ 600us : high
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
}
//
void main(void){
U_C i, no;
DDRA=0xFF; DDRB=0xFF; DDRC=0xFF; DDRD=0xFF; DDRE=0xFF; DDRF=0xFF; DDRG=0xFF; DDRH=0xFF; DDRJ=0xFF; DDRK=0xFF; DDRL=0xFF;
TCCR0A=2; TCCR0B=2; OCR0A=19; TIMSK0=2; // 16000000/8/(1+19),10us
SREG=0x80;
while(1){
for(i=0;i<180;i++){ // 600usec~2400usec까지 1도 단위로 증가
for(no=0;no<88;no++)servo(no,i); delay_ms(10); // 88개 PWM값 설정
}
for(i=180;i>0;i--){ // 600usec~2400usec까지 1도 단위로 증가
for(no=0;no<88;no++)servo(no,i); delay_ms(10); // 88개 PWM값 설정
}
}
}