본문 바로가기

stm32 레지스터 직접 접근 (6. Timer/Counter [Registers Part 03])

반응형

 

 

관련글


stm32 레지스터 직접 접근 (6. Timer/Counter [코드 Part 01]) (tistory.com)

stm32 레지스터 직접 접근 (6. Timer/Counter [함수 설명 Part 02]) (tistory.com)


더보기

 


서론


 

stm32에는 아두이노와 다르게 Timer/Counter의 레지스터들이 많습니다. 더 많은 기능을 제공하기 위해서죠. Timer의 동작 주기, Interrupt, Timer/Counter의 세부적인 모드들 (Encoder, PWM, Compare, Capture etc) 이렇게 많은 기능을 제공하기 때문에 stm32를 다루기는 어렵지만, 더 많은 서비스를 제공할 수 있죠. 

이번 시간에는 전 포스트 코드에서 각각의 함수에서 사용된 레지스터들을 살펴보고, 사용된 비트들의 기능을 알아보겠습니다.


initRCC

  RCC_APB1ENR

initTIM2

  TIM2_PSC

  TIM2_ARR

  TIM2_CNT

  TIM2_SR

enableTIM2

  TIM2_DIER

  TIM2_EGR

  TIM2_CR1

TIM2_IRQHandler

  TIM2_SR


참고 자료


 

STM32F103ZET6 Reference Manual

Section 7.3.8 [APB1 peripheral clock enable register] (115 ~ 117 page)

Section 15.4.11 [TIMx prescaler] (418 ~ 419 page)

Section 15.4.12 [TIMx auto-reload register] (419 page)

Section 15.4.10 [TIMx counter] (418 page)

Section 15.4.5 [TIMx status register] (410 ~ 411 page)

Section 15.4.4 [TIMx DMA/Interrupt enable register] (409 ~ 410 page)

Section 15.4.6 [TIMx event generation register] (412 page)

Section 15.4.1 [TIMx control register 1] (404 ~ 405 page)

 

STM32F10xxx/20xxx/21xxx/L1xxxx Cortex®-M3 programming manual

 

 

initRCC


RCC_APB1ENR

Address: 0x1C

Absolut address: 0x40021000

그림 01 (115 page)

TIM2EN: TIM2에 클럭을 공급하기 위한 비트입니다.

 

initTIM2


TIM2_PSC

Address: 0x24

Absolute address: 0x40000000 + 0x24

그림 02 (419 page)

PSC: TIM2 카운터의 주기를 분할합니다.

PSC로 지정된 클럭을 분주하여 낮은 주파수를 생성할 때 사용됩니다.

36 MHz를 36,000으로 분주하면 1 kHz가 나오기에 TIM2의 카운터가 1초에 1,000 만큼 증가합니다.

 

TIM2_ARR

Address: 0x2C

Absolute address: 0x40000000 + 0x2C

그림 03 (419 page)

ARR: 카운터가 0으로 되었을 경우 자동으로 ARR 값으로 바뀝니다.

PSC와 ARR 둘 모두 TIM2의 주기를 결정합니다.

예를 들어 PSC가 36,000로 설정 되어 카운터의 주기가 36,000,000 / 36,000 = 1 kHz로 되고 ARR이 500이라면

1 kHz / 500 = 2 Hz로 TIM2의 최종 주기가 결정됩니다.

 

TIM2_CNT

Address: 0x24

Absolute address: 0x40000000 + 0x24

그림 04 (418 page)

CNT: TIM2 카운터의 값이 저장되어 있습니다.

CNT는 PSC에 설정된 주기에 맞게 1씩 감소하다 0을 만나면 Interrupt를 발생시킵니다.

0으로 된 후, 자동으로 ARR에 설정된 값으로 변경이 되어 다시 1씩 감소합니다.

 

TIM2_SR

Address: 0x10

Absolute address: 0x40000000 + 0x10

그림 05 (410 ~ 411 page)

SR은 상태에 관련된 레지스터입니다. TIM2를 초기화하는 과정이기 때문에, 기존에 저장되어 있을지도 모르는 값을 지우기 위해 TIM2 -> SR = 0;을 쓴 것입니다.

좀더 자세히 말하자면 우리가 초기화하려는 대상은 UIF입니다. Update Interrupt Flag로 밑에서 설명할 Update interrupt가 발생되면 UIF가 자동으로 1이 됩니다. 

 

 

 

enableTIM2


TIM2_DIER

Address: 0x0C

Absolute address: 0x40000000 + 0x0C

그림 06 (409 ~ 410 page)

UIE: 업데이트 인터럽트를 활성화합니다.

여러 인터럽트가 있지만, 일정 주기마다 Interrupt를 발생시키기 위해서는 Update interrupt가 적절하기 때문에 이를 사용했습니다.

CNT가 0이 되고 ARR로 Update될 때 발생됩니다.

 

 

TIM2_EGR

Address: 0x14

Absolute address: 0x40000000 + 0x14

그림 07 (412 page)

UG: TIM2 관련 모든 설정 레지스터가 업데이트 되었다는 것을 알려줍니다.

1을 쓸 시, 카운터를 초기화하고, 레지스터들을 업데이트합니다. 

enableTIM2 함수가 실행되었다면, 모든 설정이 끝난 것으로 간주하기 때문에 TIM2 설정 마지막 부분에 해당 코드를 넣습니다.

 

 

TIM2_CR1

Address: 0x00

Absolute address: 0x40000000 + 0x00

그림 08 (404 ~ 405 page)

CEN: TIM2의 카운터를 활성화합니다.

 

 

TIM2_IRQHandler


TIM2_SR

Address: 0x10

Absolute address: 0x40000000 + 0x10

그림 08 (410 ~ 411 page)

우리는 앞서 DIER에서 Update interrupt를 활성화했기 때문에 CNT값이 0 -> ARR로 Update될 때 Interrupt가 발생됩니다. 이때 SR의 UIF 비트가 1로 변한다고 했습니다.

Handler는 UIF의 비트가 1이면 발생됩니다. 발생된 후에도 UIF가 1이면 계속해서 Handler가 발생되기 때문에 정상적으로 동작하지 않습니다. 따라서 Handler가 발생되면 UIF 비트를 0으로 초기화해 주셔야합니다.

 

 

반응형