2014年2月22日土曜日

STM32F1 TIMでPWM出力

STM32F103VEのTIM3でPWM出力をしてみた

コード

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    {
        TIM_TimeBaseInitTypeDef TIM_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

        TIM_InitStructure.TIM_Period = 7200 - 1;
        TIM_InitStructure.TIM_Prescaler = 1000 - 1;
        TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
        TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_InitStructure.TIM_RepetitionCounter = 0;

        TIM_TimeBaseInit(TIM3, &TIM_InitStructure);
    }
    {
        TIM_OCInitTypeDef TIM_OCInitStructure;

        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
        TIM_OCInitStructure.TIM_Pulse = 3600 - 1;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

        TIM_OC1Init(TIM3, &TIM_OCInitStructure);

        TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
    }

    TIM_ARRPreloadConfig(TIM3, ENABLE);
    TIM_Cmd(TIM3, ENABLE);

TIM3の出力1はGPIOAの6に出ている
なのでまずはGPIOの初期化をする
そしてタイマの初期化
72MHzのマイコンに対して10Hzでリセットされるように設定した

そしてTIM_OCを初期化する
このあたりはよくわかってない
本来TIM_OCInitTypeDefはもっと機能が多いのだけど TIM3の場合はすべての機能がハードウェアに実装されているわけではないのでこれくらい設定しておけばいいらしい

そして最後に諸々の有効化
あとは無限ループにでも突っ込んでおけば勝手にPWMが出力される
ロジアナで見ると10Hzの波が出てるので問題ないはず
パルスの周波数を設定するのはTIM_TimeBaseInitで デューティ比はTIM_OCxInitで行うようだ
今回はTIMのカウントダウンが7200に対してデューティ比設定が3600なのでちょうど50%になる

ちなみにこのパルス出力は完全にハードウェアで行われるため、__WFIで低消費電力モード(?)に入った状態のマイコンからも出力される
低消費電力にしたところでパルス幅の変更はできないし、他の処理もできないけれど

パルス出力はタイマ1本に大して4本まで個別に設定可能のようだ
例えばTIMを適当に設定してやればタイマ1本でサーボモーターを4個まで個別に操作できる
完全にバックグラウンドで処理されるのでCPUへの負荷も最小限で済む



ほんとうはこのエントリはタイマを使ったPWMではなく、DMAを使ってGPIOを高速で書き換える実験を書きたかった
しかしDMAを使った場合の出力が7MHz程度に対して、ソフトウェアで書き出すと12MHzくらいで出力できてしまった
DMAならバックグラウンドで処理できるけど、あまり美味しくないので今回はスルーした


もうちょっといろいろ試して、ある程度形になったらまたまとめようと思う
が、制御対象のモジュールを買ってこないとダメなのと、性能的にちゃんと制御できるかわからないので どうなることやら

追記:2015/11/16
TIM1,8,15,16,17ではTIM_CtrlPWMOutputsで出力を有効にする必要がある。TIM_CtrlPWMOutputs(TIM1, ENABLE);のように設定しないと出力されない。

0 件のコメント:

コメントを投稿