회원가입 ID/PW 찾기
AA

안녕 하세요. 질문을 할려구요.. 제 소스가 뭐가 잘못 된건지 좀 봐 주실수 있어요!?

일단.. 이건.. 제가 암로봇에 팔을 움직일려고 만든 소스인데요..

컴파일 상에는 에러가 없는데.. 동작이 안되서..;; 문제는

인터럽트

interrupt [USART0_RXC] void usart0_rxc(void)
{
       ch[ch_num] = UDR0;
       ch_num++;
}
여기에 있는거 같은데.. 확실히 모르겠어요;; ㅠㅠ

전체적인 동작은..

암보드에서 a,s,d,f값을 받아서.. 각자의 값에 맞춰서 동작을 하는건데..

ch 라는 배열을 둬서.. 로봇이 동작하는 동안에도 값은 계속 입력 받아서..

한동작이 끝나면 바로 다음 동작이 되도록.. 할려고 하는데..

입력을 한개씩 받을때는 동작을 하는데.. 저렇게 인터럽트를 주면 동작을 안하더라구요.. ㅠㅠ

조금만 도와 주세요~.. 이그응;;



#include <mega128.h>
#include <delay.h>


//char Getch(void); // USART 수신 받는 문자
void motor_mode1(); // 모터 제어 첫번째 모드(앞뒤)
void motor_mode2(); // 모터 제어 두번째 모드(좌우)
void motor_autocontrol(); // 모터 자동 제어 모드
void motor_reset(); // 처음 상태로 변환
                          

