2013-05-14 04:57 AM
As the subject above, can sb tell me about the difference between TIM_TimeBaseStructure.TIM_Prescaler and TIM_PrescalerConfig?
As below is the code from ST Example Librabry: [CODE] __IO uint16_t CCR1_Val = 54618; PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 500000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* Prescaler configuration */ TIM_PrescalerConfig(TIM3, PrescalerValue, TIM_PSCReloadMode_Immediate); /* Output Compare Timing Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; (CCR1_Val = TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable); [/CODE] and Handler [CODE] if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET) { TIM_ClearITPendingBit(TIM3, TIM_IT_CC1); /* LED4 toggling with frequency = 4.57 Hz */ STM_EVAL_LEDToggle(LED4); capture = TIM_GetCapture1(TIM3); TIM_SetCompare1(TIM3, capture + CCR1_Val); } [/CODE] As the code above, why period is 65535, i've read a thread swhere about this issue and they said : ''Here ARR is set to 65535. The objective was to generate an interrupt at every overflow of CC register and immediately sett the counter to zero so that the timer cannot go beyond CC value''. Is this true? Why when i use counter_down mode, and set period =1 , is going wrong? Why when i use tim2 and set period at (2^32 -1) , it dun run as the same as tim3 with 65535 ( 2^16 -1 ) ? Sorry for alot question, i'm a beginner with lots of question. Hope sb can help me. Thanks alot.2013-05-14 07:23 AM
Different ways of setting the same registers.
A Period of 65536-1 allows for simple math in advancing the CCR, ie 16-bit math handles the wrapping. A Period of less than 3, you'd probably want to avoid doing that, and instead decrease the prescale. If down in small values, you should consider PWM modes, chasing the CCR interrupt is prone to saturate the processor and result in odd/unexpected waveforms. Downcounting goes from the Period value to 0, and then resets to the Period value. The CCR chasing scheme should workable in 16-bit and 32-bit timers, would need to see code to understand your issue.2013-05-14 07:44 PM
Thanks for your reply,
I'm studing step by step , follow examples in ST library, the code above in TIM_BASE example I use STM32-Discovery board, the original code use TIM3 16bit to setfrequency
for 4 channel in output capture mode. When i replace with TIM2 32bit, and change the period to 2^32 -1 ( because i think TIM3 16bit is 65535 , so TIM2 32bit will be (65535*65535) -1) , and they must running as the same way, blinking led as the samefrequency
, but it do not. Can you explain in more detail please?. How to create frequency at 1Hz with TIM2 in this way ( use output compare mode)? I've aldready known to create 1Hz with basic way: setting period,prescaler independently with CCR. So i just want to understanding how to create frequency in this mode. Thanks alot.2013-05-14 09:02 PM
This should be a working 32-bit CCR chasing example for the STM32F4-Discovery
// STM32F4-Discovery TIM2 32-bit OC (PA.01 TIM2_CH2) - sourcer32@gmail.com
#include ''stm32f4_discovery.h''
#define CCR2_VAL (42000000) // 2Hz TIM2CLK = 84000000 APB1=AHB/4 * 2
/**************************************************************************/
void RCC_Config(void)
{
/* GPIOA clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
}
/**************************************************************************/
void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM2 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************************/
void GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOA Configuration: TIM2 CH2 (PA1) */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Connect TIM2 pins to AF */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2);
}
/**************************************************************************/
void TIM2_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 0xFFFFFFFF; // 32-bit maximal
TIM_TimeBaseStructure.TIM_Prescaler = 0; // Run at 84 MHz
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* Output Compare Timing Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR2_VAL;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable);
/* TIM Interrupts enable */
TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);
/* TIM2 enable counter */
TIM_Cmd(TIM2, ENABLE);
}
/**************************************************************************/
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET) // 2 Hz rate
{
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
/* LED3 toggling with frequency = 1 Hz */
STM_EVAL_LEDToggle(LED3);
TIM2->CCR2 += CCR2_VAL;
}
}
/**************************************************************************/
int main(void)
{
RCC_Config();
NVIC_Config();
GPIO_Config();
/* Initialize Leds mounted on STM32F4-Discovery board */
STM_EVAL_LEDInit(LED4);
STM_EVAL_LEDInit(LED3);
STM_EVAL_LEDInit(LED5);
STM_EVAL_LEDInit(LED6);
/* Turn on LED4, LED3, LED5 and LED6 */
STM_EVAL_LEDOn(LED4);
STM_EVAL_LEDOn(LED3);
STM_EVAL_LEDOn(LED5);
STM_EVAL_LEDOn(LED6);
/* TIM2 Configuration */
TIM2_Config();
while(1); // Do not exit
}
2013-05-14 09:15 PM
A 32-bit PWM example
// STM32F4-Discovery TIM2 32-bit PWM (PA.01 TIM2_CH2 1Hz) - sourcer32@gmail.com
#include ''stm32f4_discovery.h''
#define ONEHZ (84000000) // 1Hz TIM2CLK = 84000000 APB1=AHB/4 * 2
/**************************************************************************/
void RCC_Config(void)
{
/* GPIOA clock enable */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
}
/**************************************************************************/
void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable the TIM2 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**************************************************************************/
void GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOA Configuration: TIM2 CH2 (PA1) */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Connect TIM2 pins to AF */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2);
}
/**************************************************************************/
void TIM2_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 0; // Run at 84 MHz, to demonstrate 32-bit Period
TIM_TimeBaseStructure.TIM_Period = ONEHZ - 1; // Ticks for 1Hz, 1 Second Period
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* PWM1 Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = ONEHZ / 2; // 50/50 duty
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
/* TIM Interrupts enable */
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
/* TIM2 enable counter */
TIM_Cmd(TIM2, ENABLE);
}
/**************************************************************************/
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) // 1 Hz rate
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
/* LED3 toggling with frequency = 1/2 Hz */
STM_EVAL_LEDToggle(LED3);
}
}
/**************************************************************************/
int main(void)
{
RCC_Config();
NVIC_Config();
GPIO_Config();
/* Initialize Leds mounted on STM32F4-Discovery board */
STM_EVAL_LEDInit(LED4);
STM_EVAL_LEDInit(LED3);
STM_EVAL_LEDInit(LED5);
STM_EVAL_LEDInit(LED6);
/* Turn on LED4, LED3, LED5 and LED6 */
STM_EVAL_LEDOn(LED4);
STM_EVAL_LEDOn(LED3);
STM_EVAL_LEDOn(LED5);
STM_EVAL_LEDOn(LED6);
/* TIM2 Configuration */
TIM2_Config();
while(1); // Do not exit
}
2013-05-15 12:52 AM
Thanks you so much!
2013-05-15 01:39 AM
After check the stm32f4xx_it.c , I recognize that I din't change the capture value to uint32_t yet, that why when i replace TIM3 by TIM2, it go wrong :D. I really appreciate your help,Thanks you so much!!
By the way, Can you explain what alternate function is, please? I haven't used it before...What it for??2013-05-15 04:06 AM
Alternate Function is where the pin is connected to one of the Peripheral input/output functions, rather than being a direct user controlled GPIO pin.
GPIO_PinAFConfig() should be considered like a multi way dial switch, which allows the selection of one of several peripherals to the pin. This provides some flexibility about what peripheral functions are escaped from which pins.2013-05-15 11:21 PM
If so, when i connect led directly with PA1 as the chasing CCR code you post above, will the led blink as the same frequency as the timer, or what?