관련글
stm32 레지스터 직접 접근 (6. Timer/Counter [코드 Part 01]) (tistory.com)
stm32 레지스터 직접 접근 (6. Timer/Counter [함수 설명 Part 02]) (tistory.com)
잡동사니 세상 :: stm32 레지스터 직접 접근 (소개) (tistory.com)
잡동사니 세상 :: stm32 레지스터 직접 접근 (0. Microcontroller와 ARM ) (tistory.com)
잡동사니 세상 :: stm32 레지스터 직접 접근 (1. STM32F10x란) (tistory.com)
잡동사니 세상 :: stm32 레지스터 직접 접근 (2. 프로그램 설치 및 설정) (tistory.com)
잡동사니 세상 :: stm32 레지스터 직접 접근 (3. RCC) (tistory.com)
잡동사니 세상 :: stm32 레지스터 직접 접근 (4. GPIO [Input]) (tistory.com)
잡동사니 세상 :: stm32 레지스터 직접 접근 (5. Exception / Interrupt [설명 & 코드 Part 01]) (tistory.com)
잡동사니 세상 :: stm32 레지스터 직접 접근 (5. Exception / Interrupt [인터럽트 설정 Part 02]) (tistory.com)
stm32 레지스터 직접 접근 (5. Exception / Interrupt [중요 레지스터들 Part 03]) (tistory.com)
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
TIM2EN: TIM2에 클럭을 공급하기 위한 비트입니다.
initTIM2
TIM2_PSC
Address: 0x24
Absolute address: 0x40000000 + 0x24
PSC: TIM2 카운터의 주기를 분할합니다.
PSC로 지정된 클럭을 분주하여 낮은 주파수를 생성할 때 사용됩니다.
36 MHz를 36,000으로 분주하면 1 kHz가 나오기에 TIM2의 카운터가 1초에 1,000 만큼 증가합니다.
TIM2_ARR
Address: 0x2C
Absolute address: 0x40000000 + 0x2C
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
CNT: TIM2 카운터의 값이 저장되어 있습니다.
CNT는 PSC에 설정된 주기에 맞게 1씩 감소하다 0을 만나면 Interrupt를 발생시킵니다.
0으로 된 후, 자동으로 ARR에 설정된 값으로 변경이 되어 다시 1씩 감소합니다.
TIM2_SR
Address: 0x10
Absolute address: 0x40000000 + 0x10
SR은 상태에 관련된 레지스터입니다. TIM2를 초기화하는 과정이기 때문에, 기존에 저장되어 있을지도 모르는 값을 지우기 위해 TIM2 -> SR = 0;을 쓴 것입니다.
좀더 자세히 말하자면 우리가 초기화하려는 대상은 UIF입니다. Update Interrupt Flag로 밑에서 설명할 Update interrupt가 발생되면 UIF가 자동으로 1이 됩니다.
enableTIM2
TIM2_DIER
Address: 0x0C
Absolute address: 0x40000000 + 0x0C
UIE: 업데이트 인터럽트를 활성화합니다.
여러 인터럽트가 있지만, 일정 주기마다 Interrupt를 발생시키기 위해서는 Update interrupt가 적절하기 때문에 이를 사용했습니다.
CNT가 0이 되고 ARR로 Update될 때 발생됩니다.
TIM2_EGR
Address: 0x14
Absolute address: 0x40000000 + 0x14
UG: TIM2 관련 모든 설정 레지스터가 업데이트 되었다는 것을 알려줍니다.
1을 쓸 시, 카운터를 초기화하고, 레지스터들을 업데이트합니다.
enableTIM2 함수가 실행되었다면, 모든 설정이 끝난 것으로 간주하기 때문에 TIM2 설정 마지막 부분에 해당 코드를 넣습니다.
TIM2_CR1
Address: 0x00
Absolute address: 0x40000000 + 0x00
CEN: TIM2의 카운터를 활성화합니다.
TIM2_IRQHandler
TIM2_SR
Address: 0x10
Absolute address: 0x40000000 + 0x10
우리는 앞서 DIER에서 Update interrupt를 활성화했기 때문에 CNT값이 0 -> ARR로 Update될 때 Interrupt가 발생됩니다. 이때 SR의 UIF 비트가 1로 변한다고 했습니다.
Handler는 UIF의 비트가 1이면 발생됩니다. 발생된 후에도 UIF가 1이면 계속해서 Handler가 발생되기 때문에 정상적으로 동작하지 않습니다. 따라서 Handler가 발생되면 UIF 비트를 0으로 초기화해 주셔야합니다.
'stm32 > 강좌' 카테고리의 다른 글
stm32 레지스터 직접 접근 (6. Timer/Counter [함수 설명 Part 02]) (0) | 2021.03.10 |
---|---|
stm32 레지스터 직접 접근 (6. Timer/Counter [코드 Part 01]) (0) | 2021.03.06 |
stm32 레지스터 직접 접근 (5. Exception / Interrupt [중요 레지스터들 Part 03]) (1) | 2021.03.04 |
stm32 레지스터 직접 접근 (5. Exception / Interrupt [인터럽트 설정 Part 02]) (0) | 2021.03.01 |
stm32 레지스터 직접 접근 (5. Exception / Interrupt [설명 & 코드 Part 01]) (0) | 2021.02.27 |