성엽이
KKIMSSI
성엽이
전체 방문자
오늘
어제
  • 분류 전체보기 (454)
    • :) (2)
    • C프로그래밍이론 (9)
    • C++프로그래밍 (64)
      • STL (1)
    • C# (2)
    • Visual studio 10.0 (9)
    • AT91SAM7S256 (21)
    • 논리회로 (14)
    • AVR2560 (11)
    • TCPIP (16)
    • NetWork (4)
      • Ubuntu Linux (2)
    • Assembly (21)
    • UNIX 프로그래밍 (6)
    • RFID 분석 (1)
    • Win32 API (7)
    • Cortex-M3 (4)
    • Unity (91)
    • Flutter (9)
    • OwnProject (11)
      • It's mine (5)
      • 마인드스톰 실습 (1)
      • 보고서 자료 (2)
      • RPi B+ (2)
    • ETC (25)
      • 상식 (3)
    • MFC (40)
    • PostgeSQL (18)
    • 영상제어 (6)
      • VFW_영상처리 (1)
    • Python (0)
    • Java (30)
      • SpringBoot (2)
      • Javascript (1)
      • JSP (13)
      • Spring (8)
    • Oracle (4)
      • SQL (3)
    • HTML (6)
      • Thymeleaf (1)
      • CSS (1)
      • Bootstrap (3)
    • IDE (1)
      • VS Code (1)
    • Android (2)
    • Privacy Policy (0)
    • MYSQL (2)
      • MariaDB (2)
    • AWS (5)
    • 개인공부 (0)

블로그 메뉴

  • 홈
  • 태그
  • 미디어로그
  • 위치로그
  • 방명록
  • 관리자
  • 글쓰기

공지사항

인기 글

태그

  • WINAPI
  • 문자열 나누기
  • ARM Reverse Engineering
  • Boot Code 분석
  • MFC

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
성엽이
AT91SAM7S256

2013.05.24_초음파센서_

2013.05.24_초음파센서_
AT91SAM7S256

2013.05.24_초음파센서_

2013. 5. 24. 09:17


▶ 초음파센서를 통한 거리측정

소리는 1초 -> 340m 갑니다.

계산을 해보면 1cm는 ->  0.00002941176470588240 sec

분주비 8 로 오차가 가장적었음. 48/8 = 6Mhz 을 사용.

1cm -> 29.411764us 한번간거리.

          58.823528us 갔다온거리.

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

MCK_클락배수나눔.xlsx

ARM_AT91SAM7S (2).zip

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


 #include "ULTRA_AIC.h"


static volatile unsigned int ui_Tic;  // 58us 1cm.
static volatile unsigned int ui_dist;  // 
static volatile unsigned int ui_state;  // 현재 초음파 거리를 측정중인지 아닌지.
                                            // 측정중이면 1, 측정중이 아니면 0
unsigned char *ULTRA_RUN()
{
  static unsigned char uc_dist[] = "---cm";
    
  TRG_PULSE_Toggle();
  
  ui_Tic = 0;    // 미리 0cm 로 초기화.
  ui_dist = 0;    // 계속동작중인 ui_Tic 에다가 값을 넣어서. 실제거리를 제려고. 
    
  

  while( 0 == ((AT91C_BASE_PIOA->PIO_PDSR) & ( 1<<Echo_PIN )) );    // 상승엣지의 상태를 발견함.
                // LOW level 0 , HIGH level 1
// 타이머 클럭 활성화(TC_CCR, CLKEN)
  AT91C_BASE_TC0->TC_CCR  = AT91C_TC_CLKEN;    // 클럭이 켜짐. Timer/Count 를 켜줌.
// 1. 끝 : 타이머 클럭 비활성화 ------------------

// 타이머 시작(TC_CCR, SWTRG)
  AT91C_BASE_TC0->TC_CCR  = AT91C_TC_SWTRG;  

// 인터럽트를 켜줌.
  AT91C_BASE_PIOA->PIO_IER = 1<<Echo_PIN;      // PIO의 15번 핀을 켜줌. 셋팅을 끝내고 열어줌!
  AT91C_BASE_AIC->AIC_IECR = 1<<AT91C_ID_PIOA;    // 장치번호를 켜줘야함!

  ui_state = 1;      // 측정중 숫자넣어놓기.

  while( 1 == ui_state );    // 전역변수에 0 이 드러가면 나옴.

  U_Timer_Init();    // 타이머 꺼줌.
  ECHO_INIT();      // Echo 꺼줌.

  uc_dist[0]= '0' + ((ui_dist%1000)/100);    // ui_dist의 실제거리를 넣어둠.
  uc_dist[1]= '0' + ((ui_dist%100)/10);
  uc_dist[2]= '0' + ((ui_dist%10));
  
  return uc_dist;
}

