본문 바로가기
코스웨어/14년 스마트컨트롤러

20140716 수요일 업무일지 김화린 [출석번호10번]

by 알 수 없는 사용자 2014. 7. 16.
728x90
반응형

20140716 수요일 ARM

초음파

초음파를 우선 VCC  GND에 연결

초음파를 세 개의 기술을 다 쓸 수 있어야 쓸 수 있는 것이기 때문에 초음파 하는 것은 기숙이 아님



ARM 프로그래밍과 C 프로그래밍이 전제로 깔려야 한다. ARM 프로그래밍이 가능하다는 것은 회로도를 볼 줄 알아야 한다는 것!!  PIO, TC, INT 이 세 가지를 사용하여야 초음파를 쓸 수 있음

0 ~4 번까지는 HIGH  Drive

초음파를 사용하려면 External INT 를 사용해야한다

 

TC 의 소스와 IRQ의 소스를 통째로 복사를 해서 붙여 넣은 다음에 TC0   TC1 로 바꿔준다 그러면 기존의 타이머도 동작하고 얘도 동작하고

IRQ_Init  Echo_Init으로 바꿔줌

1.       IRQ(echo) 를 상승엣지로 되어있지만은 인터럽트 자체를 켜지않는 것이 좋다(인터럽트 활성화X)

2.      PIOA 활성화

3.      타이머 -> 비활성화 되어있어야함 타이머는 초기화 되어있지만 활성화 X 활성화코드를 test 함수로 옮김




지금은 Cm 개념으로 갈 거임




#include "uSonic.h"

#include "TC.h"

#include "IRQ.h"

volatile static unsigned int uiMs;

 

 

void ULTRA_Init(void)

{

   TRG_Init();      // 트리거

   ECHO_Init();  

   Timer1_Init();

    //Init 은 크게 신경써서 최적화 할 필요는 없다(속도면에서가독성을 올리자

}

 

//=============================================//

//=================== TC1 ====================== //

//=============================================//

 

void Timer1_Init(void)

{

   //..1) 전원공급

   *AT91C_PMC_PCER = PID_TC1;

   

   //..2 비활성화

   *AT91C_TC1_CCR = AT91C_TC_CLKDIS;

    

   //..3 인터럽트 비활성화

   *AT91C_AIC_IDCR = PID_TC1;

   *AT91C_TC1_IDR = AT91C_TC_COVFS | AT91C_TC_LOVRS  |AT91C_TC_CPCS  |

AT91C_TC_CPAS

   | AT91C_TC_CPBS | AT91C_TC_LDRAS | AT91C_TC_LDRBS | AT91C_TC_ETRGS;

 

   //..4 레지스터 클린

   *AT91C_TC1_SR;                //레지스터에 접속해서 한번 읽어들이기만

하면 됨

 

   //..5 세팅         // 분주비 8 RC = 353 이면  //1cm 를 다녀왔을때

   *AT91C_TC1_CMR = (AT91C_TC_CLKS_TIMER_DIV2_CLOCK << 0) | AT91C_TC_CPCTRG;

    *AT91C_TC1_RC = 353;

 

    //핸들러 함수 호출

   AT91C_AIC_SVR[AT91C_ID_TC1] = (volatile unsigned int)ULTRA_Handler;

   AT91C_AIC_SMR[AT91C_ID_TC1] = AT91C_AIC_SRCTYPE_HIGH_LEVEL|

AT91C_AIC_PRIOR_LOWEST;

 

   //..6 인터럽트 클리어

   *AT91C_AIC_ICCR = PID_TC1;

 

   // .. 7 TC 인터럽트 활성화 (RC)

    *AT91C_TC1_IER =  AT91C_TC_CPCS;

   *AT91C_AIC_IECR = PID_TC1;

}

 

void ULTRA_Handler(void)      

{

   ++uiMs;

   *AT91C_TC1_SR;

}

 

//=============================================//

//=================== IRQ ====================== //

//=============================================//

 

void ECHO_Init(void)            

