Busan IT/ARM Controller2015. 9. 10. 17:14

==================================Outline====================================

초음파 센서 동작

----------------------------------------------------------------------------

 

초음파 센서를 작동시키기 위한 코드를 계속 작성해보자.

 

 

타이밍도를 보면 펄스를 10us 동안 high로 유지하면 ultrasonic8 cycle 동안 발생한다. 이 후에 echo 펄스가 방출되어 돌아오기 직전까지 high가 유지된다.

 

echo펄스가 high를 유지한 동안의 클럭을 측정해주면 거리가 나오게 되는 것이다.

 

펄스 측정을 위해 ARM의 핀을 활성화 해주고 초음파 센서와 연결하는 작업을 해주어야 한다.

//장치를 사용하기 위한 작업을 인터페이싱이라고 한다.

 

mode 1을 사용해 줄 것이기 때문에 핀을 4개만 사용한다.

시연 동영상 - https://www.youtube.com/watch?v=bPN0R7o3wXY 


코드는 아래와 같다.


/*** ultra.c ***/

#include <project.h>

static volatile unsigned int uiCM;
static volatile unsigned int uiState = INIT_OFF;

static void UTimer_Init(void);
static void Ultra_ISR(void);
static void U_Trigger_Init();
static void U_Echo_Init();
static void U_Trigger();

static void UTimer_Init(void)
{
// 타이머 카운터 0 사용을 위한 PMC 활성화(AT91C_ID_TC0) // p33 : // p204 : //p20 : 주소 
  *AT91C_PMC_PCER = 1 << AT91C_ID_TC0;
// 1.시작 : 타이머 클럭 비활성화 ------------------
// 타이머 클럭 비활성화(TC_CCR 설정) - 설정 중에 작동하는 것을 막기 위해
  *AT91C_TC0_CCR = AT91C_TC_CLKDIS;

// 2. 시작 : 타이머 인터럽트 비활성화 -------------
// 타이머 인터럽트 비활성화(TC_IDR 설정)
  *AT91C_TC0_IDR = 0xFF;  // p479
// 인터럽트 상태 정보 초기화(TC_SR 읽기)
  *AT91C_TC0_SR;  // 언급만 하면 읽은 효과  => 읽으면 0 이 됨 //p476

// 분주비 128, 비교 방식 레지스터 설정(TC_CMR, DIV4_CLOCK, AT91C_TC_CPCTRG) 
// MCKR divided by 4096 => 12, 0.25us(TC_RC 설정) 
  *AT91C_TC0_CMR = AT91C_TC_CLKS_TIMER_DIV4_CLOCK | AT91C_TC_CPCTRG;  // register c와 비교 
  

// 타이머 카운터 0 인터럽트 비활성화(AIC_IDCR, AT91C_ID_TC0)
  *AT91C_AIC_IDCR = 1 << AT91C_ID_TC0; // p33
  
// 3. 시작 : 타이머 카운터 0 인터럽트 비활성화 ------
// 타이머 카운터 0 인터럽트 핸들러 등록(AIC_SVR[AT91C_ID_TC0], timer_handler)
// 타이머 카운터 0 인터럽트 모드 설정(AIC_SMR[AT91C_ID_TC0], AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, AT91C_AIC_PRIOR_LOWEST)
// 타이머 카운터 0 인터럽트 클리어(AIC_ICCR, AT91C_ID_TC0)
  AT91C_AIC_SVR[AT91C_ID_TC0] = (unsigned int)Ultra_ISR;  // p175
  AT91C_AIC_SMR[AT91C_ID_TC0] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | AT91C_AIC_PRIOR_LOWEST;
  *AT91C_AIC_ICCR = 1 << AT91C_ID_TC0;
// TC_RC 값 비교 타이머 인터럽트 활성화(TC_IER, AT91C_TC_CPCS)
  *AT91C_TC0_IER = AT91C_TC_CPCS;
// MCKR divided by 128 => 375, 0.001sec(TC_RC 설정) 
  *AT91C_TC0_RC = 22;
// 2. 끝 : 타이머 인터럽트 비활성화 ---------------

// 타이머 카운터 0 인터럽트 활성화(AIC_IECR, AT91C_ID_TC0)
  *AT91C_AIC_IECR = 1 << AT91C_ID_TC0;

// 3. 끝 : 타이머 카운터 0 인터럽트 비활성화 -------

// 타이머 클럭 활성화(TC_CCR, AT91C_TC_CLKEN)
  *AT91C_TC0_CCR = AT91C_TC_CLKEN;
// 1. 끝 : 타이머 클럭 비활성화 ------------------

// 타이머 시작(TC_CCR, AT91C_TC_SWTRG)
//  *AT91C_TC0_CCR = AT91C_TC_SWTRG;

  return;
}