char ch[10] = {0};
int ch_num = 0;
typedef unsigned char byte;
unsigned int tim0_cnt, mot_pos, change;
unsigned int rc_time[4] = {54, 132, 210, 132}; // 모터 데이터 시트 보고 수정   
int ex = 0;

  /*
char Getch(void)
{
        while(!(UCSR0A & 0x80));
        return UDR0;
}                  
*/                  
void motor_mode1() // 모터 제어 첫번째 모드(앞뒤)
{
        motor_reset(); // 원래 자리로 이동    

        PORTA = 0x00;
        DDRA = 0x37;    // PA0, PA1, PA2 사용
                        // PA4, PA5 사용
       
                                                      /*
                                                               PA0 = 왼팔 팔꿈치(0X01)
                                                               PA1 = 왼팔 팔 옆으로 벌리기(0X02)
                                                               PA2 = 왼팔 팔 앞으로 벌리기(0X04)
                                                               PA4 = 오른팔 팔꿈치(0X10)
                                                               PA5 = 오른팔 옆으로 벌리기(0X20)
                                                       */
       
 tim0_cnt = 0;   // 타이머/카운터0 오버플로우 횟수 리셋
 mot_pos = 0;    // 모터 위치 0도
 change = 0;     // 각도 변화 주기 리셋
       
       
        // 타이머/카운터 0 ㅇ인터럽트 주기
        // 이론치 (256-241) * 8분주 * 1/16us = 7us 약 10us           
 TIMSK = 0x01;   // TIOIE0= 1;
 TCCR0 = 0x02;   // 일반 모드 , 프리스케일 = CK/8
 TCNT0 = 238;    // 타이머/카운터0 레지스터 초기값
 SREG = 0x80;    // 전역 인터럽트 인에이블 비트 I 셋

 tim0_cnt = 0;
 PORTA = 0xFF;// 모터 HIGH 출력
 while(tim0_cnt < 2000)
        {
                if(tim0_cnt >= 132) // 90도 각 맞추기
                {
                        PORTA = 0x00;
                }
                else
                {
                        PORTA = 0x22;
                }
        }
        tim0_cnt = 0;
        while(tim0_cnt < 2000)
        {
                if(tim0_cnt >= 132) // 90도 각 맞추기
                {
                        PORTA = 0x00;
                }
                else
                {
                        PORTA = 0x13;
                }
        }
        tim0_cnt = 0;
        ex = 0;
 while(ex < 100)
 {
  if(tim0_cnt >= 2000)  // 10us * 2000 = 20ms 주기 체크
  {
   tim0_cnt = 0;
   PORTA = 0x01;   //팔꿈치 이동
   change++;
                                      
   //20ms * 20 = 0.4sec 각도 변화 주기 체크
   if(change == 20)
   {
    mot_pos = (mot_pos + 1) % 4;
    change = 0;
    ex++;
   }
  }
  if(tim0_cnt >= rc_time[mot_pos]) // 모터 Low 출력
  {
   PORTA = 0x00;
  }
 }
       

void motor_mode2() // 모터 제어 두번째 모드(좌우)
{
        motor_reset();   
       
       
        PORTA = 0x00;
        DDRA = 0x37;    // PA0, PA1, PA2 사용
                        // PA4, PA5 사용
       
                                                      /*
                                                               PA0 = 왼팔 팔꿈치(0X01)
                                                               PA1 = 왼팔 팔 옆으로 벌리기(0X02)
                                                               PA2 = 왼팔 팔 앞으로 벌리기(0X04)
                                                               PA4 = 오른팔 팔꿈치(0X10)
                                                               PA5 = 오른팔 옆으로 벌리기(0X20)
                                                       */
       
 tim0_cnt = 0;   // 타이머/카운터0 오버플로우 횟수 리셋
 mot_pos = 0;    // 모터 위치 0도
 change = 0;     // 각도 변화 주기 리셋
       
       
        // 타이머/카운터 0 ㅇ인터럽트 주기
        // 이론치 (256-241) * 8분주 * 1/16us = 7us 약 10us           
 TIMSK = 0x01;   // TIOIE0= 1;
 TCCR0 = 0x02;   // 일반 모드 , 프리스케일 = CK/8
 TCNT0 = 238;    // 타이머/카운터0 레지스터 초기값
 SREG = 0x80;    // 전역 인터럽트 인에이블 비트 I 셋

 tim0_cnt = 0;
 PORTA = 0xFF;// 모터 HIGH 출력
 while(tim0_cnt < 2000)
        {
                if(tim0_cnt >= 132) // 90도 각 맞추기
                {
                        PORTA = 0x00;
                }
                else
                {
                        PORTA = 0x22;
                }
        }
        tim0_cnt = 0;
        while(tim0_cnt < 2000)
        {
                if(tim0_cnt >= 132) // 90도 각 맞추기
                {
                        PORTA = 0x00;
                }
                else
                {
                        PORTA = 0x13;
                }
        }
        tim0_cnt = 0;   
        ex = 0;
 while(ex < 100)
 {
  if(tim0_cnt >= 2000)  // 10us * 2000 = 20ms 주기 체크
  {
   tim0_cnt = 0;
   PORTA = 0x10;   //팔꿈치 이동
   change++;
                                      
   //20ms * 20 = 0.4sec 각도 변화 주기 체크
   if(change == 20)
   {
    mot_pos = (mot_pos + 1) % 4;
    change = 0;
    ex++;
   }
  }
  if(tim0_cnt >= rc_time[mot_pos]) // 모터 Low 출력
  {
   PORTA = 0x00;
  }
 }

}


void motor_reset() // 처음 상태로 변환
{

        PORTA = 0x00;
        DDRA = 0x37;    // PA0, PA1, PA2 사용
                        // PA4, PA5 사용
       
                                                      /*
                                                               PA0 = 왼팔 팔꿈치(0X01)
                                                               PA1 = 왼팔 팔 옆으로 벌리기(0X02)
                                                               PA2 = 왼팔 팔 앞으로 벌리기(0X04)
                                                               PA4 = 오른팔 팔꿈치(0X10)
                                                               PA5 = 오른팔 옆으로 벌리기(0X20)
                                                       */
       
 tim0_cnt = 0;   // 타이머/카운터0 오버플로우 횟수 리셋
 mot_pos = 0;    // 모터 위치 0도
 change = 0;     // 각도 변화 주기 리셋
       
       
        // 타이머/카운터 0 ㅇ인터럽트 주기
        // 이론치 (256-241) * 8분주 * 1/16us = 7us 약 10us           
 TIMSK = 0x01;   // TIOIE0= 1;
 TCCR0 = 0x02;   // 일반 모드 , 프리스케일 = CK/8
 TCNT0 = 238;    // 타이머/카운터0 레지스터 초기값
 SREG = 0x80;    // 전역 인터럽트 인에이블 비트 I 셋

 tim0_cnt = 0;
 PORTA = 0xFF;// 모터 HIGH 출력
 while(tim0_cnt < 2000)
        {
                if(tim0_cnt >= 54)
                {
                        PORTA = 0x00;
                }
                else
                {
                        PORTA = 0x37;
                }
        }
}                                              

void motor_autocontrol() // 모터 자동 제어 모드
{
        while((ch[0] != 'f' || ch[0] != 'X'))
        {                              
                 motor_mode1();
                 motor_reset();
                 if((ch[0] != 'f' || ch[0] != 'X'))
                {
                        motor_mode2();
                        motor_reset();
                }
        }
}

interrupt [TIM0_OVF] void timer_int0(void)
{
 tim0_cnt++;
 TCNT0 = 238;
}
interrupt [USART0_RXC] void usart0_rxc(void)
{
       ch[ch_num] = UDR0;
       ch_num++;
}


void main()
{              

        int exit = 0;   
        int i;
       
        DDRA = 0x00; // PORT A를 모터 제어 포트로 사용
        PORTA = 0x00;
       
        SREG |= 0x80; // 인터럽트 사용
       
        UCSR0A = 0x00;
        UCSR0B = 0b00010000; // 수신기 인에이블이 되어 수신 가능 상태가 됨
        UCSR0C = 0b10000110; // bit 2, bit 1은 전송 데이터 비트 수로 8비트로 설정    
        UBRR0H = 0;
        UBRR0L = 103; // X-TAL = 16MHz 일때 BAUD = 9600
       
        /*
        a = mode 1
        s = mode 2
        d = exit
        z = auto start
        x = auto end
        */

                
       
       
        while(exit != 1)
        {
                if(ch_num > 0 && (ch[0] == 'a' || ch[0] == 'A'))
                {     
                        for(i = 0; i < ch_num; i++)
                        {
                                ch[i] = ch[i+1];
                        }
                        ch[ch_num-1] = '\0';
                        ch_num--;
                               
                        motor_mode1(); // 모터 제어 첫번째 모드(앞뒤)
                      
                }
                else if(ch_num > 0 && (ch[0] == 's' || ch[0] == 'S'))
                {
                        for(i = 0; i < ch_num; i++)
                        {
                                ch[i] = ch[i+1];
                        }
                        ch[ch_num-1] = '\0';
                        ch_num--;
                       
                        motor_mode2(); // 모터 제어 두번째 모드(좌우)
                }
                else if(ch_num > 0 && (ch[0] == 'd' || ch[0] == 'Z'))
                {
                        for(i = 0; i < ch_num; i++)
                        {
                                ch[i] = ch[i+1];
                        }
                        ch[ch_num-1] = '\0';
                        ch_num--;
                                       
                       motor_autocontrol(); // 모터 자동 제어 모드
                }
                else if(ch_num > 0 && (ch[0] == 'f' || ch[0] == 'D'))
                {
                        for(i = 0; i < ch_num; i++)
                        {
                                ch[i] = ch[i+1];
                        }
                        ch[ch_num-1] = '\0';
                        ch_num--;
                                       
                        motor_reset(); // 처음 상태로 변환  
                        exit = 1;
                }      
        }      
}

댓글 6
  • No Profile
    배열 버퍼에 값이 저장되는데..

    interrupt [USART0_RXC] void usart0_rxc(void)
    {
           ch[ch_num] = UDR0;
           ch_num++;
    }

    여기 소스 보시면 ch_num 부분이 특정값이상 올라가게 된다면 어떻게 될까요?

    main문 보니까 ch_num--가 있긴 한데  잘 동작할지 여부가..

    배열이 가득찰때를 대비해서 먼가 대비를 해야할거 같네요.


    if(ch_num>100)
    내용

    머 이런식이 되겠지만 이런경우는 mcu처리속도가 통신속도에 못따라 가면 문제가 생길수 있는 소지가 있습니다.

    님의 경우는 잘 따라가겠지만 문제는 배열에 저장되는 값이 문제라면

    일단 소스를 다 지우고 시리얼로 값을 보내고 그 값을 lcd로 확인하는 작업을 먼저 수행하여

    통신의 신뢰성을 확보하시고 그 다음 작업으로 넘어가시길 추천합니다.

    제가 바빠서 전체 소스는 못보고 스크롤로 살짝 봐서 정확히 짚어드리기는 좀 힘들겠어요.. ㅈㅅ
  • No Profile
    글쓴이 행복하면 08.03.10 14:46 댓글 좋아요 0 싫어요 0

    움.. 인터럽트에서는 입력을 못 받더라구요..
    그래서 이렇게 쓰는게 아닌가라는 생각이 들어서;; ㅋ
    다르게 입력을 받으면 받아 지는데;; 이그응;; ㅋ

  • No Profile

    음 인터럽트 자체가 동작을 안하나봐요??

  • No Profile
    코드비젼 같은데요..

    asm("sei"); 이부분이 눈에 안보이네요..

    전체 인터럽트 enable시켜주는 명령어인데요 이걸 해줘야 인터럽트가 동작할텐데요

    인터럽트가 작동되는 소스에서 저 부분을 한번 찾아보세요^^;;

    소스 함수별로 진단도 해보시고요^^;
  • No Profile
    글쓴이 행복하면 08.03.10 23:52 댓글 좋아요 0 싫어요 0

     SREG |= 0x80; // 인터럽트 사용

    이걸로 인터럽트 사용한다고 지정을 해 봤는데;; ㅋㅋ

    움.. ㅋㅋㅋ 그냥.. 인터럽트 사용안하고..

    프로그램을 짰어요;; ㅋㅋ;;

    이그응..;;

  • ㅎㅎㅎㅎㅎㅎ

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

search
번호 분류 제목 글쓴이 조회 수 날짜
34 Allegro & OrCAD HOTorcad2 마로요 1065 2008.08.29
33 PADS HOTFootPrint작성시-Padstack or Layer Name2 써치와니 1950 2008.05.28
32 Allegro & OrCAD HOTLayout footprint를 수정한후 이것을 이전에 저장해둔 max 파일에 적용할려면요?1 조디악 950 2008.05.25
31 ECAD 아무거나 HOT드릴홀 크기는 몇mil 로 하는것이 적당한가요3 조디악 3946 2008.05.16
30 ECAD 아무거나 HOTmil 이란 무엇인가요??7 앙큼상큼저뽀 3889 2008.04.10
29 ECAD 아무거나 HOTSMPS 관련...4 날뽕녀 3583 2008.04.10
28 PADS HOTpads2005의 라이브러리 질문 입니다.5 pads 1605 2008.03.21
27 Allegro & OrCAD HOTorcad에서 drc중 error에 관해3 능글토끼 1667 2008.03.21
26 Allegro & OrCAD HOT레이아웃 질문이요..ㅜㅜ1 무수리 849 2008.03.10
25 Allegro & OrCAD HOT넷리스트 만들면요...15 무수리 1419 2008.02.29
24 ECAD 아무거나 HOT허접한 질문입니다..7 무수리 3158 2008.02.28
23 Allegro & OrCAD HOT지금 orcad로 제가 만들어야 할 로봇 회로도를 만드는데..3 행복하면 978 2008.02.15
22 ECAD 아무거나 HOT그리고 회로도를 그릴 때 AVR 있잖아요3 무수리 2217 2008.01.30
21 ECAD 아무거나 HOTAVR에 전원 인가 하는 거 있잖아요3 무수리 3421 2008.01.30
20 ECAD 아무거나 HOT간단한 문제좀 해결해 주세요^^5 로봇마스터 3013 2008.01.17
19 ECAD 아무거나 HOT책을 보면서 공부 중인데요3 무수리 4238 2008.01.17
18 Allegro & OrCAD HOTlayout 에서요...???3 날뽕녀 1035 2008.01.16
17 ECAD 아무거나 HOTPCB 관련해서 좋은 책 없을까요??2 무수리 3287 2008.01.09
16 ECAD 아무거나 HOTPCB 제작하려면 처음에 설정을 어떻게 해야 되나요??1 무수리 3328 2008.01.09
15 Allegro & OrCAD HOT웈,,,, 디맨젼 사이즈 소수점으로 나오내요..2 shin 1456 2007.11.25
  • 일을 할 때는 반드시 미리 계획을 짜야하고, 말을 할 때는 반드시 실천할 수 있는 것인지 생각해야 한다.
    - 소학
  • * 납포인트 정보 *
  • 글 작성 : 3
  • 댓글 작성 : 1
  • 내 글이 추천받음 : 1
저작권법에 위배되는 콘텐츠는 등록 불가하며, 저작물에 대한 권리는 저작자에게 있습니다.
Copyright 2006-2021 © hardwareis.com, All rights reserved.