cancel
Showing results for 
Search instead for 
Did you mean: 

Pwm pin Continuous high

RChou.1
Associate III

I am working on STM32F103 and made a pwm with TIM1 channel 1 and 2 with channel 1 non inverted and channel 2 inverted, when i am disabling the pwm using HAL the inverted channel goes to continuous high state. any kind of help will be appreciable and will be helpful tome as well. 

3 REPLIES 3
Bob S
Principal

Well, if non-inverted Idle is low, then "inverted" idle is high, isn't it?

If you want both PWM outputs to go low when your disable them, then after you disable the PWM, change the channel 2 pin from "special function" to "output" and drive it low.  This also means that when you re-enable the PWM you need to change the channel 2 pin from "output" back to "special function".

Thank you Mr Bob S for giving your valuable time to this post,

I have some doubt that In AVR MCU i have made the same and i faced this issue as well, to overcome this i made this

ICR1 =0;
OCR1A=0;
OCR1B=ICR1+1; 

here if OCR1B stars counting from 1 and ICR1 having the value 0 it always resets to zero because of it inverted mode. So my question is does this work in STM32 same and if not then why it does not.

to find my answer  i tried this logic and it did not work. By that time i tried different combinations as i have to get the desired output and some how a solution came up,

for disabling i used this line of code.

HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);
htim1.Init.AutoReloadPreload = 0;
TIM1->CNT=0;
TIM1->CCR1=0;
TIM1->CCR2=-1;

 

And for enabling i used this.

HAL_TIM_PWM_Start( &htim1, TIM_CHANNEL_1 );
HAL_TIM_PWM_Start( &htim1, TIM_CHANNEL_2 );
pwmData(uADC1);

 

As well as i am attaching my entire code for your better understanding what i have done till now.

 

int main(void)
{
  HAL_Init();
 
  SystemClock_Config();
 
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_TIM1_Init();
  MX_ADC1_Init();
  MX_TIM2_Init();
  HAL_ADC_Start_DMA(&hadc1, uADCVal, 6);
  HAL_TIM_Base_Start_IT(&htim2);
 
  HAL_TIM_PWM_Start( &htim1, TIM_CHANNEL_1 );
  HAL_TIM_PWM_Start( &htim1, TIM_CHANNEL_2 );
  htim1.Init.AutoReloadPreload = 0;
  TIM1->CNT=0;
  TIM1->CCR1=0;
  TIM1->CCR2=-1;
  while (1)
  {
  if (flagu) {
AD1 += uADCVal[0];
AD2 += uADCVal[1];
AD3 += uADCVal[2];
AD4 += uADCVal[3];
AD5 += uADCVal[4];
AD6 += uADCVal[5];
//increment=0;
 
if (count >= 500) {
uADC1 = AD1/500;
AD1=0;
uADC2 = AD2/500;
volt = (float)uADC2*0.00080244078;
AD2=0;
uADC3 = AD3/500;
temp2 =(float)uADC3*0.99;
AD3=0;
uADC4 = AD4/500;
AD4=0;
uADC5 = AD5/500;
AD5=0;
uADC6 = AD6/500;
AD6=0;
count=0;
}
flagu=0;
}
  //a = map2(temp2,min, max, Omin, Omax);
  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12)==GPIO_PIN_RESET){
  HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
  HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_2);
  htim1.Init.AutoReloadPreload = 0;
  TIM1->CNT=0;
  TIM1->CCR1=0;
  TIM1->CCR2=-1;
  }
  else{
  HAL_TIM_PWM_Start( &htim1, TIM_CHANNEL_1 );
    HAL_TIM_PWM_Start( &htim1, TIM_CHANNEL_2 );
  pwmData(uADC1);
  }
  }
}

void pwmData(uint16_t dat){
__HAL_TIM_SET_AUTORELOAD(&htim1,dat);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1,dat*0.45);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2,dat*0.55);
}

*/
static void MX_TIM1_Init(void)
{

/* USER CODE BEGIN TIM1_Init 0 */

/* USER CODE END TIM1_Init 0 */

TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};

/* USER CODE BEGIN TIM1_Init 1 */

/* USER CODE END TIM1_Init 1 */
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED1;
htim1.Init.Period = 400;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
Error_Handler();
}
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 0;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM1_Init 2 */

/* USER CODE END TIM1_Init 2 */
HAL_TIM_MspPostInit(&htim1);

}

I forgot to add I am using BLUEPILL.

I still find 500mv on my both pwm pins.

So my question is does my solution make any sense and is it safe to use or not. kindly share your opinion which is really important to me.

Thank you.

Bob S
Principal

If you disable PWM (using HAL functions) then changing the OC registers will have no effect on the output pin, because the timer is disabled.  And if the timer is disabled, the OC functions are disabled.

You may be able to find some way to stop timer's input clock then change the registers as you did on the AVR processor.  But really, why not just manually drive the pin to the desired level as I described above and be done with it?