MicroPython的午睡(85) STM32版、入力キャプチャから出力コンペア

Joseph Halfmoon

前回はインプットキャプチャ機能を使用してみました。インプットキャプチャ機能と対にして使われるのがアウトプットコンペア機能です。STM32版のMicroPythonでは両機能が併用可能です。外部で発生するイベントを検出し、イベントから一定時間後に何かの制御を行うということをハードウエアの正確なタイミングで行えます。

※「MicroPython的午睡」投稿順 Indexはこちら

実験に使用しているMicroPythonと参照ドキュメント

使用しているMicroPythonは第77回でインストールしたSTマイクロエレクトロニクス社製Nucleo-F401REボード用のものです。同じSTM32マイコン搭載のpyboard版のドキュメントがほぼほぼ流用可能と思われます。Timerに関しては以下のページが参考になります。

class Timer — control internal timers

ハードウエア構成と動作

前回はNucleo-F401REボードのArduino互換ピンソケットのD7端子を入力キャプチャ用に使用しました。今回はお隣のD8端子を出力コンペア用に使用してみます。使用するタイマはSTM32が持つ「アドバンスド・コントロール・タイマ」Timer1です。

冒頭のアイキャッチ画像にインプットキャプチャとアウトプットコンペア併用の概念図を掲げました。動作としてはこんな感じです。

    1. タイマ1の16ビットカウンタは「フリーラン」状態で走ってます。
    2. インプットキャプチャ端子(今回はD7端子)が事前に設定した状態になると上記の16ビットカウンタの値がチャネル(今回はチャネル1)のキャプチャレジスタに保存されます。
    3. ソフトウエアで上記のキャプチャレジスタの値を読み取って、上記のイベントから必要なインターバル時間後に相当する「将来のカウンタ値」を計算して第2のチャネルのコンペアレジスタにセットします。
    4. 第2のチャネルは設定したカウンタ値(将来時刻)に到達するとアウトプットコンペア端子の状態を変更(今回はトグル)します。

ソフトウエアが介入するのは3の部分だけです。2の入力から4の出力までの時間は、ハードウエアによって正確に(カウンタのレゾリューションどおりに)確保されます。制御向きの機能であります。

今回使用のソースコード

今回使用のソースコードは、例によって前回使用のもののチョイ直しです。そのため、上記のステップのうち3番目のソフトウエアのところは通常割り込みでトリガをかけるべきところ、手抜きのポーリングでやってます。まあ、割り込み化は次回かね。

入力キャプチャは立ち上がりを見る設定です。出力コンペアは出力レベルをトグルさせてます。

#STM32: Timer 1 IC Test, callback
#Timer1 CH1 ... PA8(D7)
#Timer1 CH2 ... PA9(D8)
import pyb
import machine
import time

def main():
    tim = pyb.Timer(1, prescaler=1023, period=0xffff)
    print("STM32F401RE Timer 1 IC/OC Test.")      
    print("Source  Freq: {0} Hz".format(tim.source_freq()))
    print("Timer 1 Freq: {0} Hz".format(tim.freq()))
    icCH = tim.channel(1, pyb.Timer.IC, polarity=pyb.Timer.RISING, pin=machine.Pin.board.D7)
    ocCH = tim.channel(2, pyb.Timer.OC_TOGGLE, pin=machine.Pin.board.D8)
    diffV = 1000
    while True:
        oldV = icCH.capture()
        nV = icCH.capture()
        while oldV == nV:
            nV = icCH.capture()
        newTGL = nV + diffV
        if newTGL > 0xffff:
            newTGL -= 0xffff
        ocCH.compare(newTGL)

if __name__ == "__main__":
    main()
実機での実験結果

黄色C1がインプットキャプチャへの入力信号の波形です。10Hzの矩形波をテスト用に入れてます。青色C2がアウトプットコンペアの出力波形です。黄色の立ち上がりエッジから「一定期間後」にトグルするように設定したので、周波数的には2分周でほぼ5Hzの波形が観測できてます。10Hz_diff1000wave

肝心な部分は、黄色の立ち上がりエッジから、トグルまでの期間です。以下の測定は、上記ソースのdiffVの値が1000のときです。カーソルのΔ約12.2m秒とな。10Hz_diff1000mes

つづいて、diffVの値を2000に変更してみました。カーソルのΔ約24.1m秒とな。

10Hz_diff2000mes

コンペアレジスタに設定する値で出力タイミングを制御できてるみたいです。あたりまえか。

MicroPython的午睡(84) STM32版Timer1入力キャプチャで周波数測定 へ戻る

MicroPython的午睡(86) STM32版、タイマ・チャネル、割り込み受け TIPS へ進む