static void Ultra_ISR(void)    //소리가 1cm움직이면 
{
// 인터럽트 상태 정보 초기화(TC_SR 읽기)
  *AT91C_TC0_SR;  // 언급만 하면 읽은 효과  => 읽으면 0 이 됨 //p476  
  ++uiCM;      //uiCM 값이 초음파로부터 물체가 떨어진 거리(cm)
  return;
}

static void U_Trigger_Init()
{  
  *AT91C_PMC_PCER =1<< AT91C_ID_PIOA;  //Peripheral Clock Supply PIOA
  *AT91C_PIOA_PER = UTRI_PIN;      //PIO Enable Register  
  *AT91C_PIOA_PPUDR = UTRI_PIN;    //Pull-up Disable Register
  *AT91C_PIOA_OER = UTRI_PIN;      //Output Enable Register
  *AT91C_PIOA_CODR = UTRI_PIN;    //Clear Output Data Register
  
}

static void U_Echo_Init()
{  
  *AT91C_PMC_PCER = 1<<AT91C_ID_PIOA;  //Peripheral Clock Supply PIOA
  *AT91C_PIOA_PER = ECHO_PIN;      //PIO Enable Register - enabling pin means enabling input function
  *AT91C_PIOA_PPUDR = ECHO_PIN;    //Pull-up Disable Register  
}

static void U_Trigger()
{
  volatile unsigned int uiCnt;
  
  *AT91C_PIOA_CODR = UTRI_PIN;    //Clear Output Data Register

  /*** PULSE FOR TRIGGER ***/
  for(uiCnt = 0; uiCnt <1000 ; ++uiCnt);
  *AT91C_PIOA_SODR = UTRI_PIN;    //SET Output Data Register

  for(uiCnt = 0; uiCnt <1000 ; ++uiCnt);
  *AT91C_PIOA_CODR = UTRI_PIN;    //Clear Output Data Register
  /////////////////////////////////  
  
}

void Ultra_Init()
{
  UTimer_Init();
  U_Trigger_Init();    
  U_Echo_Init();
  
  uiState = INIT_ON;
  
}

unsigned int Ultra_Run()
{
  if(uiState == INIT_OFF)
  {
    LCD_Inst(LCD_INST_CLR);
    LCD_Inst(LCD_INST_HOME);
    LCD_Print("Error");
    return 0;
  }  

  uiCM = 0;  //distance 0
  *AT91C_TC0_CCR = AT91C_TC_CLKEN;  //Timer enable
  U_Trigger();  
  
  while(  0 == ((*AT91C_PIOA_PDSR) & (ECHO_PIN))  );  //holding when echo is low
  *AT91C_TC0_CCR = AT91C_TC_SWTRG;  //Timer init.

  while(  0 != ((*AT91C_PIOA_PDSR) & (ECHO_PIN))  );  //holding when echo is not low
  *AT91C_TC0_CCR = AT91C_TC_CLKDIS;  //Timer disable

  return uiCM;
}


/*** main.c ***/

#include <project.h> 
#include <stdlib.h>
#include <string.h>

volatile unsigned int uiCnt;

#define Delay(x) for(uiCnt = 0; uiCnt < x; ++uiCnt)

void Init(void)
{
  LCD_Init();
  Ultra_Init();    
    
  return;
}

int main(void)
{    
  int iCnt;
  char cADist[] ="000cm" ;
  unsigned int uiCM;
  Init();
  LCD_Inst(0x0C);
  while(1)
  {
    uiCM = Ultra_Run();
    if(uiCM == 0)
    {
      LCD_Inst(LCD_INST_CLR);
      LCD_Inst(LCD_INST_HOME);
      LCD_Print("Error");
      continue;        
    }
    
    cADist[0= uiCM/100 + '0';
    cADist[1= (uiCM%100)/10 + '0';
    cADist[2= uiCM%10 + '0';
          
    LCD_Inst(LCD_INST_HOME);    
    LCD_Print(cADist);
    for(iCnt=0; iCnt < 5; ++iCnt)
    {
      Delay(100000);
    }

    
  } 
  return 0;
}







반응형

'Busan IT > ARM Controller' 카테고리의 다른 글

PWM(Pulse Width Modulation)  (0) 2015.09.14
PWM(Pulse Width Modulation Controller)  (0) 2015.09.11
초음파 센서  (0) 2015.09.09
ARM 타이머/카운터 소스, 초음파 센서 거리측정식  (0) 2015.09.09
Timer/Counter  (0) 2015.09.07
Posted by newind2000