void ULTRA_INIT()
{
  ECHO_INIT();
  TRG_init();
  U_Timer_Init();

}
void ECHO_INIT()
{
  AT91C_BASE_PMC->PMC_PCER = 1<<AT91C_ID_PIOA;    // P203, PMC_PCER 를 통해서 PIOA 활성화.
  AT91C_BASE_PIOA->PIO_ODR = 1<<Echo_PIN;  // P252, PIO_ODR 를 통해서 15번 핀 출력 비활성화.
  AT91C_BASE_PIOA->PIO_PER = 1<<Echo_PIN;    // P250, PIO_PER 를 통해서 핀자체를 활성화.
  AT91C_BASE_PIOA->PIO_IDR = 1<<Echo_PIN;    // P250, PIO_IDR 를 통해서 15번 핀의 Interrupt 를 비활성화. 
  AT91C_BASE_AIC->AIC_IDCR = 1<<AT91C_ID_PIOA;  // P175, AIC_IDCR 를 통해 AIC 비활성화. 

// 타이머 카운터 0 인터럽트 핸들러 등록(AIC_SVR[TC0], AIC_Handler)
  AT91C_BASE_AIC->AIC_SVR[AT91C_ID_PIOA] = (volatile unsigned int )ULTRA_Handler;
  

// 타이머 카운터 0 인터럽트 모드 설정(AIC_SMR[TC0], AIC_SRCTYPE_INT_HIGH_LEVEL, PRIOR_LOWEST)
  AT91C_BASE_AIC->AIC_SMR[AT91C_ID_PIOA] = ((AT91C_AIC_PRIOR_LOWEST) | (AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE));  
                                                                                                                // Source type 은 외부인터럽트-Negative 로 맞춰줌.

  AT91C_BASE_AIC->AIC_ICCR = 1<<AT91C_ID_PIOA;   // P181, PIOA 장치에 값을 초기화. 엣지 디텍터
  AT91C_BASE_PIOA->PIO_IFER= 1<<Echo_PIN;    // P253, Glitch Input Filter Enable Register
                                          // PIN에 스위치를 통한 처음과 끝부분의 잡음 제거.
  AT91C_BASE_AIC->AIC_ISCR = 1<<AT91C_ID_PIOA;      // Glitch Input Filter 를 설정하고 다시 켜줌. 엣지 디텍터.
  //AT91C_BASE_PIOA->PIO_IER = 1<<Echo_PIN;    // PIO의 15번 핀을 켜줌. 셋팅을 끝내고 열어줌!
  //AT91C_BASE_AIC->AIC_IECR = 1<<AT91C_ID_PIOA;      // 장치번호를 켜줘야함!
    
  return;
}

void ULTRA_Handler()
{  // Timer/count 와는 다르게 인터럽트는 32개가 다 반응하므로 PIO로 외부인터럽트신호를 확인해줘야한다.
  AT91C_BASE_PIOA->PIO_ISR;  // 미리 만들어 둔다.

  ui_dist = ui_Tic;    // 하강인터럽트 걸리는 순간까지도 ui_Tic 은 계속 돌고있다.
            // 그래서 ui_dist 에다가 인터럽트 걸리는 순간에 실제거리를 저장해놓는다.  
  ui_state = 0;      // 0 으로 만들어둔다. 다음 타이머를 받기위해.

  AT91C_BASE_AIC->AIC_EOICR = 0;
  return;
}

void U_Timer_Init()
{
// 타이머 카운터 0 사용을 위한 PMC 활성화
     AT91C_BASE_PMC->PMC_PCER = 1<<AT91C_ID_TC0;
// 1.시작 : 타이머 클럭 비활성화 ------------------
// 타이머 클럭 비활성화(TC_CCR 설정)
  AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;    // 클럭이 꺼짐

// 2. 시작 : 타이머 인터럽트 비활성화 -------------
// 타이머 인터럽트 비활성화(TC_IDR 설정)
// 인터럽트 상태 정보 초기화(TC_SR 읽기)
  AT91C_BASE_TC0->TC_IDR = (AT91C_TC_COVFS) | (AT91C_TC_LOVRS) | (AT91C_TC_CPAS) | (AT91C_TC_CPBS) 
      | (AT91C_TC_CPCS) | (AT91C_TC_LDRAS) | (AT91C_TC_LDRBS) | (AT91C_TC_ETRGS);
  AT91C_BASE_TC0->TC_SR;  

// 분주비 128, 비교 방식 레지스터 설정(TC_CMR, DIV5_CLOCK, CPCTRG)
// MCKR divided by 8 => 58us(TC_RC 설정:353)
  AT91C_BASE_TC0->TC_CMR = (AT91C_TC_CLKS_TIMER_DIV2_CLOCK) | (AT91C_TC_CPCTRG);
  AT91C_BASE_TC0->TC_RC = 353;

// 타이머 카운터 0 인터럽트 비활성화(AIC_IDCR, TC0)
  AT91C_BASE_AIC->AIC_IDCR = 1<<AT91C_ID_TC0;


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


// 타이머 카운터 0 인터럽트 핸들러 등록(AIC_SVR[TC0], Timer_Handler)
  AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0] = (volatile unsigned int )U_Timer_Handler;  


