MC9S08SH4シミュレータでTPM2の妙なふるまいを見つけた [CodeWarrior]
このレポートは、MC9S08SH4 の Full Chip Simulation で見つけた TPM2 モジュールの妙なふるまいに関するものです。
ギャング出力でPWMのエミュレーション
ギャング出力をPWM出力として使うには、ソフトウェア・エミュレーションのプログラムを書く必要があることがわかってきました。 そこで、 MC9S08SH4 マイコンに搭載されている二つのタイマモジュールのうちの一つ、 TPM2 モジュールのアウトプット・コンペア(OC)機能とオーバ・フロー(OVF)機能を使って、PWMをエミュレーションするプログラムを開発しました。
発想は、実に簡単です。 OVFイベントが発生したらギャング出力をセットし、OCイベントが発生したらギャング出力をクリアします。 双方のイベントとも割り込みにより受け取り、割り込みサービス・ルーチン(ISR)の中に処理を含めることができます。 その結果、ギャング出力には、PWM波形が出てくると期待されます。
お試しプログラム
プログラムを書いて、 CodeWarrior の "Full Chip Simulation" にかけてみました。
word count_tpm2ch0; // Timer count at TPM2CH0 word count_tpm2ovf; // Timer count at TPM2OVF void __interrupt VectorNumber_Vtpm2ch0 tpm2ch0_isr(void) { count_tpm2ch0 = TPM2CNT; TPM2C0SC_CH0F = 0; // clear channel flag } void __interrupt VectorNumber_Vtpm2ovf tpm2ovf_isr(void) { count_tpm2ovf = TPM2CNT; TPM2SC_TOF = 0; // clear overflow flag } void main(void) { TPM2SC_TOIE = 1; // Enable overflow interrupt TPM2SC_CPWMS =0; // Edge aligned TPM2C0SC_CH0IE = 1; // Enable channel 0 interrupt TPM2C0SC_MS0x = 1; // Output compare TPM2C0SC_ELS0x = 0; // software only TPM2C0V = 10000; // 50% duty TPM2MOD = 19999; // 20000 cycle TPM2SC_PS = 0; // 1X TPM2SC_CLKSx = 1; // bus clock EnableInterrupts; /* enable interrupts */ /* include your code here */ for(;;) { __RESET_WATCHDOG(); /* feeds the dog */ } /* loop forever */ /* please make sure that you never leave main */ }
PWMの動作を確認するための簡単なプログラムです。 二つの変数、 "count_tpm2ch0" と "count_tpm2ovf" には、それぞれタイマカウンタの 50% と 0% の値が入ることが期待されます。 シミュレーションの結果、期待されない妙な結果が大域変数ペインに表示されました。
count_tpm2ch0 17 unsigned int count_tpm2ovf 56 unsigned int
"count_tpm2ch0" が 0.0% を "count_tpm2ovf" が 0.3% を示しています。 どこがおかしいの?
妙なふるまい
ステップ動作シミュレーションによって、 "TPM2C0SC_CH0F" OC イベント・フラグの妙なふるまいが確認されました。 タイマ・カウンタの値がモジュロ値 (TPM2MOD - 1) から 0x0000 に戻るとき、 "TPM2SC_TOF" フラグがセットされるのと一緒に "TPM2C0SC_CH0F" フラグもセットされてしまいます。 その結果、割り込みベクタの優先順位に従って、 OVF イベントの ISR に先立って OC イベントの ISR が実行され、タイマ・カウンタから 0.0% の値を取り出します。 それから、 OVF イベントの ISR が 0.3% の値を取り出したのです。
加えて、タイマ・カウンタの値が 50% の値に達しても、 OC イベントは発生しませんでした。 このことから、 OC イベント・フラグをセットするロジックに不具合があるのではないかと思われます。
TPM1は、ちゃんと動く
MC9S08SH4 は、もう一つの TPM モジュール TPM1 を持っています。 TPM1 を使って同じプログラムを実行してみました。
word count_tpm1ch0; // Timer count at TPM1CH0 word count_tpm1ovf; // Timer count at TPM1OVF void __interrupt VectorNumber_Vtpm1ch0 tpm1ch0_isr(void) { count_tpm1ch0 = TPM1CNT; TPM1C0SC_CH0F = 0; // clear channel flag } void __interrupt VectorNumber_Vtpm1ovf tpm1ovf_isr(void) { count_tpm1ovf = TPM1CNT; TPM1SC_TOF = 0; // clear overflow flag } void main(void) { TPM1SC_TOIE = 1; // Enable overflow interrupt TPM1SC_CPWMS =0; // Edge aligned TPM1C0SC_CH0IE = 1; // Enable channel 0 interrupt TPM1C0SC_MS0x = 1; // Output compare TPM1C0SC_ELS0x = 0; // software only TPM1C0V = 10000; // 50% duty TPM1MOD = 19999; // 20000 cycle TPM1SC_PS = 0; // 1X TPM1SC_CLKSx = 1; // bus clock EnableInterrupts; /* enable interrupts */ /* include your code here */ for(;;) { __RESET_WATCHDOG(); /* feeds the dog */ } /* loop forever */ /* please make sure that you never leave main */ }
この場合、変数は期待通りの 50% と 0% の値を示していました。
count_tpm1ch0 10015 unsigned int count_tpm1ovf 17 unsigned int
これは、 TPM2 だけの不具合なのだろうと思われます。
プロジェクト・アーカイブ
興味があれば、サンプル・プロジェクトをお試しください。 ZIPファイルを得るには、これを"SH07.zip"という名前で保存します。
参考文献
HCS08 Unleashed: Designer's Guide to the HCS08 Microcontrollers
- 作者: Fabio Pereira
- 出版社/メーカー: Booksurge Llc
- 発売日: 2007/11/13
- メディア: ペーパーバック
コメント 0