Busan IT/ARM Controller2015. 9. 7. 17:40

==================================Outline====================================
Timer/Counter

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

 

flash는 모델에 따라 크기가 달라지며 AT91SAM7256의 경우는 256kb 사용할 수 있다.

 

Internal Memory는 3가지 영역으로 나뉜다 :: flashSRAM 그리고 remap을 기준으로 flash()SRAM()


remap이 수행되면 cstartup.s 코드(주파수 변환)가 동작한다.

 

AT91SAM7256에서 Timer/Counter는 총 3(TC0 ~ TC2)가 있으며 카운터는 모두 16bit이다. , 0에서 65535까지 셀 수 있는 카운터이다.

 

현재 우리가 사용하는 ARM의 주파수는 48Mhz이므로 분주비와 카운터를 사용하며 원하는 단위 카운터의 시간을 만들 수 있다.



 

의사코드(psudo code)를 보고 Timer/Counter를 사용해보자.

 

//정의된 헤더파일이 없더라도 메모리맵을 보고 코딩을 할 수 있는 소양을 길러야 한다.



 // Timer.c

// 0번 타이머 접두어: TC0 // 1번 타이머 접두어: TC1 // 2번 타이머 접두어: TC2
// 예: #define TC0_CCR    ((volatile unsigned int *)0xFFFA0000)
// 인터럽터 관련 : AT91C_BASE_AIC
// 0번 타이머 관련 : AT91C_BASE_TC0
// PMC 관련   : AT91C_BASE_PMC

static unsigned int uiMsec;   //카운팅을 위한 전역 변수, 외부 접근을 막기 위해 static 선언

void Timer_Init(void)
 {
//p/33 장치번호표, p/20 memory map, T/C 주요 레지스터 p/463

// 타이머 카운터 0 사용을 위한 PMC 활성화(AT91C_ID_TC0)
   *AT91C_PMC_PCER = AT91C_ID_TC0;
// 1.시작 : 타이머 클럭 비활성화 ------------------
// 타이머 클럭 비활성화(TC_CCR 설정)
   *AT91C_TC0_CCR = AT91C_TC_CLKDIS;
   
   

// 2. 시작 : 타이머 인터럽트 비활성화 -------------

// 타이머 인터럽트 비활성화(TC_IDR 설정)
   *AT91C_TC0_IDR = 0xFF;   //타이머 인터럽트 모두 비활성화
   
// 인터럽트 상태 정보 초기화(TC_SR 읽기)
   *AT91C_TC0_SR;  //읽으면 자동으로 지워 지기 때문에 읽기만 하면 초기화 된다.  

// 분주비 128, 비교 방식 레지스터 설정(TC_CMR, DIV4_CLOCK, AT91C_TC_CPCTRG)
   *AT91C_TC0_CMR = 1<<AT91C_TC_CLKS_TIMER_DIV4_CLOCK | AT91C_TC_CPCTRG;

// MCKR divided by 128 => 2.7us(TC_RC 설정)
   

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

// 3. 시작 : 타이머 카운터 0 인터럽트 비활성화 ------
// 타이머 카운터 0 인터럽트 핸들러 등록(AIC_SVR[AT91C_ID_TC0], timer_handler)
   AT91C_AIC_SVR[AT91C_ID_TC0] = (volatile unsigned int)Timer_ISR;
   
// 타이머 카운터 0 인터럽트 모드 설정(AIC_SMR[AT91C_ID_TC0], AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, AT91C_AIC_PRIOR_LOWEST)
   AT91C_AIC_SMR[AT91C_ID_TC0] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | AT91C_AIC_PRIOR_LOWEST;

// 타이머 카운터 0 인터럽트 클리어(AIC_ICCR, AT91C_ID_TC0)
   *AT91C_AIC_ICCR = 1<<AT91C_ID_TC0;    인터럽트 초기화

// TC_RC 값 비교 타이머 인터럽트 활성화(TC_IER, AT91C_TC_CPCS)
   *AT91C_TC0_IER = AT91C_TC_CPCS;
   *AT91C_TC0_RC = 375;

// 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;

 }


void Timer_ISR(void)  //0.001초마다 호출
{
// 인터럽트 상태 정보 초기화(TC_SR 읽기)
   *AT91C_TC0_SR;

   ++uiMsec;

   
 }

void ms_Delay(unsigned int uiMs)
 {
   uiMsec = 0;
   while(uiMsec < uiMs);  
 }   
  


반응형
Posted by newind2000