로봇_PROJECT/센서부

초음파센서 3개돌리기 (SFR05 이용 두전째) PIT(내부인터럽트) 와 외부인터럽트

빛나는 미래 2010. 4. 15. 21:54

//----------PIT---------------------------------------------------------------------
#define  PIT_PIVR (*(volatile unsigned int *) 0xFFFFFD38)
#define PITC_PIMR (*(volatile unsigned int *) 0xFFFFFD30)

//------------PIO------------------------------------------------------------------
#define PIO_ASR  (*(volatile unsigned int *) 0xFFFFF470)//
#define PIO_SODR (*(volatile unsigned int *) 0xFFFFF430)
#define PIO_CODR (*(volatile unsigned int *) 0xFFFFF434)
#define PIO_OER  (*(volatile unsigned int *) 0xFFFFF410)//
#define PIO_BSR  (*(volatile unsigned int *) 0xFFFFF474)//
#define PIO_PDR  (*(volatile unsigned int *) 0xFFFFF404)//
#define PIO_IFER (*(volatile unsigned int *) 0xFFFFF420)//
#define PIO_PDSR (*(volatile unsigned int *) 0xFFFFF43C)//
#define PIO_PER  (*(volatile unsigned int *) 0xFFFFF400)//
#define PIO_ODR  (*(volatile unsigned int *) 0xFFFFF414)
#define PIO_PUER (*(volatile unsigned int *) 0xFFFFF464)
#define PIO_ISR  (*(volatile unsigned int *) 0xFFFFF44C)
#define PIO_PUDR (*(volatile unsigned int *) 0xFFFFF460)// 풀업저항 인터럽트 레지스
#define PIO_ODSR (*(volatile unsigned int *) 0xFFFFF438) 
#define PIO_IER  (*(volatile unsigned int *) 0xFFFFF440)  //인터럽트 인에이플 레지스터

//-----RSTC --------------------------------------------------------------
//#define RSTC_MR (*(volatile unsigned int *) 0xFFFFFD08)

//----- PMC -------------------------------------------------------------------

#define PMC_PCER (*(volatile unsigned int *) 0xFFFFFC10)
//------AIC---------------------------------------------------------------------
#define AIC_IDCR (*(volatile unsigned int *) 0xFFFFF124)
#define AIC_SVR  ((volatile unsigned int *)  0xFFFFF080)
#define AIC_SMR  ((volatile unsigned int *)  0xFFFFF000)   //   인터럽트 설정
#define AIC_ICCR (*(volatile unsigned int *) 0xFFFFF128)
#define AIC_IECR (*(volatile unsigned int *) 0xFFFFF120)
//---------DBGU--------------------------------------------------------
#define DBGU_MR (*(volatile unsigned int *) 0xFFFFF204)
#define DBGU_BRGR (*(volatile unsigned int *) 0xFFFFF220)
#define DBGU_CR (*(volatile unsigned int *) 0xFFFFF200)
#define DBGU_SR (*(volatile unsigned int *) 0xFFFFF214)
#define DBGU_RHR (*(volatile unsigned int *) 0xFFFFF218)
#define DBGU_THR (*(volatile unsigned int *) 0xFFFFF21C)
#define DBGU_IER (*(volatile unsigned int *) 0xFFFFF208)   // 인터럽트 설정 레지스터

#define MCK 48000000  

volatile unsigned int PIT_count=0;  // PIT interrupt count
volatile unsigned int PIT_flag=0;  // PIT interrupt flag
unsigned int SUM_BUF_L[10];  
unsigned int SUM_BUF_F[10];
unsigned int SUM_BUF_R[10];

unsigned int OUTPUT_COUNT_FRONT=0;//정면 센서값  변수
unsigned int OUTPUT_COUNT_LEFT=0;
unsigned int OUTPUT_COUNT_RIGHT=0;

 unsigned int F_LOOF_FLAG=0;
 unsigned int L_LOOF_FLAG=0;
 unsigned int R_LOOF_FLAG=0;
 
void Delay_ms(unsigned int ms)   /* ms delay for -O2 -Otime option */
{ volatile unsigned int count, countmax = (MCK / 10000) * ms;

for(count = 0; count < countmax; count++);
}

