회원가입 ID/PW 찾기
AA

제가 프로그램 소스를 구했는데 중간 중간에 주석이 있지만 잘  이해가 안되서요~
atmega8을 사용해 짠 4족로봇 소스인데 이 소스를 atmega128로 바꿀려구요
계속해봐도 잘 모르겠어요..
도와주세요~

// 천천히 전진, 좌,우 회전.
// 좌우 회전 방법 개선

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

#define U08 unsigned char
#define U16 unsigned int
#define S16 signed int
#define OFF 0
#define ON 1

#define LEG_FORWARD      (3000)        //한쪽 두개의 다리를 넓게 벌릴때 사용되는 각도
#define LEG_BACKWARD     (7500)        //  "    "       "   좁게 만들때
#define LEG_UP          (2500)
#define LEG_DOWN          (-0)

#define    ROBOT_SPEED        (U08)(3)        //robot 패턴 변화시간 *100ms  : 작을수록 빠름.
#define SERVO_DIFF        (S16)(ROBOT_SPEED * 100 / 20)  //각 패턴당 움직이는 시간(ms) / 서보 한 펄스 시간(ms)


#define ROBOT_FW     1
#define ROBOT_BW     2
#define ROBOT_LE     3
#define ROBOT_RI     4
#define ROBOT_DIR_LAST     5
#define ROBOT_STOP     0


void SERVO_ONOFF(num, onoff);
void LED_ONOFF(num, onoff);
void RobotPatternChange(void);

U08 gu08DelayTime = 0;

U08    gu08RobotDirec = 0;
U08    gu08RobotSpeed = 5;


U16 u16_ServoTargetAngle[8] = {0,};            //서보 목표 각도
U16 u16_ServoPresentAngle[8] = {0,};        //서보 현재 각도
U16 gu16ServoActualAngle[8] = {0,};            //실제 서보 각도

S16 gs16ServoAngleDiff[8];                //서보각도  변화량

                        //                1        2            3                4        //회전 관절
const U16ServoCenterValue[8] = { 0x5dc0 - 900,    0x5dc0 - 700 ,    0x5dc0 - 300 ,    0x5dc0 + 200, 
                        //                5        6            7        8                //상하 관절 
                                0x5dc0 - 500,    0x5dc0 + 300,    0x5dc0 -200,    0x5dc0 + 800  };       

