2020-05-09 03:29 AM
I have read STM32f1 Reference Manual and tested STM32CubeMx functions but have not found any solution.
Is there a way to change PWM polarity without Deinitializing Timer??
Solved! Go to Solution.
2020-05-10 11:11 AM
If the phase of the pwm signal is unimportant, write max - val instead of val to the ccr to invert the polarity.
2020-05-09 04:50 AM
I can't test it right now, but I think that toggling the CC*P bit in the CCER register can achieve this. E.g. to invert the polarity of timer 2 channel 3, do
TIM2->CCER ^= TIM_CCER_CC3P;
As it is a read-modify-write sequence, be careful that no other thread or interrupt handler accesses the register at the same time.
To avoid glitches in the output, you might want to reconfigure the pin to GPIO output e.g. on the compare event, invert the polarity, and switch back to alternate mode on the update event.
2020-05-09 05:48 AM
No, It doesn't work I have tried it before, using CMSIS & Registers.Thanks for your reply, I've tested it again, but the result is the same.
I want to change my PWM signal as pictures:
2020-05-09 12:17 PM
What have you tried exactly?
What is on those waveforms you posted? Which pin and how exactly did you generate those waveforms?
Read out content of the TIM registers before the change and after and compare/post together with respective waveforms.
JW
2020-05-09 08:41 PM
I have configured my TIM8 & Channel1 as below to generate PWM :
void PWM_Init (void)
{
TIM_TimeBaseInitTypeDef base;
TIM_OCInitTypeDef ocx;
NVIC_InitTypeDef nvic;
//Enable Pin Configurations (Clock & GPIO)
PioEnableClock( MAN_EN_PORT );
PioSetOutput(MAN_EN_PORT,MAN_EN_PIN_N);
PioSetPin(MAN_EN_PORT,MAN_EN_PIN_N);
//Timer & Channels Configurations (Clock & Alternative Functions)
RccSetTimerClock( MAN_PWM_TIMER, ENABLE );
PioEnableClock( MAN_PWM_1_PORT );
PioSetAlternateFunS( MAN_PWM_1_PORT, MAN_PWM_1_PIN, PIO_PIN_AF_PP );
// PioSetAlternateFunS( MAN_PWM_2_PORT, MAN_PWM_2_PIN, PIO_PIN_AF_PP );
PioSetOutput(MAN_PWM_2_PORT,MAN_PWM_2_PIN_N);
PioSetPin(MAN_PWM_2_PORT,MAN_PWM_2_PIN_N);
//Timer Configurations 2KHz
base.TIM_Prescaler = 18-1;
base.TIM_Period = 2000;
base.TIM_ClockDivision = 0;
base.TIM_RepetitionCounter = 0;
base.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit( MAN_PWM_TIMER, &base );
//Channels Configurations as PWM
ocx.TIM_OCMode = TIM_OCMode_PWM1;
ocx.TIM_OutputState = ENABLE;
ocx.TIM_OCPolarity = TIM_OCPolarity_Low;
ocx.TIM_OCIdleState = TIM_OCIdleState_Reset;
ocx.TIM_Pulse = 200;
TIM_OC1Init( MAN_PWM_TIMER, &ocx );
// ocx.TIM_OCMode = TIM_OCMode_PWM1;
// ocx.TIM_OutputState = ENABLE;
// ocx.TIM_OCPolarity = TIM_OCPolarity_High;
// ocx.TIM_OCIdleState = TIM_OCPolarity_Low;
// ocx.TIM_Pulse = 0;
// TIM_OC2Init( MAN_PWM_TIMER, &ocx );
//NVIC Configurations
nvic.NVIC_IRQChannel = TIM8_CC_IRQChannel;
nvic.NVIC_IRQChannelCmd = ENABLE;
nvic.NVIC_IRQChannelPreemptionPriority = 4;
nvic.NVIC_IRQChannelSubPriority = 0;
NVIC_Init( &nvic );
//! Enable Output
TIM_CtrlPWMOutputs( MAN_PWM_TIMER, ENABLE );
TIM_ARRPreloadConfig( MAN_PWM_TIMER, DISABLE );
TIM_CCPreloadControl( MAN_PWM_TIMER, ENABLE );
TIM_Cmd( MAN_PWM_TIMER, ENABLE );
}
I want to change my signal as pictures with a command, I have used both thses code to change polarity, CC1P in CCER changes but signal doesn't change:
TIM_OC1PolarityConfig(MAN_PWM_TIMER,TIM_OCPolarity_High);
MAN_PWM_TIMER->CCER ^= TIM_CCER_CC1P;
I have defined another function called PWM_change & DeInit Timer and change Output Compare Configuration as below, other configuration is the same as PWM_Init():
ocx.TIM_OCMode = TIM_OCMode_PWM1;
ocx.TIM_OutputState = ENABLE;
ocx.TIM_OCPolarity = TIM_OCPolarity_High;
ocx.TIM_OCIdleState = TIM_OCIdleState_Reset;
ocx.TIM_Pulse = 200;
TIM_OC1Init( MAN_PWM_TIMER, &ocx );
and it works calling PWM_Change() instead of changing Polarity. Bad story is it doesn't work when I remove DeInit function from first part of PWM_Change() function.
And I need use PWM signal in a PID controller and can not Init & DeInit Timer everytime.
I look for a better way to change PWM signal.
2020-05-09 11:28 PM
Which pin? Isn't it TIM8_CH1N?
Read out content of the TIM registers before the change and after and compare/post together with respective waveforms.
2020-05-10 01:01 AM
PC.6 TIM8_CH1 default pin
2020-05-10 01:17 AM
Read out content of the TIM registers before the change and after and compare/post together with respective waveforms.
2020-05-10 03:33 AM
CC1P in CCER has changed that is normal but OIS2 in CR2 has changed too.
2020-05-10 05:20 AM
OK so now if you perform the same change by directly writing to registers, you will see the waveform changing in the same way too.
To try it, you don't need to write any code, simply change it directly in the debugger.
JW