회원가입 ID/PW 찾기
AA

변수선언(전역변수)

uint16_t x , y ;
uint16_t data [7] ; // 현재 듀비값을 저장하는 변수.

uint16_t data1[7] ; // 저장된 듀티값을 받는 변수-_-;;(말이 좀 이상하네요;;)
uint16_t  z [7] = {1500,1600,1700,1800,1900,2000,2100}; //듀티값
int b=0; //항상 0으로 초기화 되었다가, 외부인터럽트가 발생하면 1로 세트되는 변수.

 

포트초기화

DDRA=0xFF;

PORTA=0x00; //서보모터가 연결된 포트

 

DDRE=0x00;

PORTE=0x00; //외부인터럽트 INT5번포트에 스위치 연결...

 

void _External_Init(void) //외부 인터럽트 초기화함수
{
  
 EICRA=0x00; // INT3~0 Disable
 EICRB=0x03; // INT4~7 Enable interrupt ==> rising edge
 EIMSK=0x20;//  Enable INT5 interrupt
 EIFR=0x20;//     Enable flag register

 

#pragma interrupt_handler int4_isr:6 //외부인터럽트
void int4_isr(void)
{
 data1[y]=data[x]; //현재듀티값을 저장하는 변수값을 출력할 변수에 저장합니다.
  b=1;

}

void main(void)

{

   b=0;

  각 포트, 초기화함수;

  while(1){

                  if (b==0){

                                  while(1){

                                                 Servo24SetDuty1(0,7,z[0]);      // z[0]배열의 값을 가져와서 모터를 돌리고
                                                 data[x]=z[0];                                //  z[0]배열의 값을 data[x]에 저장합니다.
                                                 delay();
                                                

                                                 Servo24SetDuty1(0,7,z[1]);
                                                 data[x]=z[1];
                                                 delay(10);
                                               

                                                 Servo24SetDuty1(0,7,z[2]);
                                                 data[x]=z[2];
                                                 delay();

                                                

                                                 Servo24SetDuty1(0,7,z[3]);
                                                 data[x]=z[3];
                                                 delay();       
                                               

                                                 Servo24SetDuty1(0,7,z[4]);
                                                 data[x]=z[4];
                                                 delay();
                                                Servo24SetDuty1(0,7,z[5]);
                                                data[x]=z[5];
                                                delay();
                                                Servo24SetDuty1(0,7,z[6]);
                                                data[x]=z[6];
                                                delay();
                                                Servo24SetDuty1(0,7,z[5]);
                                                data[x]=z[5];
                                                delay();
                                                Servo24SetDuty1(0,7,z[4]);
                                                data[x]=z[4];
                                                delay();
                                                Servo24SetDuty1(0,7,z[3]);
                                                data[x]=z[3];
                                                delay();
                                                Servo24SetDuty1(0,7,z[2]);
                                                data[x]=z[2];
                                                delay();
                                                Servo24SetDuty1(0,7,z[1]);
                                                data[x]=z[1];
                                                delay();
                                                Servo24SetDuty1(0,7,z[0]);
                                                data[x]=z[0];
                                                delay();
                                                } // end while

                              } // end if
       

        else if(b==1){
                                while(1){          
                                               Servo24SetDuty1(0,7,data1[y]);
                                               delay();
                                               Servo24SetDuty1(0,7,700);
                                               delay(5);
                                               Servo24SetDuty1(0,7,data1[y]);
                                              }   //end while

                              } //end else if
      
           
          }  //End while
}   // end main

 

제가 뭘 착각하고 있는걸까요 -_-?;;;

 

현재 반응은.. 일단 1500~ 2100까지는 왔다리 갔다리 합니다... 그러는 중에 스위치를 누르면, 그 순간만 멈칫하고 다시 움직입니다..

 

스위치를 계속 누르고 있으면 계속 정지해있구요..

 

 

댓글 5
  • No Profile
    채터링 때문에


    void int4_isr(void)
    {
     data1[y]=data[x]; //현재듀티값을 저장하는 변수값을 출력할 변수에 저장합니다.
      b=1;

    }

    이 함수가 몇번호출될꺼 같고요..


     delay(5); 이거는 몇s동안 딜레이 하는건가요??(다른 타이머를 쓰지 않는다면 딜레이함수가 서보가 움직일시간동안 시간을 벌어줘야 합니다.)

    그리고 delay함수 자체가 매우 중요한 역할을 할수가있습니다.

    delay함수를 nop와 같은(어셈블러로 아무런 동작도 안함)명령으로 이루어져있다면 타이머가 실시간적으로 제대로 동작할수 없겠지요..

    delay함수를 설명해주세요.


    ps, 이 소스의 목적이 안나와있어 컨셉을 잡는데 다른분들이 보기 어려워보여요...

  • No Profile
    글쓴이 챠리스만 07.10.10 18:34 댓글 좋아요 0 싫어요 0

    아크마님 답변 감사합니다 ㅋㅌ

     

    에.. 먼저 이 소스의 목적은 아래와 같습니다..

     

    가정

    서모의상태 == 서보혼에 길이가 5cm인 일자형 프레임을 장착한다.

    1.서보모터를 기동하게 되면 처음은 90도를 유지를 하게 됩니다..

    2.모드를 선택하면 90도에서 좌로 계속 움직입니다.(물체

    3. 좌로 움직이는 동안에 어떠한 물체와 접촉을 하게 되면 서보가 그 각도를 유지합니다.( 더 이상 좌로 이동이 안된다는 말입니다.)

    4. mcu는 3번의 각도값을 기억하게 됩니다.

    5. 서보모터는 3번 각도값부터 우로 회전했다가 다시 3번 각도값으로 되돌아 옵니다. 이것을 무한반복하게 됩니다.

    5번설명을 좀 더 자세히 하겠습니다..

    서보는 90도에서 좌로 계속 움직이다가 (좌값의 맥스값이 되기 전에) 물체와의 접촉으로 정지를 합니다.
    예를 들어 90도에서 좌로 30도정도 이동했다고 가정합니다.
    그리고나서 mcu가 이 값을 저장하고 다시 우로 이동을 하게 됩니다.

    이렇게 만들고 보고 싶습니다..

     

    delay()함수에 관해서는 아크마님의 의도를 바로 알아차렸습니다. 왜냐면, 코딩하면서 실제로 그런 문제들을 접했거든요..

     

    서보가 움직일 시간을 delay()함수가 제대로 벌어주지 못하면 목표각도까지 이동하지 못하기 때문입니다..

     

    그래서 위의 delay()함수는 적절하게 맞춘 딜레이입니다. (위의 delay(5)이 부분은 오타네요.. 5를 빼야합니다;;)

     

    void delay(){
    unsigned int j,i,cnt;
    for(i=1;i<2000;i++) 
       {
         for(j=1;j<2500;j++)cnt=1;
       }
    }

    딜레이함수 원형입니다..

     

    아, 그리고 코딩을 새로 해봤습니다. 작동은 되는데, 어처구니없이 됩니다 ㅋㅋㅋㅋ;;;

     

    void main(void)

    {

     생략

     while(1){

                     서보각도함수90도

                      .......

                      ...

                      서보각도함수180도

                      ......

                      ...

                     서보각도함수90도

     

    if(b==1){

                   while(1){

                                  서보각도함수(data[x]);

                                  딜레이();

                                  서보각도함수(180도);

                                  딜레이();

                                  서보각도함수(data[x]);

                                  } end while

                   } end if

    이런식으로 해놨어요....

     

    전원을 넣으면 메인의 while이 무한으로 반복입니다..( 90도->180도->90도)

    그리고 원하는 곳에서 스위치를 눌러서 외부인터럽트를 발생시킵니다..(예를 들어서 120도에서 외부인터럽트발생)

    그럼 그 순간 멈칫하다가 다시 120도->180->90도로 돌아오면 이때서야 외부인터럽트가 걸립니다...

    신기한건 여기서 if (b==1)문을 완벽하게 실행합니다 -_-;; (각도의 오차도 거의 없습니다..)

    어떻게 더 손을 봐야할지 -_ -;;

     

     

    }

      

  • No Profile
    [[code]]

    void int4_isr(void)
    {
    if(b==0)
    {
     data1[y]=data[x]; //현재듀티값을 저장하는 변수값을 출력할 변수에 저장합니다.
      b=1;

    }
    }


    if (b==0){

                                                     Servo24SetDuty1(0,7,z[0]);      // z[0]배열의 값을 가져와서 모터를 돌리고
                                                     data[x]=z[0];                                //  z[0]배열의 값을 data[x]에 저장합니다.
                                                     delay();
    .                                                

    .
    .}

    else if(b==1){
                              
                                                   Servo24SetDuty1(0,7,data1[y]);
                                                   delay();
                                                   Servo24SetDuty1(0,7,700);
                                                   delay(5);
                                                   Servo24SetDuty1(0,7,data1[y]);
                                           

    b=0
                                  } //end else if


    [[/code]]

    우선 위와같이 채터링을 좀 방지해주시고요

    가장 큰 문제점은 무한루프입니다.

    즉 while(1)이 되므로 끝나지가 않지요..ㅡㅡ; 조건이..항상 1이므로

    b값을 조사해서 1번을 실행할지 2번을 실행할지 조건으로 주게 되잖아요

    그러니까 어차피 메인 무한루프는 while(1)으로 지속되므로 내부에 있는 while(1)은 없어지거나 조건문을 달아줘야합니다.

  • No Profile
    글쓴이 챠리스만 07.10.10 19:33 댓글 좋아요 0 싫어요 0

    음... 위와 같이 코드를 수정을 해봤습니다. 확실히 스위치를 누르는 순간 외부인터럽트가 발생은 합니다. 누른 시점에 맞게 각도값이 나오기 때문입니다. 하지만, b변수에 1이 저장이 되지만 else if문으로 바로 점프하지 않고, if문을 다 처리한 후에 else if문을 처리하게 되네요 ㅠㅠ;; 곰곰히 생각해보면 저렇게 되는게 당연한거 같습니다.. 인터럽트 요청시 실행중인 루트를 멈추고-> 주소기록후-> 인터럽트루틴에 점프->루틴실행->기록한주소로 복귀->다시 실행중인 루트실행... 이렇게 되는게 맞는거 같습니다..

     

    하지만, 내가 원하는게 이게 아니자나 ㅠㅠ;;;

     

    뭔가 방법을 찾아봐야겠습니다 ^____________^;;

     

    아크마님의 조언이 많은 도움이 되었습니다. __)

     

    else if(b==1)문 안에 while문을 넣게 된 이유는 if(b==0)문이 실행되는걸 원치 않았기 때문입니다. 그래서 else if문에 들어오면 먼저 외부인터럽트를 disable걸어버리고 while문을 실행을 할려고 합니다.

  • No Profile
     else if문에 들어오면 먼저 외부인터럽트를 disable걸어버리고 while문을 실행을 할려고 합니다.

    while문 안쓰셔도 됩니다.어차피 b값을 인터럽트 체크할때 값을 보고 현재 실행중이라면 무시하는 루틴을 만들어도 되니까요

    님말씀처럼 while()을사용하시려면 break;문이나 while(조건문)형태로 하셔야될겁니다.


    b변수에 1이 저장이 되지만 else if문으로 바로 점프하지 않고, if문을 다 처리한 후에 else if문을 처리하게 되네요 

       while(1){

    if(b=1=)
    break;

    }
    이런 문장을 실행문마다 넣어주면 바로 취소하고 할수도 있겠지요.



    ps, 현재 이런 구조는 님이 원하시는 구조로 만드시기에 좀 취약한거 같습니다. 이 상태에서 맞추려 하지 마시고

    소스를 다 지우고 다시 작성하는게 좋아보입니다. 일단 이걸 하면서 개념을 잡으셨기에 아예 첨부터 작성하시면

    더욱 세련된 소스가 될것입니다.

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

search
번호 분류 제목 글쓴이 조회 수 날짜
364 자유주제 HOT반갑습니다.^^ 새로운 회원입니다.7 cyma 6692 2007.10.11
363 자유주제 HOTat90can128 질문입니다6 고문관 6668 2007.10.11
362 자유주제 HOT아 정말 이 사이트 운영자님..3 레드리네 6762 2007.10.10
361 마이크로프로세서 HOT저기 밑에 인터럽트에 관한것입니다.1 레드리네 689 2007.10.10
360 자유주제 HOT방갑습니다...^^2 야바 6475 2007.10.10
마이크로프로세서 HOT코드에 문제점이 무엇일까요?5 챠리스만 793 2007.10.10
358 마이크로프로세서 HOT이래저래 해서 물어봅니다 ㅎㅎ3 뺘쑝 795 2007.10.10
357 자유주제 HOT예전에는 내몸이 이랬는데 흑흑7 뺘쑝 1424 2007.10.10
356 자유주제 HOTrf서보제어 성공~~~기뻐해주십시오5 고문관 7556 2007.10.10
355 자유주제 HOT저.. 궁금한개 있어요..;;3 행복하면 6924 2007.10.10
354 Allegro & OrCAD HOTorcad layout에서 외곽선을 원으로 그리는 방법??3 kaizer 2065 2007.10.09
353 자유주제 HOT무서운 아크마님7 빛나는 영혼 1451 2007.10.09
352 마이크로프로세서 HOT[질문] AT89C51과 AT89S51 차이점...3 곰돌푸우 1832 2007.10.09
351 마이크로프로세서 HOT이번에 처음 접했는데요...16진수 카운트 하는 프로그램은 어떻게 짜는거에요?2 니트로마 986 2007.10.09
350 자유주제 HOT오~ 홈페이지가 점점 머찌게 변하네요.. ㅋㅋ6 행복하면 6843 2007.10.09
349 마이크로프로세서 HOTmax232cpe 콘덴서 용량 질문드립니다.2 마프맨 910 2007.10.09
348 자유주제 HOT무선 스피커 자료요청입니다...5 엘랑 6563 2007.10.09
347 자유주제 HOT음...점점 좋아지는 홈페이지 멋있습니다...4 엘랑 6954 2007.10.09
346 마이크로프로세서 HOT음..코드좀 봐주세용 -0-;;2 챠리스만 834 2007.10.09
345 자유주제 HOT안녕하세요들~2 하루 7000 2007.10.09
  • 모든 원인은 하나 이상의 결과를 낳는다.
    - 하버트 스펜서
  • * 납포인트 정보 *
  • 글 작성 : 3
  • 댓글 작성 : 1
  • 내 글이 추천받음 : 1
저작권법에 위배되는 콘텐츠는 등록 불가하며, 저작물에 대한 권리는 저작자에게 있습니다.
Copyright 2006-2021 © hardwareis.com, All rights reserved.