const S16_MovingAngleData[][8] = {
//        1                2            3                4                5            6            7            8
///////    전진 
    {LEG_FORWARD,     -LEG_FORWARD,     LEG_BACKWARD,     -LEG_BACKWARD,     0,             0,             0,             0},    //정지1: 1,2번 쪽 넓게
    {LEG_FORWARD,     -LEG_FORWARD,     LEG_BACKWARD,     -LEG_BACKWARD,     -LEG_DOWN,     LEG_UP,     -LEG_DOWN,    LEG_UP},     //다리 들고
    {LEG_BACKWARD,     -LEG_BACKWARD,     LEG_FORWARD,     -LEG_FORWARD,     -LEG_DOWN,     LEG_UP,     -LEG_DOWN,    LEG_UP},    //다리 돌리고

    {LEG_BACKWARD,     -LEG_BACKWARD,     LEG_FORWARD,     -LEG_FORWARD,     0,            0,            0,            0},            //3,4번 다리로 넓게 내리고
    {LEG_BACKWARD,     -LEG_BACKWARD,     LEG_FORWARD,     -LEG_FORWARD,     -LEG_UP,     LEG_DOWN,     -LEG_UP,     LEG_DOWN},
    {LEG_FORWARD,     -LEG_FORWARD,     LEG_BACKWARD,     -LEG_BACKWARD,     -LEG_UP,     LEG_DOWN,     -LEG_UP,     LEG_DOWN},

/////// 회전(좌 ?)
    {LEG_FORWARD,     -LEG_FORWARD,     LEG_FORWARD,     -LEG_FORWARD,     0,             0,             0,             0},            //정지1: 4발 넓게
    {LEG_FORWARD,     -LEG_FORWARD,     LEG_FORWARD,     -LEG_FORWARD,     -LEG_UP,     0,             -LEG_UP,    0},    //다리 들고
    {-LEG_FORWARD,     -LEG_FORWARD,     -LEG_FORWARD,     -LEG_FORWARD,     -LEG_UP,     0,             -LEG_UP,    0},    //

    {-LEG_FORWARD,     -LEG_FORWARD,     -LEG_FORWARD,     -LEG_FORWARD,     0,            0,            0,            0},            //3,4번 다리로 넓게 내리고
    {-LEG_FORWARD,     -LEG_FORWARD,     -LEG_FORWARD,     -LEG_FORWARD,     0,             LEG_UP,     0,             LEG_UP},
    {LEG_FORWARD,     -LEG_FORWARD,     LEG_FORWARD,     -LEG_FORWARD,     0,             LEG_UP,     0,             LEG_UP},

//////// 회전 (우 ?)
    {LEG_FORWARD,     -LEG_FORWARD,     LEG_FORWARD,     -LEG_FORWARD,     0,             0,             0,             0},            //정지1: 4발 넓게
    {LEG_FORWARD,     -LEG_FORWARD,     LEG_FORWARD,     -LEG_FORWARD,     0,             LEG_UP,     0,            LEG_UP},    //다리 들고
    {LEG_FORWARD,     LEG_FORWARD,     LEG_FORWARD,     LEG_FORWARD,     0,             LEG_UP,     0,            LEG_UP},    //

    {LEG_FORWARD,     LEG_FORWARD,     LEG_FORWARD,     LEG_FORWARD,     0,            0,            0,            0},            //3,4번 다리로 넓게 내리고
    {LEG_FORWARD,     LEG_FORWARD,     LEG_FORWARD,     LEG_FORWARD,     -LEG_UP,     0,             -LEG_UP,    0},
    {LEG_FORWARD,     -LEG_FORWARD,     LEG_FORWARD,     -LEG_FORWARD,     -LEG_UP,     0,             -LEG_UP,    0},


    {3840, -3840, 4800, -4800, 0, 0, 0, 0},
    {3840, -3840, 4800, -4800, 0, 0, 0, 0},
//    {5760, 5760, 3840, -3840, 0, 0, 0, 0},
//    {5760, 5760, 3840, -3840, 0, 0, 0, 0},
//    {5760, 5760, 3840, -3840, 0, 0, 0, 0}
};

U08 u08_WalkingPattern = 0;


U08    u08_ServoIndex = 0;

 

U08 u08_1msCnt = 0;
U08 u08_100msCnt = 0;
U08 u08_1secCnt  = 0;
U08 num=0;

 


void t1msTask()
{
    if (gu08DelayTime > 0)
    {
        gu08DelayTime--;
    }
};
void t2msTask(){};
void t10msTask(){};
void t100msTask()
{
    gu08RobotSpeed--;
    if (0 == gu08RobotSpeed)
    {
        RobotPatternChange();
        gu08RobotSpeed = ROBOT_SPEED;
    }
};
void t1secTask(){};

