Summary of Timers in ST F0 Series |
To understand TIM3 features and SFR control, refer to ReferenceManual at Chapter 14: General Purpose Timer (TIM3). Frankly speaking, I have quite a hard time in understanding the description, and also having difficulties in finding the register I need. I hope this is not a sign for I am too old for this job, :-)
Reference Manual on TIM3 |
Before we dive into controlling the timer, we need some understanding on timers. Some reference is here.
Generally to use a timer, we will need to perform the following actions:
- Enable timer 3
- Timer interrupt duration calculation
- Enable timer interrupt
- Run timer
- Implement timer ISR
1. Enable Timer 3
This is done by enabling Timer3 block by supplying clock.Enable Timer 3 Block RCC_APB1ENR: TIM3_EN |
2. Timer Interrupt Duration Calculation
2.1 Timer Prescaler
A timer is just a counter that keep running up/down (count up or count down) until overflow and interrupted is generated due to the overflow. The counter is increment in a fix duration. A 48MHz system, each clock cycle can increment the counter, making the duration for counter 0->1 happen in 1/48MHz (208.3 nano-seconds)STM32F030 is running at 48MHz, typically we want a timer to have duration of 1milliseconds. In order to 'scale down' the frequency, we will need the prescaler. Each MCU will have its own prescaler formula as describe in user manual.
Timer Prescaler TIM3_PSC = 47999 |
As shown in above, CK_CNT is the frequency that we need, PSC is the prescaler value that we should set in order to obtain the frequence we want.
However, in this tutorial I will created a 1 seconds timer, a more appropiate frequency would be 1KHz. Thus, the prescale value = 48MHz/1KHz - 1 = 47999.Said we need 1 micro-seconds interval, that would equal to 1MHz, thus the prescale value = 48MHz/1MHz - 1 = 47
As the prescale is only 16 bit, the slowest frequency we can have will be 732.4Hz.
2.2 Timer Auto Reload Value
After setting the prescaler 47999, we now have a counter(timer) that increment every 1milliseconds. We want to have a timer that interrupt at 1 second interval, thus we want the counter to count up to 1000 (1000*1milliseconds = 1 second) and generated an interrupt.The SFR so use in determining the maximum count is Timer Auto Reload Value.
Timer Auto Reload TIM3_ARR = 1000 |
By adjusting prescaler and auto-reload register, we can control timer interrupt period to a smaller/larger duration.
3. Enable timer interrupt
We need to enable the following SFR for interrupt generation upon timer overflowEnable Timer 3 Overflow Generated Interrupt TIM3_DIER : UIE |
Interrupt Block : Enable Timer 3 Interrupt NVIC_ISER : 16 (16 is ISR for Timer 3) as shown below |
Vector Table Showing Timer 3 At Position 16 |
4. Run timer
Start timer with the followingEnable Timer Run TIM_CR1 : CEN |
5. Implement Timer ISR
Timer ISR is pretty simple, we just need to clear the interrupt flag, so that ISR is not called until next interrupt happen.Then is our user code, here we just set a flag upon interrupt. In the main loop there will be code that trigger LED-LD3 base on this flag. Do notice the flag is declare as below:
volatile unsigned char LEDOnOff;
As a rule of thumb, variable use in the interrupt should always declare with 'volatile' keyword.
As usual, I have push the tutorial code into github.
No comments:
Post a Comment