회원가입 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
번호 분류 제목 글쓴이 조회 수 날짜
15 중고장터 HOTATS-20.000MHz 50개 빅세일 4749 2007.10.23
14 중고장터 HOTatmega128 pcb 팝니다. 보싸먹자 7421 2007.10.23
13 중고장터 HOT사진과 같은 모양의 서보혼 구입 원합니다.4 챠리스만 5231 2007.10.18
12 중고장터 HOT[판매] RC서보모터 RC-31112 아크마 5184 2007.10.09
11 중고장터 HOT[판매] SRF 04 초음파센서3 아크마 5241 2007.10.09
10 중고장터 HOT[판매] 5V DC어댑터 아크마 5022 2007.10.08
9 중고장터 HOT[전공서적] 회로이론 ALEXANDER , SADIKU4 아크마 6374 2007.10.08
8 중고장터 HOT라인트레이서 구합니다13 곰팅이 4934 2007.10.08
7 중고장터 HOT0.68옴 저항 1W, 2W 판매2 아크마 3940 2007.10.03
6 중고장터 HOT스테핑 모터 2개 파실분 댓글 달아주세요2 뺘쑝 3431 2007.10.02
5 중고장터 HOT라인트레이서4 날라 3518 2007.09.12
4 중고장터 HOT[판매]오실로스코프 100Mhz3 아크마 4659 2007.06.21
3 중고장터 HOT흥창 100Mhz 5510 오실로 스코프5 살러만 6238 2007.06.13
2 중고장터 HOT89c51 파라요!!11 아크마 4414 2007.05.28
1 중고장터 HOT중고 장터가 문을 열었습니다. 아크마 4399 2007.05.20
  • 모든 죄악의 기본은 조바심과 게으름이다.
    - 카프카
  • * 납포인트 정보 *
  • 글 작성 : 3
  • 댓글 작성 : 1
  • 내 글이 추천받음 : 1
저작권법에 위배되는 콘텐츠는 등록 불가하며, 저작물에 대한 권리는 저작자에게 있습니다.
Copyright 2006-2021 © hardwareis.com, All rights reserved.