void RobotPatternChange(void)
{
    U08 i, temp;
    u08_1secCnt ++;
    U16 su16TempPresentAngle;
    U16 su16TempTargetAngle;   

    LED_ONOFF(u08_1secCnt%8,OFF);
    if(u08_1secCnt%8>=1) LED_ONOFF(u08_1secCnt%8-1,ON);
   
    if(ROBOT_FW == gu08RobotDirec)
    {
        for (i=0; i<8; i++)
        {
            u16_ServoPresentAngle[i]     = u16_ServoTargetAngle[i]; //기존 목표값을 현재값으로
            u16_ServoTargetAngle[i]     = U16ServoCenterValue[i] + S16_MovingAngleData[u08_WalkingPattern][i];       
                                                                //다음 다리 각도값 : 서보모터 중앙값 + 다리이동 변화량.
            gs16ServoAngleDiff[i]         = ((S16)u16_ServoTargetAngle[i] - (S16)u16_ServoPresentAngle[i]) / SERVO_DIFF;        //서보모터 변화량 계산
            gu16ServoActualAngle[i]     = u16_ServoPresentAngle[i];    //서보 실제값을 현재 시작 서보 각도값으로.    
        }
    }
    else if(ROBOT_BW == gu08RobotDirec)
    {
        for (i=0; i<8; i++)
        {
            u16_ServoPresentAngle[i]     = u16_ServoTargetAngle[i]; //기존 목표값을 현재값으로
            u16_ServoTargetAngle[i]     = U16ServoCenterValue[i] + S16_MovingAngleData[5-u08_WalkingPattern][i];       
                                                                //다음 다리 각도값 : 서보모터 중앙값 + 다리이동 변화량.
            gs16ServoAngleDiff[i]         = ((S16)u16_ServoTargetAngle[i] - (S16)u16_ServoPresentAngle[i]) / SERVO_DIFF;        //서보모터 변화량 계산
            gu16ServoActualAngle[i]     = u16_ServoPresentAngle[i];    //서보 실제값을 현재 시작 서보 각도값으로.    
        }
    }
    else if(ROBOT_LE == gu08RobotDirec)
    {
        temp = u08_WalkingPattern + 6;
        for (i=0; i<8; i++)
        {
            u16_ServoPresentAngle[i]     = u16_ServoTargetAngle[i]; //기존 목표값을 현재값으로
            u16_ServoTargetAngle[i]     = U16ServoCenterValue[i] + S16_MovingAngleData[temp][i];       
                                                                //다음 다리 각도값 : 서보모터 중앙값 + 다리이동 변화량.
            gs16ServoAngleDiff[i]         = ((S16)u16_ServoTargetAngle[i] - (S16)u16_ServoPresentAngle[i]) / SERVO_DIFF;        //서보모터 변화량 계산
            gu16ServoActualAngle[i]     = u16_ServoPresentAngle[i];    //서보 실제값을 현재 시작 서보 각도값으로.    
        }
    }

    else if(ROBOT_RI == gu08RobotDirec)
    {
        temp = u08_WalkingPattern + 12;
        for (i=0; i<8; i++)
        {
            u16_ServoPresentAngle[i]     = u16_ServoTargetAngle[i]; //기존 목표값을 현재값으로
            u16_ServoTargetAngle[i]     = U16ServoCenterValue[i] + S16_MovingAngleData[temp][i];       
                                                                //다음 다리 각도값 : 서보모터 중앙값 + 다리이동 변화량.
            gs16ServoAngleDiff[i]         = ((S16)u16_ServoTargetAngle[i] - (S16)u16_ServoPresentAngle[i]) / SERVO_DIFF;        //서보모터 변화량 계산
            gu16ServoActualAngle[i]     = u16_ServoPresentAngle[i];    //서보 실제값을 현재 시작 서보 각도값으로.    
        }
    }
    else    //보행 패턴이 없는 경우  : 변화량을 0 으로
    {
        for (i=0; i<8; i++)
        { 
            gs16ServoAngleDiff[i] = 0;
        }
    }

    if ( ROBOT_STOP != gu08RobotDirec)
    {
   
        u08_WalkingPattern++;
        if(u08_WalkingPattern >= 6) u08_WalkingPattern = 0;
    }

};

 


int main(void)
{
    unsigned int i,j,k,l;

    u08_1secCnt = 0;  //for test

    TIMSK = 0x11;            //Timer 0 overflow int enable | Timer1 Output compare

    TCCR0 = 0x03;    //64 prescaler
    TCNT0 = 0x06;            //for 1ms

    TCCR1A = 0x00;     // Normal mode
    TCCR1B = 0x01;     // None prescaler

    GICR = 0x40;        // INT 0 enable
    MCUCR = 0x02;        // INT 0 Falling edge Ext int

    DDRA = 0xf0;        //PA4-7     : LED
    DDRC = 0xc3;        //PC0,1,6,7 : LED

    PORTA = 0xf0;        //LED all off
    PORTC = 0xc3;        //LED all off

    DDRD = 0xf0;        //Servo
    DDRB = 0xf0;
    PORTD = 0x00;
    PORTB = 0x00;

   
   
   

//    OCR1A = 0x5dc0    //test 1.5ms
// 1.5ms : 0x5dc0   0.9ms : 0x3840   2.1ms : 0x8340 
    for (i=0; i<8; i++)
    { 
        u16_ServoPresentAngle[i] = U16ServoCenterValue[i];
        u16_ServoTargetAngle[i] = U16ServoCenterValue[i];
        gu16ServoActualAngle[i] = U16ServoCenterValue[i];
    }

    u08_ServoIndex = 0;
   
    TCNT1 = 0;

//    TCCR1B = 0x04;    // 256 prescaler
//    TCNT1 = 0x0bdc;    //  1sec for test.       

    sei();

    while(1)
    {
        num++;
    }

    return 0;
}


