2013-01-23 06:46 PM
Hi, I have just saw a program about a interrupt time. The program can let the LED on and off in a specified period. But I have some question about the prescaler value, can anyone help me to understand the prescale value of this case, thanks a lot. My problem is that, I don't know why the period value is 10000-1 for 1 ms delay, is there any equation for this case and why the prescaler value is 336-1 for 1MHz. Also, why the period and prescaler value is alway -1?
Thanks.The program is as follow:/** ****************************************************************************** * @file USART/main.c * @author Andrew Markham * @version V1.0.0 * @date 27-April-2012 * @brief Main program body ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/&sharpinclude ''stm32f4xx.h''&sharpinclude <stdio.h>/* Private typedef -----------------------------------------------------------*/GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;/* Private define ------------------------------------------------------------*//* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*//* Private function prototypes -----------------------------------------------*/void INTTIM_Config(void);void LED_Config(void);/* Private functions ---------------------------------------------------------*/void TIM2_IRQHandler(void){ if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { TIM_ClearITPendingBit(TIM2, TIM_IT_Update); GPIO_ToggleBits(GPIOD, GPIO_Pin_14); GPIO_ToggleBits(GPIOD, GPIO_Pin_13); GPIO_ToggleBits(GPIOD, GPIO_Pin_12); }}/** * @brief Main program * @param None * @retval None */int main(void){ INTTIM_Config(); /* LED Configuration */ LED_Config(); while (1) { }}/** * @brief Setup an interval timer * @param None * @retval None */void INTTIM_Config(void){ NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; /* Enable the TIM2 gloabal Interrupt */ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; /* value = 0 - 15*/ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; /* value = 0 - 15*/ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* TIM2 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 10000 - 1; // 1 MHz down to 1 KHz (1 ms) TIM_TimeBaseStructure.TIM_Prescaler = 336 - 1; // 24 MHz Clock down to 1 MHz (adjust per your clock) TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* TIM IT enable */ TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); /* TIM2 enable counter */ TIM_Cmd(TIM2, ENABLE);}void LED_Config(void){ /* GPIOD Periph clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); /* Configure PD12, PD13, PD14 and PD15 in output pushpull mode */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOD, &GPIO_InitStructure);}&sharpifdef USE_FULL_ASSERT/** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */void assert_failed(uint8_t* file, uint32_t line){ /* User can add his own implementation to report the file name and line number, ex: printf(''Wrong parameters value: file %s on line %d\r\n'', file, line) */ while (1) {}}&sharpendif/** * @} */ /** * @} */ /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ #calculate-presc #stm32f2 #set-time-base #bxcan #filter2013-01-23 07:55 PM
The comments don't jive with the values, hence you are rightly confused
Going from 1 MHz to 1 KHz you'd expect a 1000 -1 value For a counter to have N states, it starts at 0 and counts up to N-1, the counter recognizes the N-1 state and the next state will be 0. The register is thus programed with N-1 rather than N. TIM Update Frequency = TIM Clock / (P * Q) Where Prescaler = P - 1, and Period = Q - 1 The base TIM Clock with depend on the AHB divider for the bus to which it's attached. TIM2 on on APB1, the typical prescaler for that is 4, where the input for the timer is 2. See the Clock Tree diagram for this relationship. Thus the TIM Clock will nominally be 84 MHz (168 MHz / 2) Therefore to get the time base ticking at 1 MHz, the prescaler needs to be 84 - 1, a period of 1000 - 1 will get the update down to 1 KHz. Your example would generate 25 Hz in my estimation, a division of 3360000, whose factors include 336 and 100002013-01-23 08:15 PM
Thanks, I have a further question. The question is that I have use the Oscilloscope to view the wave of this case. Before using the Oscilloscope to view, I have changed the program.
GPIO_ToggleBits(GPIOD, GPIO_Pin_15) --> GPIO_TogglesBits(GPIOD, GPIO_Pin_6)GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15; --> GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;Then, I connected Pin6 to Oscilloscope. But there is no any waveform. It shows ahorizontal line is below the x-axis, after a moment, the
horizontal line return over the x-axis. This event is happened continuously.
2013-01-24 11:31 PM
To start, forget about the timers for a while. Write a simple loop toggling the pin, and observe it using the oscilloscope. Only after you confirm that working, proceed with the timer (and come back with the result).
JW2013-01-25 01:57 AM
Thanks for your help. I can use the Oscilloscope to view a square wave from a pin.
2013-09-02 03:09 AM
i want to run the timer at 25MHz so the prescaler value = 2.36 is it possible to get the prescaler values in floating points?????if nt what is the fuether step?
2013-09-02 05:36 AM
You can't use fractional dividers, the STM32 permits only integers.
You could generate 25 MHz in a couple of ways. Run the processor at 150 MHz or some other 25 MHz multiple and have timers at 150 or 75 MHz via APB2/APB1. With a 25 MHz HSE crystal, you could feed that via MCO1 (PA8), which is typical for Ethernet/PHY implementations. You might also be able to use PLLI2S and feed that via MCO2 For an F2 the processor would need to run at 100 MHz to get 25 MHz out via a timer.2014-09-29 02:59 PM
Clive, please forgive my ignorance, but, where P - 1 is the Prescalar, this value should be an interger, so one could view this arrangement as 1000 - 1 = 999. Is this correct or is this actually supposed to be a range of defined values from 1000 to 1?
Thanks! Chris2014-09-29 05:35 PM
The comparators want to check for an N-1 value for N discreet values, 0 .. N-1.
When it sees the CURRENT value is N-1, the NEXT value is ZERO (Update Event) To divide by 1000 a value of 999 is programmed into the timer. The prescaler is always a 16-bit integer value in the range 0 .. 65535, representing a division by 1 .. 655362014-09-30 01:41 PM
I have found an excellent example for Factoring the numbers (Prescalar and also the Period). Its in C# but its a start to get to the end result:
public List<int> Factor(int number) {
List<int> factors = new List<int>(); int max = (int)Math.Sqrt(number); //round down for(int factor = 1; factor <= max; ++factor) { //test from 1 to the square root, or the int below it, inclusive. if(number % factor == 0) { factors.add(factor); if(factor != number/factor) { // Don't add the square root twice! Thanks Jon factors.add(number/factor); } } } return factors; }See:
http://stackoverflow.com/questions/239865/best-way-to-find-all-factors-of-a-given-number-in-c-sharp
to get the Targeted Number for (P-1 * Q-1) this works:
uint PnQ = (Clk / DesiredFrequency);
One can factor the Values of Prescalar and Period from there also. I hope this helps others out there as its not the easiest concept to get ones head around.
As an example and some modifications, I get:
Desired Frequency: 6543Hz
Factored Numbers:
i = 1 i = 12838 i = 2 i = 6419 i = 7 i = 1834 i = 14 i = 917 i = 49 i = 262 i = 98 i = 131Freq 6543 = (84000000 (Clk) / 12838 Factored Numbers: (14 * 917))
Actual Frequency calculated is: 6543.075245365322
Thanks to Clive, I have read many of your posts and found them very helpful!
All the best
Chris