So-net無料ブログ作成
検索選択

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

HCS08 Unleashed: Designer's Guide to the HCS08 Microcontrollers

  • 作者: Fabio Pereira
  • 出版社/メーカー: Booksurge Llc
  • 発売日: 2007/11/13
  • メディア: ペーパーバック

nice!(0)  コメント(0)  トラックバック(0)  このエントリーを含むはてなブックマーク#

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この記事のトラックバックURL:
※言及リンクのないトラックバックは受信されません。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。