void SERVO_ONOFF(num, onoff)       
{                                       
    if(onoff == OFF)                       
    {                                   
        if(num==0) PORTB &= ~_BV(4);   
        else if(num==1) PORTB &= ~_BV(5);
        else if(num==2) PORTB &= ~_BV(6);
        else if(num==3) PORTB &= ~_BV(7);   
        else if(num==4) PORTD &= ~_BV(4);
        else if(num==5) PORTD &= ~_BV(5);
        else if(num==6) PORTD &= ~_BV(6);
        else if(num==7) PORTD &= ~_BV(7);
    }                                           
    else if(onoff == ON)                           
    {                                           
        if(num==0) PORTB |= _BV(4);   
        else if(num==1) PORTB |= _BV(5);
        else if(num==2) PORTB |= _BV(6);
        else if(num==3) PORTB |= _BV(7);   
        else if(num==4) PORTD |= _BV(4);
        else if(num==5) PORTD |= _BV(5);
        else if(num==6) PORTD |= _BV(6);
        else if(num==7) PORTD |= _BV(7);   
    }
}

void LED_ONOFF(num,onoff)
{                                       
    if(onoff == OFF)                       
    {                                   
        if(num==0) PORTC &= ~_BV(0);   
        else if(num==1) PORTC &= ~_BV(1);
        else if(num==2) PORTC &= ~_BV(6);
        else if(num==3) PORTC &= ~_BV(7);   
        else if(num==4) PORTA &= ~_BV(4);
        else if(num==5) PORTA &= ~_BV(5);
        else if(num==6) PORTA &= ~_BV(6);
        else if(num==7) PORTA &= ~_BV(7);
    }                                           
    else if(onoff == ON)                           
    {                                           
        if(num==0) PORTC |= _BV(0);   
        else if(num==1) PORTC |= _BV(1);
        else if(num==2) PORTC |= _BV(6);
        else if(num==3) PORTC |= _BV(7);   
        else if(num==4) PORTA |= _BV(4);
        else if(num==5) PORTA |= _BV(5);
        else if(num==6) PORTA |= _BV(6);
        else if(num==7) PORTA |= _BV(7);   
    }                                       
}

ISR (TIMER1_COMPA_vect)        //서보 모터 제어용
{

    TCNT1 = 0;
    U08 temp;

    u08_ServoIndex ++;

    if(u08_ServoIndex == 16 )         //서보 인덱스 계산 8개의 서보가 각각 ON/OFF되므로 16
    {   
        u08_ServoIndex = 0;
    }

    temp = u08_ServoIndex/2;

    if(u08_ServoIndex % 2 == 0)            //짝수이면 펄스 ON
    {
        SERVO_ONOFF(temp, ON);
        OCR1A = gu16ServoActualAngle[temp];
    }
    else                                //홀수 일때는 펄스의 한 주기 길이가 2.5ms가 되도록 OFF 출력 
    {   
        SERVO_ONOFF(temp, OFF);           
        OCR1A = 0x9c40 - gu16ServoActualAngle[temp];
        gu16ServoActualAngle[temp] += gs16ServoAngleDiff[temp];                                                                                                   //0x9c40이 2.5ms 시간임.
    }
}


ISR (INT0_vect)
{
    if ( 0 != gu08DelayTime) return; 
    gu08RobotDirec++;
    gu08DelayTime = 200;
    if (gu08RobotDirec >= ROBOT_DIR_LAST)
    {   
        gu08RobotDirec = ROBOT_STOP;
    }
}

 

