1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

STM32のTIMの位相をずらす

Posted at

TIMでPWMを出している途中で、TIMの位相を正確に動かしたい、というニッチ(たぶん)な使い方。

image.png

1段目がPWMの波形。
2段目がデバッグ用のピン出力。

デバッグ出力がバタバタしたあたりでPWMの位相が50%ほど変化しているのがわかる。

1つ目のエッジで「次の周期で位相を変えなさい」という指示を出す(ループ)。
指示の直後の割り込み(2つ目のエッジ)で周期を調整している(ISR)。
そのままだと以降も周期が短いままなので、その次の割り込み(3つ目のエッジ)で周期を戻している(ISR)。

テストコード

初期化
htim3.Instance->PSC = 0;
htim3.Instance->ARR = tim3_ARR;
htim3.Instance->CCR1 = 500;

HAL_TIM_GenerateEvent(&htim3, TIM_EVENTSOURCE_UPDATE);

HAL_TIM_RegisterCallback(&htim3, HAL_TIM_PERIOD_ELAPSED_CB_ID, TIM3_period);

HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);

osDelay(5);

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET);
__HAL_TIM_CLEAR_IT(&htim3, TIM_IT_UPDATE);
__HAL_TIM_ENABLE_IT(&htim3, TIM_IT_UPDATE);

osDelay(5);

HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
ISR
void TIM3_period(TIM_HandleTypeDef *htim)
{
    HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_7);

    if (htim3.Instance->ARR == tim3_ARR)
    {
        htim3.Instance->ARR = tim3_ARR / 2;
    }
    else
    {
        htim3.Instance->ARR = tim3_ARR;
        __HAL_TIM_DISABLE_IT(&htim3, TIM_IT_UPDATE);
    }
}

今回は周期・移相量を定数で固定としたが、適当な変数で持たせれば自由に動かせるはず。

また、コールバックを使うので、どこかで#define USE_HAL_TIM_REGISTER_CALLBACKS 1を定義しておく必要がある。

その他

タイミングクリティカルな処理をゴリゴリやるので、実際に使う際は十分注意すること。今回のテストコードは実環境ではたぶんうまく動かない(低確率でバグる)。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?