There is piece of code in stm32 library that's behaving strangely. This is assignment made from initializing structure to timer auto-reload register:
/* Set the Autoreload value */
TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ;
I've TIM_Period = 1999999
, however after assignment TIMx->ARR = 33919
. Smaller number usually points to overflow, so I checked: (1999999-33919) / 65536 = 30
. This would mean the number overflowed 30 times on 16 bit data type, but both variables are 32 bit unsigned integers. Extracted from structure declarations:
For TIMx:
__IO uint32_t ARR; /*!< TIM auto-reload register, Address offset: 0x2C */
For TIM_TimeBaseInitStruct:
uint32_t TIM_Period; /*!< Specifies the period value to be loaded into the active
Auto-Reload Register at the next update event.
This parameter must be a number between 0x0000 and 0xFFFF. */
Where __IO
is defined as volatile
.
This is disassembly of that assignment:
296 TIMx->ARR = TIM_TimeBaseInitStruct->TIM_Period ;
0800c37c: ldr r3, [r7, #0]
0800c37e: ldr r2, [r3, #4]
0800c380: ldr r3, [r7, #4]
0800c382: str r2, [r3, #44] ; 0x2c
What is happening here.. could it be something external causing the value to overflow? Note that I'm debugging on real hardware through ST-Link with no code optimization.
I'm going to guess that your chip has 16-bit timer registers. That is, it might still be a 32-bit register, but only have 16 useful bits in it.
Something like:
31 16 15 0
+--------------------+------------------+
| RESERVED | Auto-reload value|
+--------------------+------------------+
Fact checking forthcoming (if you have a specific part number that would help me out).
Edit: By looking at some documentation [PDF link], my guess seems to be confirmed:
Edit 2: Since you mentioned which chip you were using, I found that documentation too [PDF link], which contains this handy diagram:
As you can see, some timers have 32-bit autoreload, and some don't. Which timer you've chosen will affect the behaviour you see.