ISR (TIMER0_OVF_vect)        //Tick Timer??
{

    TCNT0 = 0x06;
    u08_1msCnt++;

    t1msTask();
    if(u08_1msCnt % 2 == 0)    t2msTask();
    if(u08_1msCnt % 10 == 0) t10msTask();
    if(u08_1msCnt % 100 == 0)
    {
        t100msTask();
        u08_100msCnt++;
        u08_1msCnt = 0;
    }
   
    if(u08_100msCnt % 5 == 0)
    {
     //    t500msTask();
    }

    if(u08_100msCnt == 10)
    {   
        t1secTask();
        u08_100msCnt =0;

    }
    if(u08_100msCnt % 100 == 0)
    {
        //t10secTask();
        u08_100msCnt = 0;
    }

    return 0;
}

댓글 1

하드웨어 설계 및 개발에 대하여 개발자들이 자유롭게 토론하는 공간입니다.
- Q&A, 자유주재 토론, 관련 정보 공유
- 분야 : 마이크로프로세서 응용, 전기/전자(아날로그/디지털) 회로 설계, C/C++ 프로그래밍, 펌웨어,
         PCB Artwork, 트러블슈팅 등 하드웨어 설계에 관한 전반인 내용
※ 게시글에 맞는 분류를 선택하여 글을 작성해 주시면 쾌적한 사이트 운영에 많은 도움이 됩니다.
※ 하드웨어 인사이트는 회원들간의 거래정보를 게재할 뿐이지, 그 어떤 책임과 의무도 가지지 않습니다.

search
번호 분류 제목 글쓴이 조회 수 날짜
75 중고장터 HOTAVR JTAGICE MK2 에뮬레이터 팝니다. bluewing 5041 2010.10.06
74 중고장터 HOTARM 개발보드 마이크로비젼 MV2440-LCD 팝니다. bluewing 4211 2010.10.06
73 중고장터 HOT뉴코란도 구합니다.11 설록맨 3174 2010.10.05
72 중고장터 HOTUSB HUB IC판매 Newface 3478 2010.09.24
71 중고장터 HOT삼성 3.5인치 TFT-LCD (Touch 포함) 싸게 드려요. 삼성 3.5인치 TFT-LCD (Touch 포함) 싸게 드려요. 삼성 3.5인치 TFT-LCD (Touch 포함) 싸게 드려요.1 띵요루슛 4338 2010.09.17
70 중고장터 HOT오실로스코프 싸게 사고 싶어요~7 야웅이 3255 2010.09.13
69 중고장터 HOTSTR-6253 판매합니다.2 행국강기 3914 2010.09.07
68 중고장터 HOTnewtc꺼 AVR MEGA 128pro 개발키트(풀셋) 구합니다. 어쩌다 3226 2010.08.21
67 중고장터 HOTD&J DC모터 3개 판매 로봇용적합 IGM30 12V 엔코더 타입1 아크마 6575 2009.01.11
66 중고장터 HOTCMOS 카메라 OV9650 판매1 아크마 3756 2010.07.28
65 중고장터 HOT삼성 3.5인치 TFT-LCD (Touch 포함) 싸게 드려요.2 용가리3 3280 2010.07.17
64 중고장터 HOTmicrochip 사 ac motror controller demo board 이단장 3377 2010.06.17
63 중고장터 HOT각종 부품 팝니다. 캐리안 3648 2010.06.10
62 중고장터 HOT기울기센서 (TILT SA1) 팝니다 폴라리스 4193 2010.06.05
61 중고장터 HOT중고 서적구해요..^^13 로이lee 4164 2010.05.26
60 중고장터 HOT컴퓨터 사요2 제갈공ㅇㅇ 3859 2010.05.24
59 중고장터 HOT소리인식센서 구합니다!1 재럴 3661 2010.05.22
58 중고장터 HOTHELICOMM 사의 IP-LINK 2134- 2264 모듈 구매합니다. 아크마 4117 2010.05.20
57 중고장터 HOT터치 lcd안쓰시는거 구입합니다1 duziny 3881 2010.05.13
56 중고장터 HOT어셈블리어 교재 구합니다~1 배개 3706 2010.04.28
  • 태만이란 약한 마음을 가진 사람의 유일한 피난처이다.
    - 체스터필드
  • * 납포인트 정보 *
  • 글 작성 : 3
  • 댓글 작성 : 1
  • 내 글이 추천받음 : 1
저작권법에 위배되는 콘텐츠는 등록 불가하며, 저작물에 대한 권리는 저작자에게 있습니다.
Copyright 2006-2021 © hardwareis.com, All rights reserved.