Posted on November 21, 2014 at 12:04The original post was too long to process during our migration. Please click on the attachment to read the original post.
PB9?? The AF settings also appear completely wrong.
A quick blind fix here, using the data sheet pin configurations.
#include ''stm32f30x.h''
static void TIM_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
uint16_t TimerPeriod = 0;
uint16_t ChannelPulse = 0;
/* GPIOA & GPIOB Clocks enable */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE);
/* GPIOA & GPIOB Configuration: Channel 3 (TIM2) and Channel 1 (TIM15) as alternate function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // TIM2_CH3
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_10); // TIM2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; // TIM15_CH1
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_1); // TIM15
/* Tim15 and Tim2 Configuration ---------------------------------------------------
Generate 2 PWM signals :
Tim15 input clock (Tim15CLK) is set to APB2 clock (PCLK2)
Tim2 input clock (Tim2CLK) is set to APB1 clock (PCLK1)
=> Tim15CLK = PCLK2 = SystemCoreClock
=> Tim2CLK = PCLK1 = SystemCoreClock
Tim15CLK = SystemCoreClock, Prescaler = 0, Tim15 counter clock = SystemCoreClock
Tim2CLK = SystemCoreClock, Prescaler = 0, Tim2 counter clock = SystemCoreClock
SystemCoreClock is set to 72 MHz for STM32F30x devices
The objective is to generate 2 PWM signal at 1MHz for Tim15 and at 4MHz for Tim2:
- Tim15_Period = (SystemCoreClock / 1000000) - 1
- Tim2_Period = (SystemCoreClock / 4000000) - 1
The channel 1 and channel 3 duty cycle are set to 50%
The Timer pulse is calculated as follows:
- Channel2Pulse = DutyCycle * (Tim15_Period + 1) / 100
- Channel3Pulse = DutyCycle * (Tim2_Period + 1) / 100
Note:
SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f30x.c file.
Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate()
function to update SystemCoreClock variable value. Otherwise, any configuration
based on this variable will be incorrect.
----------------------------------------------------------------------- */
/* Compute the value to be set in ARR regiter to generate signal frequency at 1MHz */
TimerPeriod = (SystemCoreClock / 1000000);
/* Compute CCR1 value to generate a duty cycle at 50% for channel 1 */
ChannelPulse = (uint16_t) (((uint32_t) 5 * TimerPeriod) / 10);
/* Tim15 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, ENABLE);
/* Time Base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = TimerPeriod - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM15, &TIM_TimeBaseStructure);
/* Channel Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = ChannelPulse;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OC1Init(TIM15, &TIM_OCInitStructure); // TIM15_CH1
/* Tim1 counter enable */
TIM_Cmd(TIM15, ENABLE);
/*----------------------------------------------------------------------- */
/* Compute the value to be set in ARR regiter to generate signal frequency at 4MHz */
TimerPeriod = (SystemCoreClock / 4000000 );
/* Compute CCR1 value to generate a duty cycle at 50% for channel 3 */
ChannelPulse = (uint16_t) (((uint32_t) 5 * TimerPeriod) / 10);
/* Tim2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
/* Time Base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = TimerPeriod - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* Channel Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = ChannelPulse;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OC3Init(TIM2, &TIM_OCInitStructure); // TIM2_CH3
/* Tim2 counter enable */
TIM_Cmd(TIM2, ENABLE);
}
int main(void)
{
/*!< At this stage the microcontroller clock setting is already configured,
this is done through SystemInit() function which is called from startup
file (startup_stm32f30x.s) before to branch to application main.
To reconfigure the default setting of SystemInit() function, refer to
system_stm32f30x.c file
*/
/* TIM Configuration */
TIM_Config();
/* Infinite loop */
while (1);
}
#ifdef 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
'', file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Pin configuration is broken, wrong pin, wrong bank Looking at STM32F302R8 LQFP48 pinout: PB14=Tim15_ch1(AF1) and PA9=TIM2_CH3. Where am I wrong? I don't understand.Channel 3 setting configure Channel 1 You mean the Timer period of one overwrite the other? Thanks for your feedback. Best regards
GPIO_Init(GPIOA, &GPIO_InitStructure); Sets up PA9 and PA14, not PB14 AF_6 != AF1 or AF_10 OC1 != OC3 See blind fix example, I don't have a board/scope to hand and I haven't eat my breakfast yet.
Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Sorry to disturb again Clive, but PA14 is assigned for the debugg serial Wire on the STM32F302. As far I understand I can use any other one with correct banck and OC channel.
Thanks a lot for your resolved. Have a good day and take care! Franck
I took now Tim15 ch2 (PA3) on PortA AF9 bus APB2. Code is as follow: #include ''stm32f30x.h'' static void TIM_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; uint16_t TimerPeriod = 0; uint16_t ChannelPulse = 0; /* GPIOA & GPIOB Clocks enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE); /* GPIOA & GPIOB Configuration: Channel 3 (TIM2) and Channel 1 (TIM15) as alternate function push-pull */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // TIM2_CH3 GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_10); // TIM2 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; // TIM15_CH2 GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource14, GPIO_AF_9); // TIM15 /* Tim15 and Tim2 Configuration --------------------------------------------------- Generate 2 PWM signals : Tim15 input clock (Tim15CLK) is set to APB2 clock (PCLK2) Tim2 input clock (Tim2CLK) is set to APB1 clock (PCLK1) => Tim15CLK = PCLK2 = SystemCoreClock => Tim2CLK = PCLK1 = SystemCoreClock Tim15CLK = SystemCoreClock, Prescaler = 0, Tim15 counter clock = SystemCoreClock Tim2CLK = SystemCoreClock, Prescaler = 0, Tim2 counter clock = SystemCoreClock SystemCoreClock is set to 72 MHz for STM32F30x devices The objective is to generate 2 PWM signal at 1MHz for Tim15 and at 4MHz for Tim2: - Tim15_Period = (SystemCoreClock / 1000000) - 1 - Tim2_Period = (SystemCoreClock / 4000000) - 1 The channel 1 and channel 3 duty cycle are set to 50% The Timer pulse is calculated as follows: - Channel2Pulse = DutyCycle * (Tim15_Period + 1) / 100 - Channel3Pulse = DutyCycle * (Tim2_Period + 1) / 100 Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f30x.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. ----------------------------------------------------------------------- */ /* Compute the value to be set in ARR regiter to generate signal frequency at 1MHz */ TimerPeriod = (SystemCoreClock / 1000000); /* Compute CCR1 value to generate a duty cycle at 50% for channel 1 */ ChannelPulse = (uint16_t) (((uint32_t) 5 * TimerPeriod) / 10); /* Tim15 clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, ENABLE); /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = TimerPeriod - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM15, &TIM_TimeBaseStructure); /* Channel Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = ChannelPulse; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OC2Init(TIM15, &TIM_OCInitStructure); // TIM15_CH2 /* Tim1 counter enable */ TIM_Cmd(TIM15, ENABLE); /*----------------------------------------------------------------------- */ /* Compute the value to be set in ARR regiter to generate signal frequency at 4MHz */ TimerPeriod = (SystemCoreClock / 4000000 ); /* Compute CCR1 value to generate a duty cycle at 50% for channel 3 */ ChannelPulse = (uint16_t) (((uint32_t) 5 * TimerPeriod) / 10); /* Tim2 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE); /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = TimerPeriod - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* Channel Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = ChannelPulse; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OC3Init(TIM2, &TIM_OCInitStructure); // TIM2_CH3 /* Tim2 counter enable */ TIM_Cmd(TIM2, ENABLE); } int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f30x.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f30x.c file */ /* TIM Configuration */ TIM_Config(); /* Infinite loop */ while (1); } #ifdef 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) */ /* Infinite loop */ while (1) { } } #endif Nothing on pin PA3 as can be see on attachement. One more pb. Somehow it seems that I break the communication with NUCLEO board. LED1 fixed orange! Keil debugger setting indicating a SW error: No cortex-M. SW device found. It is the second board that I put in the same state and I don't know how to come back!! Thanks for your help on that ''easy'' - I understand subject.
________________
Attachments : Screen_2014-11-21_04-54-36.jpeg : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0s2&d=%2Fa%2F0X0000000bi3%2Fz.WiPvwLpAoggFkPO_G7hf3DHBpk_XbwA1giO7CmMZM&asPdf=false
I took now Tim15 ch2 (PA3) on PortA AF9 bus APB2. Code is as follow: #include ''stm32f30x.h'' static void TIM_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; uint16_t TimerPeriod = 0; uint16_t ChannelPulse = 0; /* GPIOA & GPIOB Clocks enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE); /* GPIOA & GPIOB Configuration: Channel 3 (TIM2) and Channel 1 (TIM15) as alternate function push-pull */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // TIM2_CH3 GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_10); // TIM2 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; // TIM15_CH2 GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource14, GPIO_AF_9); // TIM15 /* Tim15 and Tim2 Configuration --------------------------------------------------- Generate 2 PWM signals : Tim15 input clock (Tim15CLK) is set to APB2 clock (PCLK2) Tim2 input clock (Tim2CLK) is set to APB1 clock (PCLK1) => Tim15CLK = PCLK2 = SystemCoreClock => Tim2CLK = PCLK1 = SystemCoreClock Tim15CLK = SystemCoreClock, Prescaler = 0, Tim15 counter clock = SystemCoreClock Tim2CLK = SystemCoreClock, Prescaler = 0, Tim2 counter clock = SystemCoreClock SystemCoreClock is set to 72 MHz for STM32F30x devices The objective is to generate 2 PWM signal at 1MHz for Tim15 and at 4MHz for Tim2: - Tim15_Period = (SystemCoreClock / 1000000) - 1 - Tim2_Period = (SystemCoreClock / 4000000) - 1 The channel 1 and channel 3 duty cycle are set to 50% The Timer pulse is calculated as follows: - Channel2Pulse = DutyCycle * (Tim15_Period + 1) / 100 - Channel3Pulse = DutyCycle * (Tim2_Period + 1) / 100 Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f30x.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. ----------------------------------------------------------------------- */ /* Compute the value to be set in ARR regiter to generate signal frequency at 1MHz */ TimerPeriod = (SystemCoreClock / 1000000); /* Compute CCR1 value to generate a duty cycle at 50% for channel 1 */ ChannelPulse = (uint16_t) (((uint32_t) 5 * TimerPeriod) / 10); /* Tim15 clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, ENABLE); /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = TimerPeriod - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM15, &TIM_TimeBaseStructure); /* Channel Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = ChannelPulse; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OC2Init(TIM15, &TIM_OCInitStructure); // TIM15_CH2 /* Tim1 counter enable */ TIM_Cmd(TIM15, ENABLE); /*----------------------------------------------------------------------- */ /* Compute the value to be set in ARR regiter to generate signal frequency at 4MHz */ TimerPeriod = (SystemCoreClock / 4000000 ); /* Compute CCR1 value to generate a duty cycle at 50% for channel 3 */ ChannelPulse = (uint16_t) (((uint32_t) 5 * TimerPeriod) / 10); /* Tim2 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE); /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = TimerPeriod - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* Channel Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = ChannelPulse; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OC3Init(TIM2, &TIM_OCInitStructure); // TIM2_CH3 /* Tim2 counter enable */ TIM_Cmd(TIM2, ENABLE); } int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f30x.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f30x.c file */ /* TIM Configuration */ TIM_Config(); /* Infinite loop */ while (1); } #ifdef 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) */ /* Infinite loop */ while (1) { } } #endif Nothing on pin PA3 as can be see on attachement. One more pb. Somehow it seems that I break the communication with NUCLEO board. LED1 fixed orange! Keil debugger setting indicating a SW error: No cortex-M. SW device found. It is the second board that I put in the same state and I don't know how to come back!! Thanks for your help on that ''easy'' - I understand subject.
________________
Attachments : Screen_2014-11-21_04-54-36.jpeg : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0yA&d=%2Fa%2F0X0000000bi4%2FE8ocxkJKo6Yc_pXy0ri6JcdGWY9dERXrH7ZrL9hx67Q&asPdf=false
GPIO_PinAFConfig(GPIOA, GPIO_PinSource14, GPIO_AF_9); // TIM15 Should be PinSource3 Now I need to debugg the NUCLEO board and come back to a communication protocol. Somebody know how I can?