2018-01-14 12:04 AM
Hi All,
I am new to STM8S and not yet that good at microcontroller programming in general. I am trying to learn about timers/counters in microcontrollers.
I wrote following code to toggle an LED connected at PB5 pin in each second.
#include 'stm8s.h'
int main() {
// Default clock is HSI/8 = 2MHz
PB_DDR |= (1 << PB5); // PB5 is now output
PB_CR1 |= (1 << PB5); // PB5 is now pushpull
TIM2_PSCR = 0b00000111; // Prescaler = 128
TIM2_CR1 |= (1 << TIM2_CR1_CEN); // Enable TIM2
while (1) {
if ( ( ((uint16_t)TIM2_CNTRH << 8) + (uint16_t)TIM2_CNTRL ) >= 15625 ) {
// Reset counter back to 0
TIM2_CNTRH = 0;
TIM2_CNTRL = 0;
// Toggle LED.
PB_ODR ^= (1 << PB5);
}
}
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?
My microcontroller is not connected with any external clock and using internal clock to operate.
After I reading datasheet, I see MCU clock will be HSI/8 = 2MHz by default. I set 128 as prescaler for TIM2. So, TIM2 counter will increment in each 64us. So, when it reach at 15625 it will be 1 second (64 * 15625 = 1000000us = 1s).
So, I assumed the LED to toggle in each second.
The problem is the LED stays ON all time.
Could somebody help me to identify the problem with my code?
Thanks in advance. #counter #timer #stm8s #stm8s103f3Solved! Go to Solution.
2018-01-15 01:33 AM
After reading reference manual, I found that we need to set UG bit of TIM2_EGR register to tell MCU to take prescaler value set.
TIM2_PSCR = 0b00000111; // Prescaler = 128
// Generate an update event so prescaler value will be taken into account.
TIM2_EGR |= (1 << TIM2_EGR_UG);
TIM2_CR1 |= (1 << TIM2_CR1_CEN); // Enable TIM2�?�?�?�?
2018-01-15 01:33 AM
After reading reference manual, I found that we need to set UG bit of TIM2_EGR register to tell MCU to take prescaler value set.
TIM2_PSCR = 0b00000111; // Prescaler = 128
// Generate an update event so prescaler value will be taken into account.
TIM2_EGR |= (1 << TIM2_EGR_UG);
TIM2_CR1 |= (1 << TIM2_CR1_CEN); // Enable TIM2�?�?�?�?
2020-07-15 10:26 PM
Hai Junaid PV,
I was following your Timer operation and configured the same for TIM1.And able to get the 1sec work.Now I want set timer for 32sec or more.Can you help me on how to set the prescalar and time period value please.
Regrads
Srikanth.
2020-07-16 12:07 AM
I think you can set 4096 as prescaler value.
Default clock is 2MHz.
So,
(1/2000000) * 4096 * 15625 = 32
Please note, Timer 1 has 16 bit prescaler capability and we need to set two registers TIM1_PSCRL and TIM1_PSCRH.
Regards,
Junaid
2020-07-16 02:27 AM
Hi Junaid,
Thanks for your valuable input.I am able to do the TIM1 for 32sec. But same operation I was trying to do on TIM2 it was not working.For TIM2 anything I need to take care.
Regards
Srikanth.
2020-07-16 05:58 AM
the code gets you going but can be further improved: 1) it is not very modular and hard to reuse the code; 2) it doesn't ensure atomicity in reading the timer counter.
rewriting the counter isn't a good way to ensure long-term accuracy. instead I use something like this:
//return 1 if sufficient ticks have passed
//return 0 otherwise
uint8_t tim2_cnt(uint16_t cnt) {
static uint16_t _cnt=0; //temp tick counter
if (tim2_get() - _cnt > cnt) {_cnt+=cnt; return 1;}
return 0;
}
so in your case, something like this would work:
if (tim2_cnt(TICK_DLY) flip_led(); //flip the led if sufficient tim2 ticks have passed.
tim2_get() returns a read of the tim2 counter, often via a double read to ensure atomicity.
2020-07-16 08:36 AM
Hi Srikanth,
Setting prescaler for TIM2 is different from TIM1. For TIM2 we are setting a number that will be used as power of 2 to get prescaler value. It is well explained in STM8S Reference Manual.
So, to get prescaler value 4096, we need to set 12 (0b00001100) as TIM2_PSCR register value. 2^(12) = 4096.
Please refer STM8S reference manual, it has all details you need.
Regards,
Junaid