« 開発環境をWindows7に移行 | トップページ | ココログブログの見栄え向上 »

STM32 Primer2のSysTickタイマー周期設定

SysTickタイマーはSTM32 MCUが持つ機能で、OSがタスク切り替えを行う契機として使用します。PrimerのCircleOSでは、SysTickタイマー周期毎にタスクを切り替えるのではなく、SysTickHandlerに登録された以下の関数群を毎回実行します。

  • BUTTON_Handler: ボタンの状態取得
  • POWER_Handler: バッテリー状態の取得と表示
  • RTC_DisplayTime: 時刻の取得と表示
  • MENU_Handler: メニュー表示の更新とアプリケーションの起動。
    加えて、SysTick周期100回毎にユーザーアプリケーションの本体部分(Application_Handler)を実行する
  • その他の周期処理

CircleOSにてSysTickタイマーをどのように設定しているかを調べてみました。

CircleOSにおけるSysTickタイマー周期

以前の記事「STM32 Primer2」の末尾に示す通り、タイマー周期はMCUのクロック設定に連動して変化します。例えば24MHz動作の場合、SysTick周期 = 1ms、Application_Handler呼び出し周期 = 100msとなります。

SysTick制御レジスターの動作

SysTick制御レジスタのフィールド定義と動作を以下に示します。「Cortex-M3 テクニカルリファレンスマニュアル(Rev.G)」をベースに、STM32固有の部分(太字・斜体)を追記してみました。

1)SysTick制御レジスタ

Bit フィールド名称 機能
2 CLKCOURCE
(SysTickタイマーのクロックソース)
0: 外部参照クロックを使用
STM32ではAHBクロック(=HCLK)の1/8を供給する(STM32 Ref Manual 4.2章より)
1: コアクロックを使用
STM32ではAHBクロック(HCLK)を使用する
1 TICKINT 1: 0 までカウントダウンすると、SysTick ハンドラを保留する → 割り込みを生成すると理解
0: 0 までカウントダウンしても、SysTick ハンドラを保留しない → 割り込み生成しない
0 ENABLE 1: カウンタはマルチショット方式で動作
0: カウンター無効

2)SysTick リロード値レジスタ

Bit フィールド名称 機能
0-23 RELOAD カウンタが0になったときに、SysTick現在値レジスタにロードする値 → タイマー周期を指定する

SysTick制御レジスターの設定

CircleOSの初期化時に、SysTick_Configuration()関数にて設定を行っています。コードは以下の通りです(CircleOS V3.80のscheduler.cより抜粋)。5行目のSysTick_CLKSourceConfig()はSTM32F10x標準ライブラリ(以下STライブラリ)の関数です。パラメーター名よりCLKCOURCE = 0を設定することが分かります。

14行目のSysTick_Config(SystemFrequency / 500)では、SysTickリロード値レジスタを、SystemFrequency(12MHz) / 500 = 24000に設定しています。

void SysTick_Configuration( void )
    {
    /* Configure SysTick to generate an interrupt @1.5MHz (with HCLK = 36MHz) */
    /* Select AHB clock(HCLK) as SysTick clock source */
    SysTick_CLKSourceConfig( SysTick_CLKSource_HCLK_Div8 );
    //SysTick_SetReload( 3000 );

    /* Enable SysTick Counter */
    //SysTick_CounterCmd( SysTick_CTRL_ENABLE );

    /* Enable SysTick interrupt */
    //SysTick_ITConfig( ENABLE );
    
    if (SysTick_Config(SystemFrequency / 500)) /* SystemFrequency is
                defined in system_stm32f10x.h and equal to HCLK frequency */
        {
        /* Capture error */
        while (1);
        } 
    }

SysTick_Config()は、CMSISファイルcore_cm3.hで定義されたインライン関数でコードは以下です。

static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{ 
  if (ticks > SYSTICK_MAXCOUNT)  return (1);   /* Reload value impossible */

  SysTick->LOAD  =  (ticks & SYSTICK_MAXCOUNT) - 1;   /* set reload register */
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for System Interrupts */
  SysTick->VAL   =  (0x00);                    /* Load the SysTick Counter Value */
  SysTick->CTRL = (1 << SYSTICK_CLKSOURCE) | 
                  (1<<SYSTICK_ENABLE) | 
                  (1<<SYSTICK_TICKINT);        /* Enable SysTick IRQ and SysTick Timer */
  return (0);                                  /* Function successful */
}

SysTick_Config()の中で、リロード値レジスタの設定(5行目)に加えて、CLKSOURCEを1に再設定しています(8行目)。また割り込みの有効化をここで行っています(9~10行目)。すなわち、最終的なSysTickタイマーの設定条件は以下となります。

  • SysTickカウンターをカウントダウンするクロックはMCUのコアクッロク(18~72MHz)  (CLKCOURCE = 1)
  • SysTickタイマー割り込み有効
  • カウンターのリロード値は24000

上記設定により、冒頭に示したとおり、クロック周波数24MHz時のSysTickタイマー周期は1msとなります。
   SysTickタイマー周期 = 24000000Hz / 24000 = 1000Hz

SysTick割り込み発生回数をカウントするプログラムを作って動かしてみると、確かにクロック24MHzでは、1秒間に1000回割り込みが発生することが分かります。

PS: SyntaxHighlighter for Windows Live Writerを使ってソースコードのフォーマットを行ってみました。使い方が分からず結構苦戦。このページが昨晩から何回も消えたり・見えたりしていた筈です。

« 開発環境をWindows7に移行 | トップページ | ココログブログの見栄え向上 »

STM32-ARM」カテゴリの記事

コメント

この記事へのコメントは終了しました。

2018年10月
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
無料ブログはココログ