cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 Time base Interrupt

waheed901
Associate II
Posted on February 16, 2017 at 11:39

Hi,

I need Help regarding time base.

I found one of the example and tried to modify that for STM32 F4 Discovery board.

I want to count number of external pulses by using TIM4 in 1.13 ms. So the time base is configured to generate interrupt after each 1.13 ms (as the read_me file states). the code is generating interrupt but it is not after 1.13 ms. can any body help me in this matter. I have attached the files for your review. 

Thanks in Advance  

#clive #clive1 #stm32-stm32f4
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on February 20, 2017 at 14:25

 ,

 ,

25 / 8 = 3.125?

♯ define PLL_M 25 // You are not clocking at 25 MHz, shouldn't this be 8 ?

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..

View solution in original post

14 REPLIES 14
waheed901
Associate II
Posted on February 17, 2017 at 02:53

waheed901
Associate II
Posted on February 17, 2017 at 02:55

The Readme file states

This example shows how to configure the TIM peripheral in Output Compare Timing

mode with the corresponding Interrupt requests for each channel in order to generate

4 different time bases.

The TIM3CLK frequency is set to SystemCoreClock / 2 (Hz), to get TIM3 counter

clock at 6 MHz so the Prescaler is computed as following:

- Prescaler = (TIM3CLK / TIM3 counter clock) - 1

SystemCoreClock is set to 168MHz for STM32F4xx Devices.

The TIM3 CC1 register value is equal to 40961,

CC1 update rate = TIM3 counter clock / CCR1_Val = 146.48 Hz,

so the TIM3 Channel 1 generates an interrupt each 6.8ms

The TIM3 CC2 register is equal to 27309,

CC2 update rate = TIM3 counter clock / CCR2_Val = 219.7 Hz

so the TIM3 Channel 2 generates an interrupt each 4.55ms

The TIM3 CC3 register is equal to 13654,

CC3 update rate = TIM3 counter clock / CCR3_Val = 439.4Hz

so the TIM3 Channel 3 generates an interrupt each 2.27ms

The TIM3 CC4 register is equal to 6826,

CC4 update rate = TIM3 counter clock / CCR4_Val = 878.9 Hz

so the TIM3 Channel 4 generates an interrupt each 1.13ms.

When the counter value reaches the Output compare registers values, the Output

Compare interrupts are generated and, in the handler routine, 4 pins(PG.06, PG.08,

PI.09 and PC.07) are toggled with the following frequencies:
Posted on February 17, 2017 at 06:05

Pretty sure the TIM CLK is 2* the APB1 clock, and the math here is broken (logic copied from ST example)

capture_T_4 =TIM4->CNT;

if (capture_T_4 >= capture_T_4_old)

{

Intr_Enc_Count = (capture_T_4 - capture_T_4_old);

}

else /* (uwIC2Value2 <= uwIC2Value1) */

{

Intr_Enc_Count = ((0xFFFF - capture_T_4_old) + capture_T_4);

}

A simple current - last computation will suffice.

Confused how a TIM in maximal mode counting at 6 MHz arrives at 1.13 ms, I don't see you advancing the phase of Channel 4

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
waheed901
Associate II
Posted on February 17, 2017 at 07:12

Thanks for your reply.

as per the readme text file of the example

CC4 update rate = TIM3 counter clock / CCR4_Val = 878.9 Hz

so the TIM3 Channel 4 generates an interrupt each 1.13ms.

When the counter value reaches the Output compare registers values, the Output

Compare interrupts are generated and, in the handler routine, 

I am not sure about the logic is correct or not, but I am getting the 

Clock_Freq = RCC_Clocks.PCLK1_Frequency; // Timer Clock 26.88 MHz

System_Freq = RCC_Clocks.HCLK_Frequency; // System Clock 53.76 MHz

but the interrupts are not generated after 1.13 ms.

As far as count at TIM4 ...thanks for the suggestion...I will check that once the interrupt thing is correct. 

Posted on February 17, 2017 at 17:03

The problem is the README file doesn't matter if you've butchered up the code it describes. You have modified the code and left it in a mess, and you are trying to apply several concepts that you don't seem to fully understand.

If you want one interrupt at 1.13 ms period, you either need to configure the Period of the TIM to be that, and use the Update Interrupt, or you need to use a channel, and keep advancing the phase by 1.13 ms each time you get a CCx interrupt. Best I can see you are not doing that, as code was commented out.

A TIM clocking at 52.76 MHz, prescaled to 6.595 Mhz, with a 65536-1 period, will interrupt at 100.6 Hz, 9.9ms, based on quick guesses at what's going on.

If the reported clocks are wrong, then you need to examine the PLL and HSE/HSI clock settings and defines in the context of the board you are using.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on February 17, 2017 at 17:06

A timer at 6 MHz, Period = 6780-1, should yield an Update Rate of 884.96Hz or 1.13ms

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
waheed901
Associate II
Posted on February 20, 2017 at 03:14

Thanks for your replies and you are right I dont have much of the background of micro-controller programming, that's why I need to modify existing examples. 

I have been trying to learn and figure out the problem. 

I tried to do the same thing with system tick example: but it is again not giving me output at every 1ms:

I am sorry for bothering you people again, but I am still a naive in this field of programming and playing with ARM -Controllers.

int main(void)

{

if (SysTick_Config(SystemCoreClock / 1000))  // Setup SysTick Timer for 1 msec interrupts.

{

/* Capture error */

while (1);

}

while (1)

}

void SysTick_Handler(void)

{

Time=Time_old+1; // Number of interrupts 

// sending data to USART

sprintf(X, '%6.6f %6.6f %6.6f %6.6f %6.6f %6.6f %6.6f \r\n',Time, Time_old, Time_old, Time_old, Time_old, Time_old, Time_old);

s = X;

//out[indx]=*s;

//while(*s)

{

sprintf(X, '%6.6f %6.6f f \r\n',Time, Time_old);

s = X;

while(*s)

{

while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);

USART_SendData(USART2, *s++);

}

Time_old=Time;

}
waheed901
Associate II
Posted on February 20, 2017 at 04:08

Thanks for the reply:

The board I am using is     STM32F4-Discovery

The rate I am getting for the system tick example is around 3.1 ms

I have not define any value for HSE_VALUE, 

I did not change any setting for PLL in system_stm32f4xx.c and used the same as the example has. 

>> 

sprintf() of floating point data to a USART in an interrupt is probably not ideal. 115200 baud is about 11520 character in a second, you're calling 1000 times a second, gives you about 11.5 chars before saturation. Timing 1MS? Use a GPIO pin, review with a scope.

Thanks for the suggestion, I will try to work it out  later. 
Posted on February 20, 2017 at 03:53

>>I tried to do the same thing with system tick example: but it is again not giving me output at every 1ms:

So *WHAT* rate do you observe? These situations are really hard to diagnose without more complete information.

What board are you using? The STM32F4-Discovery? Something else, please specify.

The HSE would be 8 MHz, you'd need to make sure the PLL settings in system_stm32f4xx.c are correct, and the define HSE_VALUE is 8000000 and not 25000000

sprintf() of floating point data to a USART in an interrupt is probably not ideal. 115200 baud is about 11520 character in a second, you're calling 1000 times a second, gives you about 11.5 chars before saturation. Timing 1MS? Use a GPIO pin, review with a scope.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..