cancel
Showing results for 
Search instead for 
Did you mean: 

STM8S103 Timer TIM2 timing

sthvw
Associate III

Hi,

Using ST Workbench debugger my 16-bit timer TIM2 (china bought) overflows each 16 seconds as the prescaler is set to 10. With an 16MHz internal clock divided by 2^10 (1024) the timer should overflow theoretically each 4.1 seconds. Prescaler 9 takes 8 seconds an prescaler 8 takes 4 seconds. So it is consistent but not according documentation. Where do I go wrong? Or is the internal clock 4MHz???

1 ACCEPTED SOLUTION

Accepted Solutions
sthvw
Associate III

Hi,
(well I think I am the expert...;-))
I finally succeeded detecting DCF77 signals of 100ms (0-bit), 200ms (1-bit), 1s (start of bit) and 2s (final second 59). From the first active going edge the counter is started and on the next edge the counter value is read and counter is restarted. I started applying the longest signal of 2s by a function generator to the stm8s103. The counter value should be within the 16-bit counter range 65535. So I started with prescaler value 15 and decremented it until the measured counter value is at the highest possible count less than 65535. Decrementing the prescaler value the counter value doubles exactly, so no problem with the prescaler or counter itself. Prescaler 9 timer 2 counts:
56463 at 2 seconds.
28230 at 1 second
5646 at 200ms
2823 at 100ms
So very very nice.
I used these values with a plus/minus offset to detect correct DCF77 signals and it works perfectly.
So lets be simple. With CKDIVR set to zero then 1 second takes 28230 counter ticks. Therefore the timer 2 input frequency must be 28.230Hz. Multiplied by prescaler 2^9 is 512 makes 14453760 or 14.4 system clock frequency not even within 1% of 16MHz as documented and far out from the HSI calibration posibilities.
Thanks for listening.

View solution in original post

9 REPLIES 9
Peter BENSCH
ST Employee

Unfortunately, you have not shown the relevant program parts of the initialisation of the clock tree. The timers are clocked by fMASTER (see RM0016, section 9), which in turn can be derived from fHSIDIV. fHSIDIV in turn is the 16MHz clock HSI divided by 1/2/4/8. You have probably set HSIDIV to 1/4?

Regards
/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi Peter,

nice to talk to an expert.

I did a long conversation with ChatGPT... (sometimes talks noncense but sometimes generates good hints...)

My example program using my own macro's
CLK->CKDIVR = 0 ;
while ( 1 ) {
DEF_SET_PD3_HI;
DEF_SET_PD3_LO;
DEF_SET_PD3_HI;
DEF_SET_PD3_LO;
DEF_SET_PD3_HI;
DEF_SET_PD3_LO;
}//while

My oscilloscope shows a toggle time of 125ns, assuming one instruction per clock cycle the system clock is 8MHz, not 16MHz.

Setting the timer2 prescaler to 10 it should divide the system clock by 2^10 = 1024. Setting breakpoint at timer2 overflow interrupt handler about 16 seconds after startup an overflow is detected. With 8MHz system clock divided by 1024 makes 7812,5Hz say around 8KHz with a 64K counter it should take about 8 seconds to overflow. But in reality it is 16 seconds. So I assume my (chinese clone) chip is running at 8KHz and the timer prescaler factor calculation should be minus 1.

curious about your response

 

Peter BENSCH
ST Employee

Well… and your macros contain what code?

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
sthvw
Associate III


First of all I do no see something like [Accept as Solution] but anyway:

#define DEF_MSK_PIN_3 0x08

#define DEF_SET_PD3_LO GPIOD->ODR &= (uint8_t)~DEF_MSK_PIN_3
#define DEF_SET_PD3_HI GPIOD->ODR |= DEF_MSK_PIN_3

To me it s a bare pin toggle...

And you believe that

  • GPIOD->ODR &= (uint8_t)~DEF_MSK_PIN_3
  • GPIOD->ODR |= DEF_MSK_PIN_3

