1 概要
1-1 タイマーの機能
タイマーには大きく分けて 3種類あり。
ADTM = Advanced-control Timer:高度制御タイマー
GPTM = General-purpose Timer:汎用タイマー
BCTM = Basic Timer:基本タイマー
CH32V203K8T6,C8T6には ADTM = 1個、GPTM = 3個 のタイマーが有る
タイマーの種類と機能、タイマーNo対応表
機能の詳細は 203取説 他参照
ADTM = Advanced-control Timer:高度制御タイマー
GPTM = General-purpose Timer:汎用タイマー
BCTM = Basic Timer:基本タイマー
CH32V203K8T6,C8T6には ADTM = 1個、GPTM = 3個 のタイマーが有る
タイマーの種類と機能、タイマーNo対応表
| 項 目 | ADTM | GPTM | BCTM |
|---|---|---|---|
| 16ビット自動リロードカウンタ(アップカウントをサポート) | ○ | ○ | ○ |
| 16ビット自動リロードカウンタ(ダウン・アップダウンカウントをサポート) | ○ | ○ | -- |
| 16ビットプリスケーラ(分周比は1~65536の範囲で動的に調整可能) | ○ | ○ | ○ |
| 4つの独立した比較/キャプチャチャネル | ○ | ○ | -- |
| デッドゾーン時間をプログラム可能な相補出力 | ○ | ーー | -- |
| タイマー制御用の外部信号 | ○ | ○ | -- |
| サイクル決定後にタイマーを更新するための繰り返しカウンタ | ○ | -- | ーー |
| タイマーの出力信号をリセット状態または既知の状態にするためのブレーク信号入力 | ○ | -- | ーー |
| 複数モードでのDMA生成 | ○ | ○ | ○ |
| インクリメンタルエンコーダ | ○ | ○ | -- |
| タイマー間のカスケード接続と同期 | ○ | ○ | -- |
| CH32V203K8T6 タイマー数 | 1 | 3 | 0 |
| CH32V203C8T6 タイマー数 | 1 | 3 | 0 |
| CH32V307V タイマー数 | 4 | 4 | 2 |
| CK_INT APBx | 2 | 1 | 1 |
| TIM1 CH32V203K8T6,C8T6 有り | ○ | -- | -- |
| TIM2 CH32V203K8T6,C8T6 有り | -- | ○ | -- |
| TIM3 CH32V203K8T6,C8T6 有り | -- | ○ | -- |
| TIM4 CH32V203K8T6,C8T6 有り | -- | ○ | -- |
| TIM5 | -- | ○ | -- |
| TIM6 | -- | -- | ○ |
| TIM7 | -- | -- | ○ |
| TIM8 | ○ | -- | -- |
| TIM9 | ○ | -- | -- |
| TIM10 | ○ | -- | -- |
1-2 タイマーの接続代替機能GPIOとPinNo
Default alternate function
PinNo(CH32V203K8T6/H32V203C8T6)
CH1〜CH4 (チャネル)
タイマーの特定の機能に割り当てられる入出力チャネルです。
これらのチャネルは、主に以下の目的で使用されます。
ETR (External Trigger input)
PinNo(CH32V203K8T6/H32V203C8T6)
| TIM1 | TIM2 | TIM3 | TIM4 | |
|---|---|---|---|---|
| CH1 | PA8 (18/29) | PA0 (6/10) | PA6 (12/16) | PB6(29/42) |
| CH2 | PA9 (19/30) | PA1 (7/11) | PA7 (13/17) | PB7(30/43) |
| CH3 | PA10(20/31) | PA2 (8/12) | PB0 (14/18) | PB8(31/45) |
| CH4 | PA11(21/32) | PA3 (9/13) | PB1 (15/19) | PB9(--/46) |
| ETR | PA12(22/23) | PA0 (6/10) | ----------- | ---------- |
CH1〜CH4 (チャネル)
タイマーの特定の機能に割り当てられる入出力チャネルです。
これらのチャネルは、主に以下の目的で使用されます。
入力キャプチャ(Input Capture, IC):
外部イベント(例: パルス信号のエッジ)のタイミングを正確に捉えるために使用されます。
出力比較(Output Compare, OC)/ PWM生成:
特定のタイミングで出力ピンのレベルを変化させたり(OC)、パルス幅変調(PWM)信号を生成したりするために
使用されます。
外部イベント(例: パルス信号のエッジ)のタイミングを正確に捉えるために使用されます。
出力比較(Output Compare, OC)/ PWM生成:
特定のタイミングで出力ピンのレベルを変化させたり(OC)、パルス幅変調(PWM)信号を生成したりするために
使用されます。
ETR (External Trigger input)
・外部トリガー入力を意味します。
・タイマーの動作(例: 計数の開始、停止、リセット)を、内部クロックではなく外部信号によって制御するために
使用される専用の入力ピンまたは機能です。
・例えば、外部からの特定の信号が入力されたときにタイマーのカウントをリセットする、またはカウントを
開始/停止するといった制御が可能です。
これにより、外部イベントとタイマー動作を同期させることができます。
・タイマーの動作(例: 計数の開始、停止、リセット)を、内部クロックではなく外部信号によって制御するために
使用される専用の入力ピンまたは機能です。
・例えば、外部からの特定の信号が入力されたときにタイマーのカウントをリセットする、またはカウントを
開始/停止するといった制御が可能です。
これにより、外部イベントとタイマー動作を同期させることができます。
1-3 簡単なタイマーの使い方
今回2,3項でプログラムの例を記載していますが、下記の2通りを説明しています。
(1)2項で説明しているのは ポーリング処理
プログラム側でタイマーのフラグ(更新イベントなど)を定期的に確認(監視)して処理する方法をポーリング処理と言います。
(2)3項で説明しているのは 割り込み処理
タイマーのフラグ(更新イベントなど)が発生すると他のプログラム動作を中断してTIM2_IRQHandler関数を実行する手法を割り込み処理と言います。
(1)2項で説明しているのは ポーリング処理
プログラム側でタイマーのフラグ(更新イベントなど)を定期的に確認(監視)して処理する方法をポーリング処理と言います。
(2)3項で説明しているのは 割り込み処理
タイマーのフラグ(更新イベントなど)が発生すると他のプログラム動作を中断してTIM2_IRQHandler関数を実行する手法を割り込み処理と言います。
1-4 プログラム中の不明点
プログラムをして不明な点が有った。判れば追記していく。
1-4-1 TIM1_IRQnが無いのはなぜ
タイマー割り込みの初期化で
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn ; //TIM1_IRQnが無いのはなぜ
理由は判りませんでしたが、TIM1ではもっと細かく設定ができます。
TIM1とTIM2について調べた結果を一覧にした。
なおCH32V003とCH32V203ともに調べたので結果を記載します。(同じでした)
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn ; //TIM1_IRQnが無いのはなぜ
理由は判りませんでしたが、TIM1ではもっと細かく設定ができます。
TIM1とTIM2について調べた結果を一覧にした。
なおCH32V003とCH32V203ともに調べたので結果を記載します。(同じでした)
| 割込名 | 003 | 203 | 備考 | ||
|---|---|---|---|---|---|
| 1 | 2 | 1 | 2 | ||
| TIM*_IRQn | ○ | ○ | タイマーの汎用的な割り込み要求番号、またはすべてのタイマー関連割り込みをまとめて処理するデフォルトのハンドラ名です。 | ||
| TIM*_UP_IRQn | ○ | ○ | 更新イベント(Update Event)の割り込み要求番号です。タイマーのカウンタがオーバーフローまたはアンダーフローしたとき(周期が満了したとき)に発生します。 | ||
| TIM*_CC_IRQn | ○ | ○ | キャプチャ/コンペア(Capture/Compare)の割り込み要求番号です。特定のカウンタ値に達したとき(コンペア一致)や、外部信号のエッジを検出したとき(キャプチャ)に発生します。 | ||
| TIM*_TRG_COM_IRQn | ○ | ○ | トリガー(Trigger)およびコミutation(COM、相補出力の切り替え)イベントの割り込み要求番号です。他のタイマーとの同期(トリガー)や、PWM出力の安全な切り替えなどに使用されます。 | ||
| TIM*_BRK_IRQn | ○ | ○ | ブレーク(Break)イベントの割り込み要求番号です。モーター制御などでエラーが発生した際に、PWM出力を非常停止させるために使用されます。 | ||
2 ポーリング処理
2-1 動作概要
TIM2のフラグをメインプログラムの中で確認し処理する。
動作を見るため、PC6をオシロ入力3 線色赤、PC7をオシロ入力4 線色青 に接続して動作を確認する。
動作を見るため、PC6をオシロ入力3 線色赤、PC7をオシロ入力4 線色青 に接続して動作を確認する。
2-2 プログラム内容
2-3 補足説明
メインプログラム中の
while(1){
GPIO_WriteBit (GPIOC, GPIO_Pin_6, Bit_SET); // OSC3
TIM2->ATRLR = x-1;
を変化させた場合の波形
プログラム中の TIM_Time2.TIM_Period = count - 1;のcount値を1または TIM2->ATRLR = 0; にするとタイマーが動作しなくなる理由。
カウンタの更新イベントが発生しなくなる(または即座に発生し続けるが有効なカウント動作にならない)ため です。
主な理由は以下の通りです:
「0までカウント」の意味:
タイマーは、カウンタ(CNT)が TIM_Period で設定した値に到達した時に「更新イベント(Update Event)」を発生させ、CNTを0にリセットします。
TIM_Period = 1 の場合:0 → 1 → (更新/リセット) → 0 という 2ステップの動作になります。
TIM_Period = 0 の場合:0 → (更新/リセット) → 0 という動作を期待されますが、ハードウェアの仕様上、 0から0への遷移では正常なカウントアップ・比較動作が成立せず、タイマーが停止した状態、あるいは期待した割り込みが発生しない状態になります。
while(1){
GPIO_WriteBit (GPIOC, GPIO_Pin_6, Bit_SET); // OSC3
TIM2->ATRLR = x-1;
を変化させた場合の波形
x=4![]() |
x=1![]() |
カウンタの更新イベントが発生しなくなる(または即座に発生し続けるが有効なカウント動作にならない)ため です。
主な理由は以下の通りです:
「0までカウント」の意味:
タイマーは、カウンタ(CNT)が TIM_Period で設定した値に到達した時に「更新イベント(Update Event)」を発生させ、CNTを0にリセットします。
TIM_Period = 1 の場合:0 → 1 → (更新/リセット) → 0 という 2ステップの動作になります。
TIM_Period = 0 の場合:0 → (更新/リセット) → 0 という動作を期待されますが、ハードウェアの仕様上、 0から0への遷移では正常なカウントアップ・比較動作が成立せず、タイマーが停止した状態、あるいは期待した割り込みが発生しない状態になります。
3割り込み処理
3-1 動作概要
TIM2のタイマ割り込みを使用して90(us)ごとにPB3端子電圧が(Hi,Lo)変化するプログラムを作成する。
ダウンカウントモードを使用する。
3-2 プログラム内容
3-3 補足説明
注意:GPIOで補足説明したものはここでは説明はしない。(1) TIM2タイマ初期化
■TIM_TimeBaseInitのパラメータには
●Prescaler (プリスケーラ):
システムクロックを分周(分割)して、タイマーのカウントクロック周波数を設定します。
これにより、タイマーの分解能や最大カウント時間を調整できます。
これにより、タイマーの分解能や最大カウント時間を調整できます。
●Period (自動リロード値 ARR):
タイマーのカウンタがリセットされるまでの最大値(上限値)を設定します。
カウンタがこの値に達すると、通常はゼロに戻るか、更新イベント(割り込みなど)を生成します。
プリスケーラとピリオドの組み合わせにより、タイマー割り込みの正確な周期(時間)が決まります。
今回のプログラムで周期計算方法:
TIM_Prescaler = dv-1;
TIM_Period = count-1;
TIM2_Init(dv,count) 各最大数値(65535,65535)
計算方法: dv×count/SYSCLK(MHz) = (us)
カウンタがこの値に達すると、通常はゼロに戻るか、更新イベント(割り込みなど)を生成します。
プリスケーラとピリオドの組み合わせにより、タイマー割り込みの正確な周期(時間)が決まります。
今回のプログラムで周期計算方法:
TIM_Prescaler = dv-1;
TIM_Period = count-1;
TIM2_Init(dv,count) 各最大数値(65535,65535)
計算方法: dv×count/SYSCLK(MHz) = (us)
48 × 90 / 48 = 90 (us)
●Clock Division (クロック分割):
主に高度なタイマー機能(特にPWMのデッドタイム生成など)で使用される、内部クロックとサンプリングクロックの比率を設定します。
通常はデフォルト値(TIM_CKD_DIV1など)が使用されます。
『MounRiver Studioでプログラム』の『 2.18 ch32v20x_tim.h』を確認すると
/* TIM_Clock_Division_CKD */
#define TIM_CKD_DIV1 ((uint16_t)0x0000)
#define TIM_CKD_DIV2 ((uint16_t)0x0100)
#define TIM_CKD_DIV4 ((uint16_t)0x0200)
のモード(値)が有ることが判る。
通常はデフォルト値(TIM_CKD_DIV1など)が使用されます。
『MounRiver Studioでプログラム』の『 2.18 ch32v20x_tim.h』を確認すると
/* TIM_Clock_Division_CKD */
#define TIM_CKD_DIV1 ((uint16_t)0x0000)
#define TIM_CKD_DIV2 ((uint16_t)0x0100)
#define TIM_CKD_DIV4 ((uint16_t)0x0200)
のモード(値)が有ることが判る。
●Counter Mode (カウンタモード):
タイマーのカウントアップ、カウントダウン、またはセンターアラインモード(PWMなどで使用)といった動作方向を設定します。
『MounRiver Studioでプログラム』の『 2.18 ch32v20x_tim.h』を確認すると
/* TIM_Counter_Mode */
のモードが有ることが判る。
今回使用するのは、減算していくので、『TIM_CounterMode_Down』になる。
『MounRiver Studioでプログラム』の『 2.18 ch32v20x_tim.h』を確認すると
/* TIM_Counter_Mode */
|
#define TIM_CounterMode_Up ((uint16_t)0x0000) カウンタが0からTIM_Period値までカウントアップし、その後0に戻ります。一般的なタイマー動作やPWM生成に使用されます。 |
|
#define TIM_CounterMode_Down ((uint16_t)0x0010) カウンタがTIM_Period値から0までカウントダウンし、その後TIM_Period値に戻ります。 |
|
#define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020) #define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040) #define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060) カウンタが0からTIM_Period値までカウントアップした後、TIM_Period値から0までカウントダウンします。このモードは主に高度なPWM生成に使用され、特定のスイッチング周波数で音響ノイズを低減するのに役立ちます |
今回使用するのは、減算していくので、『TIM_CounterMode_Down』になる。
■TIM_ARRPreloadConfigとは
自動リロードレジスタ (ARR) のプリロード機能を有効または無効にするためのライブラリ関数です。
この関数の主な目的は以下の通りです。
ARRレジスタの更新タイミングの制御:
ARR (Auto-Reload Register) とは:
この関数の主な目的は以下の通りです。
ARRレジスタの更新タイミングの制御:
プリロード有効 (TIM_ARRPreloadConfig(TIMx, ENABLE)を設定) にすると、プログラムによってARRレジスタに新しい値が書き込まれても、その値はすぐにはタイマーの動作に反映されません。
新しい値はプリロードレジスタに保持され、実際のARRレジスタの値は、現在のタイマー周期が終了したとき(通常はタイマーの更新イベント発生時)に更新されます。
これにより、PWM出力のデューティ比やタイマー周期を滑らかに変更でき、グリッチ(意図しない瞬間的な変化)を防ぐことができます。
プリロード無効 (TIM_ARRPreloadConfig(TIMx, DISABLE)を設定) にすると、ARRレジスタに新しい値が書き込まれると、すぐにタイマーの動作に反映されます。
新しい値はプリロードレジスタに保持され、実際のARRレジスタの値は、現在のタイマー周期が終了したとき(通常はタイマーの更新イベント発生時)に更新されます。
これにより、PWM出力のデューティ比やタイマー周期を滑らかに変更でき、グリッチ(意図しない瞬間的な変化)を防ぐことができます。
プリロード無効 (TIM_ARRPreloadConfig(TIMx, DISABLE)を設定) にすると、ARRレジスタに新しい値が書き込まれると、すぐにタイマーの動作に反映されます。
ARR (Auto-Reload Register) とは:
タイマーがカウントアップまたはカウントダウンする際の最大値(または最小値)を設定するレジスタです。
この値に達すると、タイマーはリセットされるか、カウント方向を反転し、同時に更新イベントを生成することが多いです。
要約すると、TIM_ARRPreloadConfig関数は、タイマーの周期を動的に変更する際に、その変更が即座に反映されるようにするか(無効)、 次の周期の開始まで待機させるか(有効)を制御する役割を果たします。
この値に達すると、タイマーはリセットされるか、カウント方向を反転し、同時に更新イベントを生成することが多いです。
要約すると、TIM_ARRPreloadConfig関数は、タイマーの周期を動的に変更する際に、その変更が即座に反映されるようにするか(無効)、 次の周期の開始まで待機させるか(有効)を制御する役割を果たします。
(2) タイマーの更新イベントにより動作させた後の処理
イベントによる処理をした後にタイマーのイベントフラグをクリアする必要がある。
ループ内で使用する場合と割り込みで使用する場合の違いなどを記載する。
ループ内で使用する場合と割り込みで使用する場合の違いなどを記載する。
■各関数の役割
●TIM_ClearFlag(TIMx,クリア内容):
タイマーのステータスフラグ(SRレジスタ)を直接クリアします。主に「割り込みを有効にしていない状態(ポーリング制御)」で、イベントが発生したかどうかを監視し、確認後にその跡を消すために使用します。
●TIM_ClearITPendingBit(TIMx,クリア内容):
タイマーの割り込み保留ビット(ステータスフラグ)をクリアします。主に「割り込みハンドラ(ISR)内」で使用され、割り込み要求が完了したことをハードウェアに伝えます。
■TIM_ClearITPendingBit をクリアすると TIM_ClearFlag もクリアされるか?
クリアされる。
内部的な動作として、TIM_ClearITPendingBit は内部で TIM_ClearFlag と同じステータスレジスタ(SR)のビットを操作しています。WCHの標準ライブラリ(StdPeriph Driver)の実装では、TIM_ClearITPendingBit は単に TIM_ClearFlag を呼び出すか、あるいは全く同じレジスタ操作を行っているため、一方をクリアすればもう一方もクリアされた状態になります。
■使い分けの推奨
●メインループ内での監視:
TIM_GetFlagStatus と組み合わせて TIM_ClearFlag を使用します。●割り込み処理内:
可読性と作法として TIM_ClearITPendingBit を使用します。3-4 結果
90(us)毎にHi-Loを繰り返している。 OK !