{

   //PIOA 에 전원공급

   *AT91C_PMC_PCER = PID_PIOA;     

     

    //Pin_ECHO(PA14] 출력 비활성화

   *AT91C_PIOA_ODR = PIN_ECHO;

   

    //Pin_ECHO(PA14] 핀 활성화

    *AT91C_PIOA_PER = PIN_ECHO;

   

    //Pin_ECHO(PA14] 인터럽트 비활성화

    *AT91C_PIOA_IDR = PIN_ECHO;

 

     // 풀업 저항  끄기

    *AT91C_PIOA_PPUDR= PIN_ECHO;

        

    AT91C_AIC_SVR[AT91C_ID_PIOA] = (volatile unsigned int )ECHO_Handler;

    // PIO 의 인터럽트 발생 시 해당 벡터에 담겨 있는 함수의 주소가 실행된다

    //즉 아트메가와 다르게 우리가 함수를 만들어놓고 그 주소를 넣어주는 식,

    //아트메가는 기존에 벡터라는 이름의 함수가 존재

 

   // Source Mode Register - 모드 어느 엣지에 신호를 보낼 것인가 ?

   *AT91C_AIC_SMR = AT91C_AIC_SRCTYPE_HIGH_LEVEL|AT91C_AIC_PRIOR_LOWEST;

    //  2를 다섯번 미는 개념 2진수 1 0  5번 미는거임      인터럽트의

우선순위를 최고 낮게 함

 

     //다른 명령이 있을지도 모르니까 해당 pid 의 인터럽트를 모드 clear 해준다

   *AT91C_AIC_ICCR = PID_PIOA;

 

      //Set Command Register

     *AT91C_AIC_ISCR = PID_PIOA;

}

 

 

void ECHO_Handler(void)

{

  

   static volatile unsigned int uiState;

 

   uiState = *AT91C_PIOA_ISR;

 

   if( PIN_ECHO == (uiState & PIN_ECHO) )

   {

      //   T/C 리셋시작

      *AT91C_TC1_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;

   }

  

    //중간에 처리하는 동안 인터럽트가 삽입되면 문제가 되니까 내용을 클리어

하기 위해서

   uiState = *AT91C_PIOA_ISR;

     //호출된 인터럽트를 다 처리했다는 문법적인 처리

   *AT91C_AIC_EOICR = 0;

}

 

void TRG_Init(void)

{

   *AT91C_PMC_PCER = PID_PIOA;  

   *AT91C_PIOA_PER = PIN_TRG;

   *AT91C_PIOA_OER = PIN_TRG;

}

 

void ULTRA_Trigger(void)

{  

   volatile unsigned int iCount;

  

   *AT91C_PIOA_CODR = PIN_TRG;

   DELAY(1000);

   *AT91C_PIOA_SODR = PIN_TRG;

   DELAY(1000);

   *AT91C_PIOA_CODR = PIN_TRG;       //L- > H- > L

 

   //Trigger 를 쏴주고 버스트가 생기는 동안 인터럽트 감시를 위해 활성화

  

   //PIOA  PA14 (echo pin) 활성화

    *AT91C_PIOA_IER = PIN_ECHO;

    //PIOA인터럽트 활성화

   *AT91C_AIC_IECR = PID_PIOA;      

}

 

 

void ULTRA_ACT(void)

{  

   ULTRA_Init();

   ULTRA_Trigger();

}


 

C언어 포인터 특강


보통 주소는 컴파일러가 관리하지만 heap영역의 주소는 OS가 관리한다.

* %p - 8자리의 주소를 출력하는 주소연산자.

심벌테이블에는 변수이름과 자료형 , 그리고 이 변수가 할당받은 메모리의 주소가 기록된다.

변수 x 앞에 붙은 &(ampersand) 는 주소연산자이다.


변수이름 빼고 다 용도가 된다.포인터의 용량이 8바이트여야지 제일 끝에 주소를 담을 수 있다는 것

어드레스가 어디까지 허용하드냐에 따라서 포인터 변수의 바이트가 결정된다 그래서 sizeof 로 알아봐야하는 것 !!

주소앞에 별이 붙으면 값을 의미한다.


*0x12FF7C = 8 ; 이거는 될까 안될까??

안됨 오른쪽 형동등성 발생

왼쪽의 정체는 잘못된 연산 2항연산이 되어야 하는데 1항연산이 됨

*을 우리는 포인터로 보는데 컴파일은 곱셈으로 봄

7 = *3; 을 컴파일 못해주는 것처럼

A = * 3; 이것도 안됨 *을 곱셈으로 보니깐 



그래서 별과 주소 사이에 캐스팅이 필요한 것이다 . !!

숫자는 type 이라는 것이 존재하지 않으니깐

그럼 *(int *) 숫자 즉 *(int *) 0x12FF7C 이렇게 !! 


그럼 단항연산자 포인터로 된다그래서 주소로 인식 되고 주소를 따라가게 되는 것이다그리고 8이 들어가게 되는 것 !!



728x90