• ベストアンサー

SH7144のMTU割り込みについて

マイコン初心者です。 現在SH7144の勉強を行っているのですが、MTUによる割り込みが上手くできずに困っています。 開発環境はGCC Developer Liteになります。 下記にソースを示します。 #include<7144.h> void initIO(void) { PFC.PECRL2.WORD = 0x0000; //ポートEの7~0を入出力に設定 PFC.PEIORL.WORD = 0xffff; //ポートEの15~0を出力に設定 } void initMTU(void) { MST.CR2.BIT._MTU = 0; //MTUモジュールスタンバイの解除 MTU0.TSR.BIT.TGFA = 0; //TGFAフラグクリア MTU0.TCR.BYTE = 0x22; //TGRAのコンペアマッチでクリア //PΦ/16でカウント=1562.5kHz MTU0.TMDR.BYTE = 0xC0; //TGRA通常動作 MTU0.TIER.BYTE = 0x41; //MTU0のTGIEAコンペアマッチで割り込み MTU0.TGRA = 1562; //パルス周期設定(1562.5kHz/出力周波数1kHz=1562回) INTC.IPRD.BIT._MTU0G = 15; //割り込み要因MTU0のTGIプライオリティ15 MTU.TSTR.BIT.CST0 = 1; //MTUカウンタ動作開始 } void int_tgi0a(void) { static int d = 1; MTU0.TSR.BIT.TGFA = 0; //TGFAフラグクリア PE.DRL.BIT.B0 = d; //PE0に出力 d = ~d; //dの値を反転 } void main(void) { initIO(); initMTU(); while(1); } プログラムはMTU0のTGIEAコンペアマッチで割り込み、PE0の出力を反転する動作を考えて書きました。 ご教授の程をお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • anzu-k
  • ベストアンサー率66% (2/3)
回答No.2

あなたの記述したものが、上記ソースで全てであるならば、 1つ気付いたことがあります。 SH2にはSRレジスタと言うものがありますが、SR内のI0bitからI3bitの初期値(リセット直後)は"1111"となっています。 つまり、割込みマスクが最大の状態ではじまるので、割込みがすべて弾かれます。 通常マイコンは、リセット直後にて、一部(NMI等)を除き割込みが全て禁止状態になっている場合が多いです。 これは単に割込み許可やらレベルやらのレジスタだけではなく、 SH2ならば上記のように割込みマスクが最大レベルになっていたり、 マイコンによっては全割込みを制御できる1つのフラグにより、禁止されていたりします。 (また、1箇所で全割込みをコントロールできると何かと便利なのですよ。) あなたのやったように初期化コードで割り込みレベルや割り込み許可を設定した後に、全割り込みを許可してやります。 コントロールレジスタを書き換えるので、インラインアセンブラを使用しなければならないかもしれません。 ストア命令で(STC ?)I0bitからI3bitを0にしてやれば良いかと思います。 #define _EI() __asm("stc ほにゃらら")__ /*割り込み許可(EnableのEとInterruptのIです)*/ #define _DI() __asm("stc ほにゃらら")__ /*割り込み禁止(DisableのDです)*/ のようにマクロにしているのをよく見ますし、私もそうしたりします。 ただ、gccでインラインアセンブラを使ったことがないので、「ほにゃらら」部分は分かりません。 何かのサンプルプログラムやどこかのサイトにあるかも知れないので探してみて下さい。 (誰かズバリ回答してくれるのを願ってます。インクルードされている"7144.h"の中にあったらいいですね。) とかいている最中に、回答があったようですね。set_imask(0)がそうだと思います。 私はSH2も使用したことがなければ、GCCでの組み込みプログラミングもしたことがありません。 しかしながら、H8やM16C、M32C等のマイコンのプログラミング経験はあります。 また何故か7144のデータシートを持っていたり…。 勉強がてら、クイズだと思って答えてみました。参考になれば幸いです。

maa_teru
質問者

お礼

貴重なアドバイスありがとうございました。 貴重なアドバイスの3割位しか理解できなかった自分自身にちょっと脱力、anzu-kさんのご回答を読んだ後、ハードウェアマニュアルで再度勉強しました。 SH2の割込みを使う為には、下記三点の手順を踏む必要があるということと理解しました。 (1)SRレジスタのI0bit~I3bitマスクを解除 (2)INTCレジスタでプライオリティレベルを設定 (3)MTUなど各機能ごとに割り込み要因を設定 今回の問題では(1)が抜けていたということで、set_imask(0)を探したら見つからないよどうしよう・・・orz インラインアセンブラも分らないよ(泣)どうしよう・・・orz などとやっているうちに"7144.h"の中にSetSRReg()というものを発見! なんとか割込みできるようになりました。 ありがとうございました。

その他の回答 (3)

  • anzu-k
  • ベストアンサー率66% (2/3)
回答No.4

ANo.2の訂正です。本当に済みません。 STCではなくLDCでした。 割り込み許可するためには、例えば asm(" ldc $0x0,sr "); とすればいいのかも知れません。

  • anzu-k
  • ベストアンサー率66% (2/3)
回答No.3

度々申し訳ありません。 ANo.2の補足です。今後のための補足です。 今のところ必要ないかも知れませんが、色々な割り込みレベルを使用した多重割り込みを使用する場合、 EI()で、SRレジスタをスタックに積んでから、SRレジスタのI0からI3bitを"1111"にして、 DI()では、逆にスタックに積んだものをSRレジスタに戻すっていう方法なんかもありますよ。 (もちろんEIとDIの呼出は対になってないととんでもないことになりますが…) こうすると、割り込みハンドラ内など、割り込みレベルに関わらず使えます。 しかし、SH2ってPUSH命令とPOP命令がなさそう(そうだったのか!)だから、 通常のスタックポインタがどのレジスタなのかどうかで、インラインアセンブラのやり方がかわりそうですね。 つまり、コンパイラに依存しそうです。

  • R32C
  • ベストアンサー率39% (115/290)
回答No.1

調べ方ですが、ルネサスの「アプリケーションノート」という分類で サンプルドキュメントが公開されています。 らしいものを探して、なにが 違うか比較するといいと思います。 ざっとみたところ、サンプルと違う部分として、 P_MTU0.TIORH_0.BYTE = 0x00; set_imask(0); // これはGDLだと EI; だったと思う。 がないみたいだと思いました。

maa_teru
質問者

お礼

貴重なアドバイスありがとうございます。 ルネサンスのHPでアプリケーションノート見つけました。 ヽ(´▽`)ノYYヽ(´▽`)ノ・・・ルネッサ~ンス set_imask(0);がうまく見つけられなかったのですがヘッダーファイル"7144.h"の中にset_imask(0)と近い記述のSetSRReg()を見つけ、なんとか割込みできるようになりました。 ありがとうございました。