2018-02-20 01:27 AM
I'm trying to use TIM2 on the STM32F0-Discovery board (I am new to the STM32, but have used the STM8 before).
I setup TIM2 and USART1, then in a loop I send the value of TIM2_CNT via the USART1, so I can see how TIM2 counts. Since the USART1 stuff is working at the intended 9600 baud, I am confident that the basic clock setup is there and the STM32F0 is running at 8 Mhz.
However, I see TIM2_CNT count at about 50 Mhz, no matter the value of TIM2_PSC.
Here is my initialization code:
&sharpinclude <stdint.h>
&sharpdefine TIM2_BASE 0x40000000
&sharpdefine TIM2_CR1 (*(volatile uint16_t *)(TIM2_BASE + 0x00))&sharpdefine TIM2_CNT (*(volatile uint32_t *)(TIM2_BASE + 0x24))&sharpdefine TIM2_PSC (*(volatile uint16_t *)(TIM2_BASE + 0x28))&sharpdefine RCC_BASE 0x40021000&sharpdefine RCC_APB2ENR (*(volatile uint32_t *)(RCC_BASE + 0x18))&sharpdefine RCC_APB1ENR (*(volatile uint32_t *)(RCC_BASE + 0x1c))&sharpdefine GPIOA_BASE 0x48000000&sharpdefine GPIOA_MODER (*(volatile uint32_t *)(GPIOA_BASE + 0x00))&sharpdefine GPIOA_AFRH (*(volatile uint32_t *)(GPIOA_BASE + 0x24))&sharpdefine USART1_BASE 0x40013800&sharpdefine USART1_CR1 (*(volatile uint32_t *)(USART1_BASE + 0x00))&sharpdefine USART1_BRR (*(volatile uint32_t *)(USART1_BASE + 0x0c))&sharpdefine USART1_ISR (*(volatile uint32_t *)(USART1_BASE + 0x1c))&sharpdefine USART1_TDR (*(volatile uint32_t *)(USART1_BASE + 0x28))void init(void)
{ RCC_AHBENR |= (1ul << 17); // Enable I/O A RCC_APB2ENR |= (1ul << 14); // Enable USART1 RCC_APB1ENR |= (1ul << 0); // Enable Timer 2// Use PA9, PA10 for USART instead of GPIO.
GPIOA_MODER |= (0x2ul << 18) | (0x2ul << 20); GPIOA_AFRH |= (0x1ul << 4) | (0x1ul << 8);// 9600 baud, 1 start bit, 8 data bits, 1 stop bit.
USART1_BRR = 8000000 / 9600; USART1_CR1 = 0xd;// Set timer to 1000 ticks per second?
TIM2_PSC = 8000; TIM2_CR1 = (1ul << 0);}Philipp
#stm32f0 #tim2 #timerSolved! Go to Solution.
2018-02-20 01:56 AM
Philipp,
The prescaler is - in ST's parlance - preloaded, which means, that the value from PSC won't get used until Update event (i.e. 'overflow') occurs. As TIM2 is a 32-bit register and the reset value of ARR is 0xFFFFFFFF, even at 48MHz it takes cca 90 seconds until this happens. You can force an update by setting TIMx_EGR.UG (but that then sets the TIMx_SR.UIF which in turn fires an interrupt if enabled, this often confuses newbies as the 'libraries' do exactly this).
Please get a debugger, GDB+OpenOCD will do with the STLink onboard the Discos. Observe TIM2 behaviour from there (yes the debugger is intrusive, due to HW-triggers-upon-read registers e.g. the CCxIF bits in TIMx_SR, but for this simple purpose it's fine).
JW
PS What in the licence of device headers ([Cube or SPL]\Drivers\CMSIS\Device\ST\[STM32xxxxx]\Include\) makes you feel them being not free? Not using them (symbols and constants from there) just adds another layer of uncertainty.
2018-02-20 01:56 AM
Philipp,
The prescaler is - in ST's parlance - preloaded, which means, that the value from PSC won't get used until Update event (i.e. 'overflow') occurs. As TIM2 is a 32-bit register and the reset value of ARR is 0xFFFFFFFF, even at 48MHz it takes cca 90 seconds until this happens. You can force an update by setting TIMx_EGR.UG (but that then sets the TIMx_SR.UIF which in turn fires an interrupt if enabled, this often confuses newbies as the 'libraries' do exactly this).
Please get a debugger, GDB+OpenOCD will do with the STLink onboard the Discos. Observe TIM2 behaviour from there (yes the debugger is intrusive, due to HW-triggers-upon-read registers e.g. the CCxIF bits in TIMx_SR, but for this simple purpose it's fine).
JW
PS What in the licence of device headers ([Cube or SPL]\Drivers\CMSIS\Device\ST\[STM32xxxxx]\Include\) makes you feel them being not free? Not using them (symbols and constants from there) just adds another layer of uncertainty.