// 타이머 카운터 0 인터럽트 모드 설정(AIC_SMR[TC0], AIC_SRCTYPE_INT_HIGH_LEVEL, PRIOR_LOWEST)
  AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] = ((AT91C_AIC_PRIOR_LOWEST) | (AT91C_AIC_SRCTYPE_POSITIVE_EDGE));

// 타이머 카운터 0 인터럽트 클리어(AIC_ICCR, TC0)
  AT91C_BASE_AIC->AIC_ICCR = 1<<AT91C_ID_TC0;


// TC_RC 값 비교 타이머 인터럽트 활성화(TC_IER, CPCS)
  AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS;
// 2. 끝 : 타이머 인터럽트 비활성화 ---------------


// 타이머 카운터 0 인터럽트 활성화(AIC_IECR, TC0)
  AT91C_BASE_AIC->AIC_IECR = 1<<AT91C_ID_TC0;


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

/*// 타이머 클럭 활성화(TC_CCR, CLKEN)
  AT91C_BASE_TC0->TC_CCR  = AT91C_TC_CLKEN;    // 클럭이 켜짐.
// 1. 끝 : 타이머 클럭 비활성화 ------------------

// 타이머 시작(TC_CCR, SWTRG)
  AT91C_BASE_TC0->TC_CCR  = AT91C_TC_SWTRG;*/

}

void U_Timer_Handler()
{
  AT91C_BASE_TC0->TC_SR;    // TC0_SR 에 가서 CPCS비트에 1이 들어가있는 상태면 인터럽트가 비활성화됨.
          // 그래서 1이 들어가있으면 안됨. TC0_SR 에 접근(읽으면) 0 으로 만듬
  ++ui_Tic;      // 여기선 데이터 단위 cm 이라고 보면됨.
  return;
}

void TRG_init()
{
  AT91C_BASE_PIOA->PIO_OER = 1<<TRG_PIN;
  AT91C_BASE_PIOA->PIO_PER = 1<<TRG_PIN;
  AT91C_BASE_PIOA->PIO_CODR = 1<<TRG_PIN;
  //AT91C_BASE_PIOA->PIO_PPUDR=1<<TRG_PIN;  //트러거핀 풀업저항을 오픈시켜 사용금지
  return;
}

void TRG_PULSE_Toggle()
{
  volatile unsigned int ui_Cnt;

  AT91C_BASE_PIOA->PIO_SODR = 1<<TRG_PIN;
  for(ui_Cnt=0;ui_Cnt < 100;++ui_Cnt);  // 48 cycle 이상 지연. 0.00001s 4000 cycle 이상 지연.
  AT91C_BASE_PIOA->PIO_CODR = 1<<TRG_PIN;

  return;
}





저작자표시

'AT91SAM7S256' 카테고리의 다른 글

2013.05.27_ARM_사용자정의한글띄우기_  (0) 2013.05.27
2013.05.24_while문 반복중에도 DBGU_인터럽트걸기!  (0) 2013.05.24
2013.05.15_Timer/Count_인터럽트(수정중)  (0) 2013.05.15
2013.05.09_DBGU(응용)_Recv_Char  (0) 2013.05.09
2013.05.08_DBGU_문자보내기!  (0) 2013.05.08
    'AT91SAM7S256' 카테고리의 다른 글
    • 2013.05.27_ARM_사용자정의한글띄우기_
    • 2013.05.24_while문 반복중에도 DBGU_인터럽트걸기!
    • 2013.05.15_Timer/Count_인터럽트(수정중)
    • 2013.05.09_DBGU(응용)_Recv_Char
    성엽이
    성엽이

    티스토리툴바

    개인정보

    • 티스토리 홈
    • 포럼
    • 로그인

    단축키

    내 블로그

    내 블로그 - 관리자 홈 전환
    Q
    Q
    새 글 쓰기
    W
    W

    블로그 게시글

    글 수정 (권한 있는 경우)
    E
    E
    댓글 영역으로 이동
    C
    C

    모든 영역

    이 페이지의 URL 복사
    S
    S
    맨 위로 이동
    T
    T
    티스토리 홈 이동
    H
    H
    단축키 안내
    Shift + /
    ⇧ + /

    * 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.