are each processed in one clock cycle?
Please have a look at the generated ASM statements when the compiler is set to optimise for codesize.

Regards
/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

I managed to call an assembly function from C.

mov 0x5000, 0xff ; Store back to ODR
mov 0x5000, 0x00 ; Store back to ODR
mov 0x5000, 0xff ; Store back to ODR
mov 0x5000, 0x00 ; Store back to ODR

and execute it consequtive about 20 times before returning to a C loop.

This toggles all pins of port A. If I look with oscilloscope I see a pin toggle each 125ns.

According chatgpt each instructions takes 4 clock cycles. But do to pipelining it probably takes only 2 clock cycles. If I assume 2 clock cycles are used then one clock cycle takes 62,5ns which corresponds to a 16MHz system clock.

 

sthvw
Associate III

But still TIM2 does not work as expected.
CKDIVR = 0
TIM2 Reload value = 0xffff.
Pin PD3 is togged at TIM2 overflow.
Selecting a TIM2 pre-scaler factor of 3 (2^3=8) it means that the overflow should occur each 32.767ms but checking it by oscilloscope it overflows each 112ms. Also setting the pre-scaler to maximum of 2^15 it should overflow each 134 seconds but it overflows each 444 seconds! I tried another STM8S103, same results.
Who can help me out???

 

sthvw
Associate III

Hi,

Maybe I overlook something, otherwise this timer sucks. I configured the TIM2 timer channel 2 to be output by hardware directly on port-pin PD3. Disabling all kinds of interrupts. Experimenting with the duty cycle (compare) value with PSCR set to 0. My oscilloscope measures a cycle time of 13.8ms (should be 4.1ms) divided by 65.536 steps is on average 211ns per clock tick, corresponding with a timer clock frequency of 4.8MHz. If calculating the time per timer clock tick with several compare (duty cycle) values it starts at about 622ns per step (compare value = 10) then decreases until 75.6ns per step around compare value decimal 1000 and then slowly increase to 209us per step at compare value 0xFE00. It looks like some interference is taking place… If I set the HSIDIV to 0x03 (0x18) then the overflow time is 112ms (a factor 8 slower, that is consequent). If the Compare value is set to 0x8000 it is expected that the duty cycle will be 50% of the cycle time but on my oscilloscope it shows that it is active only 17% of the cycle time…..(very strange....) I consulted the stm8s Errata Sheet (October 2019 ES0102 Rev 7) but nothing is reported about this timer behavior. I will use this timer to detect DCF77 timing signals but first manually will find out what offset/calibration values to use.
Maybe there is some expert in the field???
Thanks for listening anyway.

sthvw
Associate III

Hi,
(well I think I am the expert...;-))
I finally succeeded detecting DCF77 signals of 100ms (0-bit), 200ms (1-bit), 1s (start of bit) and 2s (final second 59). From the first active going edge the counter is started and on the next edge the counter value is read and counter is restarted. I started applying the longest signal of 2s by a function generator to the stm8s103. The counter value should be within the 16-bit counter range 65535. So I started with prescaler value 15 and decremented it until the measured counter value is at the highest possible count less than 65535. Decrementing the prescaler value the counter value doubles exactly, so no problem with the prescaler or counter itself. Prescaler 9 timer 2 counts:
56463 at 2 seconds.
28230 at 1 second
5646 at 200ms
2823 at 100ms
So very very nice.
I used these values with a plus/minus offset to detect correct DCF77 signals and it works perfectly.
So lets be simple. With CKDIVR set to zero then 1 second takes 28230 counter ticks. Therefore the timer 2 input frequency must be 28.230Hz. Multiplied by prescaler 2^9 is 512 makes 14453760 or 14.4 system clock frequency not even within 1% of 16MHz as documented and far out from the HSI calibration posibilities.
Thanks for listening.