void Delay_us(unsigned int us)   /* us delay for -O2 -Otime option */
{ volatile unsigned int count, countmax = (MCK / 9600000) * us;

for(count = 0; count < countmax; count++);
}

void DBGU_TX_char(unsigned int data)  /* transmit a character by DBGU */
{
 while(!(DBGU_SR & 0x0002));  // wait until TXRDY=1

 DBGU_THR = data;   // transmit a character
}


void DBGU_string(char *string)   /* transmit a string by DBGU */
{
 while(*string != '\0')
 { DBGU_TX_char(*string);
 string++;
 }
}

unsigned int DBGU_RX_char(void)   /* receive a character by DBGU */
{
 while(!(DBGU_SR & 0x0001));  // wait until RXRDY=1
 return DBGU_RHR;   // receive a character
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void L_FILTER_LINE_UP(unsigned int x)
{
unsigned int i,j,temp;
//출력받은 데이타를 메모리에 저장

 for(i=0;i<10;i++)//데이타의 입력
 {
  SUM_BUF_L[i]=x;
 }
//데이터가 박은 값을 우선으로 정렬한다

for(i=0;i<9;i++)
 {
  for(j=i+1;j<10;j++)
  {
   if(SUM_BUF_L[i]>SUM_BUF_L[j])

   {
    temp=SUM_BUF_L[j];
    SUM_BUF_L[j]=SUM_BUF_L[i];
    SUM_BUF_L[i]=temp;
   }

  }
 }

}
//=--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void F_FILTER_LINE_UP(unsigned int x)
{
unsigned int i,j,temp;
//출력받은 데이타를 메모리에 저장

 for(i=0;i<10;i++)//데이타의 입력
 {
  SUM_BUF_F[i]=x;
 }
//데이터가 박은 값을 우선으로 정렬한다

for(i=0;i<9;i++)
 {
  for(j=i+1;j<10;j++)
  {
   if(SUM_BUF_F[i]>SUM_BUF_F[j])

   {
    temp=SUM_BUF_L[j];
    SUM_BUF_F[j]=SUM_BUF_F[i];
    SUM_BUF_F[i]=temp;
   }

  }
 }

}
//--------------------------------------------------------
void R_FILTER_LINE_UP(unsigned int x)
{
unsigned int i,j,temp;
//출력받은 데이타를 메모리에 저장

 for(i=0;i<10;i++)//데이타의 입력
 {
  SUM_BUF_R[i]=x;
 }
//데이터가 박은 값을 우선으로 정렬한다

for(i=0;i<9;i++)
 {
  for(j=i+1;j<10;j++)
  {
   if(SUM_BUF_R[i]>SUM_BUF_R[j])

   {
    temp=SUM_BUF_R[j];
    SUM_BUF_R[j]=SUM_BUF_R[i];
    SUM_BUF_R[i]=temp;
   }

  }
 }

}
void PIT_ISR(void)    /* PIT interrupt service routine */

 
 unsigned int PITPIVR;
 PITPIVR=PIT_PIVR;// PIT COUNT RESET ???
 //-------------------송신부 설정 ----------------------------------------------
 PIT_count++;     // increment PIT_count

 if(PIT_count < 10)    // 400Hz/5 = 80Hz (그러나 반주기 동안만 불이켜지게되므로 80Hz/2=40Hz(25ms))
  return;
 PIT_count = 0;    // if PIT_count=10, clear it

 PIO_SODR = ((unsigned int)1 << 13)|((unsigned int)1 << 11)|((unsigned int)1 << 12);
 Delay_us(10);
 PIO_CODR = ((unsigned int)1 << 13)|((unsigned int)1 << 11)|((unsigned int)1 << 12);
 DBGU_string("\r송신트리거 발송\r\n");   
  
}

 

