Top.Mail.Ru
Уведомления
Очистить все

[Решено] Не могу изменить период PWM

ll47
 ll47
(@ll47)
Level 1

Привет, использую таймер для генерации PWM. Настройки таймера:

static void MX_TIM3_Init(void)
{

  /* USER CODE BEGIN TIM3_Init 0 */

  /* USER CODE END TIM3_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};

  /* USER CODE BEGIN TIM3_Init 1 */

  /* USER CODE END TIM3_Init 1 */
  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 47;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 3333;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 1667;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM3_Init 2 */

  /* USER CODE END TIM3_Init 2 */
  HAL_TIM_MspPostInit(&htim3);

}

Запускаю так:

HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_4);

После этого PWM генерируется нормально, проверяю осциллографом. Попозже смогу приложить фото. Добавил колбэк для таймера, в котором хочу изменить период, оставив скважность 50%:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if (htim == &htim3)
  {
    TIM3->ARR = (new_period / 10000 * 65535);
    TIM3->CCR4 = (new_period / 10000 * 65535) / 2;
  }
}

В переменной new_period у меня значения меняются от 1 до 10000. А для PWM я хочу значения от 1 до 65535, поэтому нормирую new_period и умножаю на 65535. Но после первого захода в колбэк сигнал на выходе просто пропадает.

Подскажите, в чем может быть проблема?

Цитата
Создатель темы Размещено : 11.11.2021 15:08
Метки темы
Aveal
(@aveal)
Top level Admin

Добрый вечер, а new_period  как объявлена?

ОтветитьЦитата
Размещено : 11.11.2021 18:49
ll47
 ll47
(@ll47)
Level 1
От: @aveal

Добрый вечер, а new_period  как объявлена?

Добрый вечер, спасибо за ответ))

uint16_t new_period;
ОтветитьЦитата
Создатель темы Размещено : 11.11.2021 19:15
Aveal
(@aveal)
Top level Admin

@ll47 Здесь деление всегда 0 дает:

new_period / 10000

Надо к float привести явно:

TIM3->ARR = (uint16_t)((float)new_period / 10000 * 65535);
ОтветитьЦитата
Размещено : 12.11.2021 11:31
ll47
 ll47
(@ll47)
Level 1

Мда, прежде чем грешить на библиотеки всегда стоит свой код проверить... 

@aveal сильно благодарю, все заработало!

ОтветитьЦитата
Создатель темы Размещено : 12.11.2021 13:45
(@stm128)
New member

Позитивно у вас тут.... редко встретишь такие форумы

ОтветитьЦитата
Размещено : 12.11.2021 17:54
Aveal reacted
Aveal
(@aveal)
Top level Admin

@stm128, вечер добрый) Я, в принципе, для этого изначально форум и создавал. Из-за того, что на 99% из русскоязычных форумов токсичность зашкаливает, надоело.

ОтветитьЦитата
Размещено : 12.11.2021 18:24
stm128 reacted
Поделиться: