2015-10-26 06:30 AM
Hi
Some days ago I tried to add a PWM function in my project, As it was unsuccessfull, I built a working standalone pwm project that I tried to integrate to the real life project. I did not succeed in making it work. To understand what happens, I removed every piece of code to get a minimum non working project. Now I face some very stranges behaviours : - removing one or several unused uint16_t variables turns the unworking code to a working one. - inlining a function called once turns the unworking code to a working one. - replacing a call to function A which only do a call to function B by a direct call to function B turns the unworking code to a working one. I really don't unerdstand what happens. If anybody has an idea of what may happen, I'm interested in any clue. Optimization is -O0. µc : STM32F103VET6. Code attached and below. Search for ''***'' pattern to find comments that points the above lines of code. main.c
#include
#include ''board.h''
int
main(
void
)
{
// board_timer_init();
board_init_mcu();
// *** calling the previous commented function instead of this one makes the code work.
RightTimerLedStart( );
while
( 1 )
{
}
}
board.h
#ifndef SRC_BOARD_H_
#define SRC_BOARD_H_
#include
#include
#include
#include ''stm32f10x.h''
#include ''timer_board.h''
/*!
* Board GPIO pin names
*/
typedef
enum
{
PA_0 = 0, PA_1, PA_2, PA_3, PA_4, PA_5, PA_6, PA_7, PA_8, PA_9, PA_10, PA_11, PA_12, PA_13, PA_14, PA_15,
PB_0, PB_1, PB_2, PB_3, PB_4, PB_5, PB_6, PB_7, PB_8, PB_9, PB_10, PB_11, PB_12, PB_13, PB_14, PB_15,
PC_0, PC_1, PC_2, PC_3, PC_4, PC_5, PC_6, PC_7, PC_8, PC_9, PC_10, PC_11, PC_12, PC_13, PC_14, PC_15,
PD_0, PD_1, PD_2, PD_3, PD_4, PD_5, PD_6, PD_7, PD_8, PD_9, PD_10, PD_11, PD_12, PD_13, PD_14, PD_15,
PE_0, PE_1, PE_2, PE_3, PE_4, PE_5, PE_6, PE_7, PE_8, PE_9, PE_10, PE_11, PE_12, PE_13, PE_14, PE_15,
PF_0, PF_1, PF_2, PF_3, PF_4, PF_5, PF_6, PF_7, PF_8, PF_9, PF_10, PF_11, PF_12, PF_13, PF_14, PF_15,
PH_0, PH_1, PH_2, PH_3, PH_4, PH_5, PH_6, PH_7, PH_8, PH_9, PH_10, PH_11, PH_12, PH_13, PH_14, PH_15,
// Not connected
NC = (
int
)0xFFFFFFFF
} PinNames;
/*!
* Define the GPIO IRQ on a rising, falling or both edges
*/
typedef
enum
{
NO_IRQ = 0,
IRQ_RISING_EDGE,
IRQ_FALLING_EDGE,
IRQ_RISING_FALLING_EDGE
} IrqModes;
/*!
* Define the IRQ priority on the GPIO
*/
typedef
enum
{
IRQ_VERY_LOW_PRIORITY = 0,
IRQ_LOW_PRIORITY,
IRQ_MEDIUM_PRIORITY,
IRQ_HIGH_PRIORITY,
IRQ_VERY_HIGH_PRIORITY
} IrqPriorities;
/*!
* Structure for the GPIO
*/
typedef
struct
{
PinNames pin;
uint16_t pinIndex;
GPIO_TypeDef *port;
uint16_t portIndex;
} Gpio_t;
#define RIGHT_BLUE_LED PA_9
extern
Gpio_t right_blue_led;
void
board_init_mcu(
void
);
void
board_timer_init(
void
);
/*!
* \brief Initializes the given GPIO object
*
* \param [IN] obj Pointer to the GPIO object to be initialized
* \param [IN] pin Pin name ( please look in pinName-board.h file )
* \param [IN] mode Pin mode (This parameter can be a value of @ref GPIOMode_TypeDef)
* \param [IN] value Default output value at initialization
*/
void
gpio_init( Gpio_t *obj, PinNames pin, GPIOMode_TypeDef mode);
#endif /* SRC_BOARD_H_ */
board.c
#include ''board.h''
Gpio_t right_blue_led;
void
board_init_mcu(
void
)
{
board_timer_init();
}
void
board_timer_init(
void
)
{
TimersLedsInit();
}
void
gpio_init( Gpio_t *obj, PinNames pin, GPIOMode_TypeDef mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
if
( pin == NC )
{
return
;
}
obj->portIndex = ( uint32_t ) pin >> 4;
obj->pin = pin;
obj->pinIndex = ( 0x01 << ( obj->pin & 0x0F ) );
obj->port = ( GPIO_TypeDef * )( GPIOA_BASE + ( obj->portIndex << 10 ) );
RCC_APB2PeriphClockCmd( ( RCC_APB2Periph_GPIOA << obj->portIndex ), ENABLE );
GPIO_InitStructure.GPIO_Mode = mode;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = obj->pinIndex;
GPIO_Init( obj->port, &GPIO_InitStructure );
}
timer_board.h
#ifndef SRC_TIMER_BOARD_H_
#define SRC_TIMER_BOARD_H_
#include /* C99 types */
void
TimersLedsInit();
void
RightTimerLedStart( );
#endif /* SRC_TIMER_BOARD_H_ */
timer_board.c
#include /* C99 types */
#include
#include ''board.h''
void
TimersLedsInit()
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 56000;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 1000;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
/* TIM1 clock enable */
RCC_APB2PeriphClockCmd( RCC_APB2Periph_TIM1, ENABLE );
/* Time base configuration */
TIM_TimeBaseInit( TIM1, &TIM_TimeBaseStructure );
TIM_Cmd( TIM1, DISABLE );
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void
RightTimerLedStart( )
{
gpio_init( &right_blue_led, RIGHT_BLUE_LED, GPIO_Mode_AF_PP );
// *** Changing this line by the following paragraph (which is the inline equivalent) makes the code work.
// GPIO_InitTypeDef GPIO_InitStructure;
// RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA , ENABLE );
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
// GPIO_Init(GPIOA, &GPIO_InitStructure );
uint16_t CCR1_Val = 500;
uint16_t CCR2_Val = 249;
// *** Removing this unused variable makes the code work.
uint16_t CCR3_Val = 166;
// *** Removing this unused variable makes the code work.
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init( TIM1, &TIM_OCInitStructure );
// *** removing this (useless) line makes the code work.
TIM_OC2Init( TIM1, &TIM_OCInitStructure );
TIM_ARRPreloadConfig( TIM1, ENABLE );
/* TIM3 enable counter */
TIM_Cmd( TIM1, ENABLE );
TIM_CtrlPWMOutputs( TIM1, ENABLE );
}
#stm32f103-pwm
2015-10-26 06:52 AM
Maybe you haven't allocated enough space for the stack.
Hope this helps,Danish2015-10-26 06:57 AM
[deleted] as Danish Ali was faster ;)
2015-10-26 08:16 AM
Hi,
Thanks for your answer. Where do you find this information ? I had a look to the startup and link files but this was not obvious to me... Julien