Atmaga16A 클럭

Atmega16A의 경우 16MHz 크리스탈 사용하는데 1초당 16000000번 진동하며 16000000번의 클럭파형 생성합니다.

1클럭 당 1개의 명령어를 수행할 수 있습니다.

 

내부 레지스터 중에 TCNT0라는 레지스터가 있고, 클럭이 1번 발생할 때마다 TCNT0이 1씩 증가하며 카운트합니다.

이때, 레지스터 설정에 따라 다르게 오버플로우 인터럽트와 비교매치 인터럽트를 발생시킵니다.

인터럽트 발생 종류에 따라 Case.1과 Case2의 경우로 나누겠습니다.

 

인터럽트 발생

Case.1 오버플로우 인터럽트

Default로 설정되어 있을 경우 TCNT0 값이 256이 되는 순간 오버플로우 인터럽트 발생합니다.

256번째에 오버플로우 인터럽트가 1번 발생. TCNT0 레지스터를 통해 1초당 62500번의 인터럽트를 발생.

=> 16000000 / 256 = 62500번의 인터럽트 발생

1클럭당 TCNT0 값이 1씩 증가하고 256번 이후 오버플로우 인터럽트가 합니다.

 

Case.2 비교매치 인터럽트

Default가 아닌 OCR0 설정 시 TCNT0의 값과 OCR0 레지스터 설정 값이 같아지는 순간 비교매치 인터럽트가 발생합니다.

ex) OCR0의 설정 값이 250일 경우

TCNT0와 OCR0 비교 250번째에 비교매치 인터럽트가 1번 발생. TCNT0 레지스터를 통해서는 1초당 64000번의 인터럽트를 발생.

=> 16000000 / 250 = 64000번의 인터럽트 발생

 

1클럭당 TCNT0 값이 1씩 증가하고 OCR0 레지스터 설정값과 같아지는 순간 비교매치 인터럽트가 발생합니다.

 

Prescaler 설정

아직까진 Case 1, Case 2번의 설정만으로는 인터럽트가 너무 많이 발생하여 1초에 1000번을 발생시키려고 하는 것과는 거리가 있습니다.

인터럽트 발생 횟수를 줄이기 위해 Prescaler, 즉 분주기를 이용해야 합니다.

 

분주기는 타이머에 공급하는 입력 클럭의 속도를 조절하는 역할을 합니다. 예를들어 64MHz 클럭을 64의 분주율로 설정하면 1MHz의 클럭과 동일하게 동작하는 것을 볼 수 있습니다. Atmega의 분주율은 TCCR0 레지스터 하위 3개의 비트를 이용하여 설정합니다.

 

위에서 발생한 62500번의 인터럽트는 Defalut에서 발생하는 횟수로 Prescaler가 1로 설정된 경우입니다.

Default 기준 Prescaler 미설정시 1클럭당 TCNT0이 1씩 증가하므로 256번째 클럭에 Interrupt가 발생하는데, Prescale을 10으로 설정시 10클럭당 TCNT0 값이 1씩 증가, 100으로 설정시 100클럭당 TCNT0 값이 1씩 증가하여 인터럽트 발생 횟수를 조절합니다.

 

지금까지 설명한 개념을 바탕으로 1초에 1000번 인터럽트가 발생하도록 만들어 보겠습니다.

TCNT0 레지스터의 초기값을 0으로 설정하였고, 분주율을 64로 설정하여 64클락당 TCNT0 값이 1씩 증가합니다.

TCNT0 값이 1씩 증가하여 OCR0의 설정값인 249를 넘어가는 순간 오버플로우 인터럽트가 1번 발생합니다.

 

기존 1초에 16000000번 발생하던 클락을 TCNT0, OCR0 레지스터 값을 비교하여 16000000/250번의 인터럽트를 발생시키고,

분주기를 통해 64번의 클락을 조절하여 16000000/250/64번 결국 1초동안 1000번의 인터럽트가 발생합니다.

'ATmega' 카테고리의 다른 글

Linux 환경 AVRDUDE 사용법  (0) 2020.07.31
Complier Optimization  (0) 2020.02.05
CodeVisionAVR 환경 Atmega에 Hex 파일 다운로드  (0) 2020.01.30
AVR용 컴파일러 비교 및 설치  (0) 2020.01.20