MicroPython的午睡(81) STM32F401RE版、使われているタイマを調べる

Joseph Halfmoon

前回ADCをサンプリングするのにタイマ4を使ってしまいましたが「誰もタイマ4を使っていないの?」という疑問を調べもせずの見切り発車でした。今回は、STM32マイコン専用のstmモジュールを使って、タイマが動いているか否かを判定できるようにしたいと思います。それにしてもSTM32、タイマ充実してます。

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

STM32F401RE搭載のタイマ

まず、STM32F401REというマイコンに何本のタイマやタイマ類似のハードウエアが搭載されているのか以下の表にまとめてみました。分類すると4種類で合計12本です。

    • TIMxという名の汎用タイマ群。TIM1だけはAdvanced Control Timerと呼ばれているが基本は他のTIMと同様。合計8本。
    • watchdog(番犬)タイマ2本。
    • SysTickタイマ1本。
    • RTC(実時間時計)1本。
Name Type counter clk
TIM1 Adv. cont. 16bit APB2
TIM2 Gen. purpose 32bit APB1
TIM3 Gen. purpose 16bit APB1
TIM4 Gen. purpose 16bit APB1
TIM5 Gen. purpose 32bit APB1
TIM9 Gen. purpose 16bit APB2
TIM10 Gen. purpose 16bit APB2
TIM11 Gen. purpose 16bit APB2
Independent watchdog watchdog 12bit 32kHz Int.RC
Windows watchdog watchdog 7bit APB1
SysTick SysTick 24bit HCLK/8 or HCLK
RTC RTC RTC Int/Ext OSC.

TIMxのxに入る番号が飛んでますが、これはSTM32シリーズ内で番号と機能に一貫性を持たせているためだと思われます。他機種へ行ってもTIM4はTIM4のつもりで使えるのは良いです。他機種でTIM6使っていてもSTM32F401REではTIM6とまったく同じものは無い、ということも分かります。

Watchdogは2本もあります。Independent watchdogと呼ばれている方は、クロックをみるとわかりますが、内蔵の32kHz RC オシレータで動作している番犬のようです。他の信号源とはまったく無関係かつ内蔵発信器なので「最後の砦」として異常事態に備える目的用だと思います。一方、Windows watchdogの方は7ビット(ただし長周期のプリスケーラが付属)で、APBバスのペリフェラルクロック1で動作しているので、通常の異常などはこちらで検出させるものと思われます。

SysTickは、Armコアに付属のタイマです。RTOSが使用したりする高速クロックのタイマです。MicroPythonの内部でもシステムの動作のために使われているかもしれません。

最後のRTCは実時間時計です。ハードウエア・カレンダも搭載しているみたい。32kHzのオシレータでも駆動できますが、1MHzの高速クロックも使えるようです。なかなか高級。

MicroPythonのTimerモジュールで使用可能なのはTIMxの汎用タイマ群のどれかだと思われます。

タイマの使用状況の確認ソース

使用されているタイマにはクロックが供給されている筈なので、RCC(ResetとClockをControlするユニット)内の以下のレジスタを観察すれば、タイマの使用状況がわかると思われます。

    • RCC_CFGR、CLOCKソースの設定や分周比などを制御するレジスタ
    • RCC_APB1ENR、 APB1クロックの供給を制御
    • RCC_APB2ENR、 APB2クロックの供給を制御

前掲の表のclk欄をご参照いただけると、TIM2からTIM5の4本はAPB1クロック、TIM1とTIM9からTIM11の4本がAPB2クロックで動作しているとわかります。

ソースが以下に。ようやく stmモジュールが活躍。

#STM32: read GP Timer setting
import stm

def readRCC_CFGR():
    return stm.mem32[stm.RCC + stm.RCC_CFGR]

def readRCC_APB1ENR():
    return stm.mem32[stm.RCC + stm.RCC_APB1ENR]

def readRCC_APB2ENR():
    return stm.mem32[stm.RCC + stm.RCC_APB1ENR]

def decodePPRE(fieldval):
    ppre = "DIR"
    if fieldval == 4:
        ppre = "1/2"
    elif fieldval == 5:
        ppre = "1/4"
    elif fieldval == 6:
        ppre = "1/8"
    elif fieldval == 7:
        ppre = "1/16"
    return ppre

def decodeRCC_CFGR(regval):
    ppre2 = (regval & 0xE000) >> 13
    ppre1 = (regval & 0x1C00) >> 10
    sws   = (regval & 0xC) >> 2
    swsCLK="n/a"
    if sws == 0:
        swsCLK = "HSI"
    elif sws == 1:
        swsCLK = "HSE"
    elif sws == 2:
        swsCLK = "PLL"
    print("CFGR   : {0:08x}".format(regval))
    print("  SWS  : {0}".format(swsCLK))
    print("  APB1 : {0}".format(decodePPRE(ppre1)))
    print("  ABP2 : {0}".format(decodePPRE(ppre1)))  

def decodeAPB1ENR(regval):
    print("APB1ENR: {0:08x}".format(regval))
    if (regval & 0x1) != 0:
        print("  TIM2 En")
    if (regval & 0x2) != 0:
        print("  TIM3 En")
    if (regval & 0x4) != 0:
        print("  TIM4 En")
    if (regval & 0x8) != 0:
        print("  TIM5 En")
    if (regval & 0x800) != 0:
        print("  WWDG En")

def decodeAPB2ENR(regval):
    print("APB2ENR: {0:08x}".format(regval))
    if (regval & 0x1) != 0:
        print("  TIM1 En")
    if (regval & 0x10000) != 0:
        print("  TIM9 En")
    if (regval & 0x20000) != 0:
        print("  TIM10 En")
    if (regval & 0x40000) != 0:
        print("  TIM11 En")

def main():
    print("STM32F401RE GP CLOCK setting.")
    decodeRCC_CFGR(readRCC_CFGR())
    decodeAPB1ENR(readRCC_APB1ENR())
    decodeAPB2ENR(readRCC_APB2ENR())
    print("End of test.")

if __name__ == "__main__":
    main()
実機実行結果

実機実行結果が以下に。STM32IOread0Results0

STM32F401RE用にビルドしたMicroPythonの起動後デフォルト状態では、

    1. メインのクロックソースは内蔵PLLからのクロック
    2. APBバスに接続されているペリフェラルを制御する2つのAPBクロックはAHBバスクロックに対して4分周
    3. 汎用タイマ8本のすべてにクロックは供給されていない

という観察結果を得ました。ホントか?

まあ、これをみるとADのサンプリングに使うだけならどのタイマでも使えそうであります。勿論、MicroPythonのモジュールによってはタイマを使うものがあるハズなので、そのときはぶつからないタイマを選択しないとなりませんが。

MicroPython的午睡(80) STM32F401RE版、タイマ駆動でADサンプリング へ戻る

MicroPython的午睡(82) STM32F401RE版、タイマとPWM出力端子の関係 へ進む