1
\$\begingroup\$

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 in each second which is connected at PB5 pin.

#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 to 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 the time.

Could somebody help me to identify the problem with my code?

Thanks in advance.

\$\endgroup\$
  • \$\begingroup\$ Can you debug this and monitor the LED Pin? If it doesn't work in the debugger then at least you have eliminated that the problem is not from your hardware. \$\endgroup\$ – Rrz0 Jan 14 '18 at 21:37
  • \$\begingroup\$ Unfortunately I am yet to learn about debugging :) However, LED blinks fine if I run program using simple for loop to create the delay. \$\endgroup\$ – Junaid Jan 14 '18 at 21:42
2
\$\begingroup\$

After reading Reference Manual more I found we need to set UG bit TIM2_EGR to generate and update event so MCU will take the prescaler value for TIMER 4.

TIM2_EGR |= (1 << TIM2_EGR_UG);

So, updated code will be:

#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_EGR |= (1 << TIM2_EGR_UG); // Generate an update event so prescaler value will be taken into account.
  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);
    }
  }
}

Now the LED started to toggle in each second!!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.