2015-02-05 12:30 PM
Hello, I found some unexpected behaviour with the 32-bit TIM2 module on STM32F4xx devices, and many others.
When accessing the TIM2->ARR (a 32-bit timer) register, 16-bit writes have the following behaviour. If you try writing 0x0987 to TIM2->ARR, it will actually write 0x098709 The high and low half-words have been written with this value. I found this behaviour using a DMA transfer, but the problem is much more basic and can be reproduced easily single-stepping through some code.#include ''stm32f4xx.h'' int main(void) {
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* 32-bit writes to TIM2->ARR work fine */
uint32_t *pARR_32 = (uint32_t *)&TIM2->ARR;
*pARR_32 = 0x00000123;
/* 16-bit writes to TIM2->ARR DO NOT WORK AS EXPECTED*/
uint16_t *pARR_16 = (uint16_t *)&TIM2->ARR;
*pARR_16 = 0x0987;
if( TIM2->ARR == 0x09870987 )
{
while(1); // FAILED: High and low half-words are repeated
}
while(1); // Does not make it here
} As JW posted below (thanks!), this behaviour is both expected and documented. Hope this helps someone else who may not have realized it. #stm32-tim22015-02-05 12:36 PM
No, this is an expected and documented behaviour.
RM0383rev.1 2.1.7: When a 16- or an 8-bit access is performed on an APB register, the access is transformed into a 32-bit access: the bridge duplicates the 16- or 8-bit data to feed the 32-bit vector. RM0383rev.1 13.4 TIM2 to TIM5 registers: The 32-bit peripheral registers have to be written by words (32 bits). JW2015-02-05 01:21 PM
JW, thanks for the quick response and RM0383 references. I am updating my original post to help others who run into this behaviour without expecting it.