void PIO_ISR_EXTERN(void)// 외부인터럽트 처리 함수(초음파 출력파형을 처리한다)
{
 unsigned int num=10000;//전송하고자하는 문자열의 단뒤 예 2자리일경우 10 3자리일경우 100
 //unsigned int status;
 unsigned int i;//루프돌리기위한  변수
 unsigned int PIOPDSR;// PDSR 값 저장을위한 변수
 unsigned int FLAG=0;//  출력값을  읽었을 때 만 기억하는 플래그
 
 unsigned int L_FILTER_VALUE;//필터된 값
 unsigned int TANSFER_BUF_L[6];//하이퍼 터미널로 전달 할 버퍼

 unsigned int F_FILTER_VALUE;//필터된 값
 unsigned int TANSFER_BUF_F[6];//하이퍼 터미널로 전달 할 버퍼
 
 unsigned int R_FILTER_VALUE;//필터된 값
 unsigned int TANSFER_BUF_R[6];//하이퍼 터미널로 전달 할 버퍼
 

 
//--------------- 센서 수신부 입력 받는 곳 ----------------------
  
   PIOPDSR=PIO_PDSR;
 //  status=PIO_ISR;
  
 

//------------FRONT SENSOR-----------------------------------------------------

while((F_LOOF_FLAG<11) && (PIO_PDSR &((unsigned int)0x4000)))//신호 10개를 측정
 {
     while(PIO_PDSR &((unsigned int)0x4000))// 출력값 측정 PA14번 포트
       {
        OUTPUT_COUNT_FRONT++; //초음파 센서 데이터 측정
        FLAG=1;
       }
     if(FLAG==1) //카운터 했을때만 출력을 한다
         {
       DBGU_string("\r센서FRONT입력들어옴2 \r\n");
       OUTPUT_COUNT_FRONT=OUTPUT_COUNT_FRONT/80;
       //수치를 cm 변환 하드웨어 DATA SHEET상 54로나누면 센지 148로 나누면 인치로 변환
      
        F_FILTER_LINE_UP(OUTPUT_COUNT_FRONT);//데이타 정렬
  
        FLAG=0;// 플레그 초기화
      }
     
            F_LOOF_FLAG++;
 }
  //----------------------------------------------------------------------
  if(F_LOOF_FLAG>0)   
  
   { DBGU_string("\rF루프 입력들어옴 \r\n");
      for(i=1;i<9;i++) //7개의 데이타중 앞뒤 2개의 데이타  필터링, 튀는 값(앞뒤) 버림
      {
       F_FILTER_VALUE+=SUM_BUF_F[i];// 8개의 데이타 합산
      }
       F_FILTER_VALUE=F_FILTER_VALUE/8;//8개의 데이타 평균
      
       for(i=0;i<10;i++)//버퍼의 초기화
   {
    SUM_BUF_F[i]=0;
   }
        
      for(i=0;i<5;i++)//전송하는 문자열의  개수 만큼 루프돌린다.
      {
       TANSFER_BUF_F[i]=(F_FILTER_VALUE%(10*num)-F_FILTER_VALUE%num)/num + 48;//숫자를 문자로변환
    
       num/=10;//숫자의 단위를 감소시키기 위함
       DBGU_TX_char(TANSFER_BUF_F[i]);//캐릭터 문자 1바이트  전송
      }
    
      DBGU_TX_char('\r');// 커서 맨앞으로 이동
      DBGU_TX_char('\n');//  커서 줄바꾸기
      OUTPUT_COUNT_FRONT=0;//다음 초음파  출력값을 받기위해 리셋
      F_LOOF_FLAG=0; 
      }
      num=10000;//자릿수 초기화
    
 //------------LEFT SENSOR---------------------------------15--------------------    
      while((L_LOOF_FLAG<11) && (PIO_PDSR &((unsigned int)0x8000)))//신호 10개를 측정
 {
     while(PIO_PDSR &((unsigned int)0x8000))// 출력값 측정 PA15번 포트
       {
        OUTPUT_COUNT_LEFT++; //초음파 센서 데이터 측정
        FLAG=2;
       }
     if(FLAG==2) //카운터 했을때만 출력을 한다
         {
       DBGU_string("\r센서LEFT입력들어옴2 \r\n");
       OUTPUT_COUNT_LEFT=OUTPUT_COUNT_LEFT/80;
       //수치를 cm 변환 하드웨어 DATA SHEET상 54로나누면 센지 148로 나누면 인치로 변환
      
        L_FILTER_LINE_UP(OUTPUT_COUNT_LEFT);//데이타 정렬
  
        FLAG=0;// 플레그 초기화
      }
     
            L_LOOF_FLAG++;
 }
  //----------------------------------------------------------------------
  if(L_LOOF_FLAG>0)   
  
   { DBGU_string("\rL루프 입력들어옴 \r\n");
      for(i=1;i<9;i++) //7개의 데이타중 앞뒤 2개의 데이타  필터링, 튀는 값(앞뒤) 버림
      {
       L_FILTER_VALUE+=SUM_BUF_L[i];// 8개의 데이타 합산
      }
       L_FILTER_VALUE=L_FILTER_VALUE/8;//8개의 데이타 평균
      
       for(i=0;i<10;i++)//버퍼의 초기화
   {
    SUM_BUF_L[i]=0;
   }
        
      for(i=0;i<5;i++)//전송하는 문자열의  개수 만큼 루프돌린다.
      {
       TANSFER_BUF_L[i]=(L_FILTER_VALUE%(10*num)-L_FILTER_VALUE%num)/num + 48;//숫자를 문자로변환
    
       num/=10;//숫자의 단위를 감소시키기 위함
       DBGU_TX_char(TANSFER_BUF_L[i]);//캐릭터 문자 1바이트  전송
      }
    
      DBGU_TX_char('\r');// 커서 맨앞으로 이동
      DBGU_TX_char('\n');//  커서 줄바꾸기
      OUTPUT_COUNT_LEFT=0;//다음 초음파  출력값을 받기위해 리셋
      L_LOOF_FLAG=0; 
      }
      num=10000;//자릿수 초기화

 

//------------RIGHT SENSOR---------------------------------15--------------------    
      while((R_LOOF_FLAG<11) && (PIO_PDSR &((unsigned int)0x100)))//신호 10개를 측정
 {
     while(PIO_PDSR &((unsigned int)0x100))// 출력값 측정 PA15번 포트
       {
        OUTPUT_COUNT_RIGHT++; //초음파 센서 데이터 측정
        FLAG=3;
       }
     if(FLAG==3) //카운터 했을때만 출력을 한다
         {
       DBGU_string("\r센서RIGHT입력들어옴2 \r\n");
       OUTPUT_COUNT_RIGHT=OUTPUT_COUNT_RIGHT/80;
       //수치를 cm 변환 하드웨어 DATA SHEET상 54로나누면 센지 148로 나누면 인치로 변환
      
        R_FILTER_LINE_UP(OUTPUT_COUNT_RIGHT);//데이타 정렬
  
        FLAG=0;// 플레그 초기화
      }
     
            R_LOOF_FLAG++;
 }
  //----------------------------------------------------------------------
  if(R_LOOF_FLAG>0)   
  
   { DBGU_string("\rR루프 입력들어옴 \r\n");
      for(i=1;i<9;i++) //7개의 데이타중 앞뒤 2개의 데이타  필터링, 튀는 값(앞뒤) 버림
      {
       R_FILTER_VALUE+=SUM_BUF_R[i];// 8개의 데이타 합산
      }
       R_FILTER_VALUE=R_FILTER_VALUE/8;//8개의 데이타 평균
      
       for(i=0;i<10;i++)//버퍼의 초기화
   {
    SUM_BUF_R[i]=0;
   }
        
      for(i=0;i<5;i++)//전송하는 문자열의  개수 만큼 루프돌린다.
      {
       TANSFER_BUF_R[i]=(R_FILTER_VALUE%(10*num)-R_FILTER_VALUE%num)/num + 48;//숫자를 문자로변환
    
       num/=10;//숫자의 단위를 감소시키기 위함
       DBGU_TX_char(TANSFER_BUF_R[i]);//캐릭터 문자 1바이트  전송
      }
    
      DBGU_TX_char('\r');// 커서 맨앞으로 이동
      DBGU_TX_char('\n');//  커서 줄바꾸기
      OUTPUT_COUNT_RIGHT=0;//다음 초음파  출력값을 받기위해 리셋
      R_LOOF_FLAG=0; 
      }
      num=10000;//자릿수 초기화           


}
 int main(void)
 {

  //-----------DBGU-----------------------------------------------------------------------------
  PMC_PCER = (unsigned int) 1 << 2;  // enable clock of DBGU 주변장치의 전력공급을 시작한다
  DBGU_MR = 0x00000800;   // normal mode, no parity
  DBGU_BRGR = 26;   // MCK/16/26 = 115200 bps
  DBGU_CR = 0x00000150;   // TX, RX enable
  DBGU_IER = ((unsigned int)1<<0);//수신 인터럽트 설정
  // DTXD, DRXD by Peripheral A
  PIO_ASR = (unsigned int) 1 << 10 | (unsigned int) 1 <<  9;
  PIO_BSR = 0;
  PIO_PDR = (unsigned int) 1 << 10 | (unsigned int) 1 <<  9;// 해당포트를 i/o 포트로사용을 금지 한다(주변장치사용)
  
  //-----PIO----------------------------------------------------------------------------------------------------
  //PIO_CODR = 0x00003FFF; // 

  PIO_PER = ((unsigned int)1 << 11)|((unsigned int)1 << 12)|((unsigned int)1 << 13)
     |((unsigned int)1 << 14)|((unsigned int)1 << 15)|((unsigned int)1 << 8); // 다음 포트를 주변장치가 아닌 Set in PIO mode 사용 */
  
  PIO_OER = ((unsigned int)1 << 11)|((unsigned int)1 << 12)|((unsigned int)1 << 13)
     |((unsigned int)1 << 14)|((unsigned int)1 << 15)|((unsigned int)1 << 8);// 다음포트 를사용하겠다

  PIO_ODR  = (1 << 14)|(1 << 15)|(1 << 8);
  
  PIO_IER  = ((unsigned int)1 << 14)|((unsigned int)1 << 15)|((unsigned int)1 << 8);// 인터럽트 사용을 허가한다
  
  PIO_PUDR = ((unsigned int)1 << 14)|((unsigned int)1 << 15)|((unsigned int)1 << 8);// 풀업저항 금지  즉 입력포트로 설정 하겠다
  PIO_IFER = ((unsigned int)1 << 14)|((unsigned int)1 << 15)|((unsigned int)1 << 8);// 글리치 필터(마스터 클럭의 1/2 이하의 주기는 잡음으로 간주하여 무시한다)
  //--------PIT----------------------------------------------------------------------------------------

  // enable peripheral clock for PIT
  PMC_PCER |= ((unsigned int)1 << 1);

  PITC_PIMR = (15000-1)|((unsigned int)1 << 24)|((unsigned int)1 << 25);

  //---------AIC-------------------------------------------------------------------
  //-------- 내부 인터럽트 설정 (PIT)----------------------------------------------
  //* Disable the interrupt on the interrupt controller
  AIC_IDCR = (unsigned int)1 << 1; // 1 시스템(sys:PMC, DBGU,RTT, PIT,EFC)등 관련  2 입출력관련(PIOA)

  //* Save the interrupt handler routine pointer and the interrupt priority
  AIC_SVR[1] = (unsigned int)PIT_ISR;
  //* Store the Source Mode Register
  AIC_SMR[1] = 7 ; // SRCTYPE 00  설정  PRIOR(우선순위):7 가장 높음
  //* Clear the interrupt on the interrupt controller
  AIC_ICCR = (unsigned int)1 << 1;
  
  AIC_IECR = (unsigned int)1 << 1;
  //------ 외부 인터럽트 설정
  AIC_IDCR|=(unsigned int)1<<2;    //마스크 설정
   AIC_SVR[2]=(unsigned int)PIO_ISR_EXTERN;      //인터럼트 함수 설정
   AIC_SMR[2]=5;//
   AIC_IECR|=(unsigned int)1<<2;    //인터럽트 허용 명령 레지스터
   AIC_ICCR|=(unsigned int)1<<2;    //인터럽트를 엣지클리어 명령레지스터
   
  PIO_CODR = ((unsigned int)1 << 14)|((unsigned int)1 << 15)|((unsigned int)1 << 8);
  while(1);  // wait for interrupt
 
}