SH7144でパルス幅を測定する方法

このQ&Aのポイント
  • SH7144でPIOに接続された信号のパルス幅を測定する方法について説明します。
  • H8-3048のサンプルプログラムを参考にして、SH7144への変更方法を教えてください。
  • 初心者向けに具体的な手順を教えていただけると助かります。
回答を見る
  • ベストアンサー

SH7144でパルス幅を測定したい。

マイコン初心者です。 SH7144でPIOに接続された信号のパルス幅を測定したいです。 ネットで検索をしてH8-3048のサンプルプログラムを見つけたのですが、 SH7144への変更のしかがたが分かりません。 どなたか分かる方がいましたらお教えください。 初心者ですので、具体的に教えていただけると助かります。 ちなみに、下記がネットで見つけたH8-3048でのプログラムです。 宜しくお願いいたします。 /* メイン関数************************************************/ int main(void){ long counter; P1.DDR = 0xff; // port1出力に設定 表示LED PA.DDR = 0x00; // portA入力に設定 パルス入力用 ITU1.TCR.BYTE = 0x23; // GRAインプットキャプチャ,カウンタクリアGRA clock 1/8 ITU1.TIOR.BYTE = 0xCD; // GRA立下り,GRB立ち上がりインプットキャプチャ ITU.TSTR.BIT.STR1 = 0; // カウント停止状態 while(1){ while(PA.DR.BIT.B4 == 0){} // 入力パルス立ち上がり検知 ITU.TSTR.BIT.STR1 = 1; // ITU1 TCNTカウント開始 while(ITU1.TSR.BIT.IMFA == 0){} // GRAキャプチャ,パルス立下り検知 ITU1.TSR.BIT.IMFA = 0; // フラグをクリア ITU.TSTR.BIT.STR1 = 0; // ITU1 TCNTカウント停止 counter = ITU1.GRA; // カウント値の取得 P1.DR.BYTE = counter >> 4; // 8bitシフトさせP1に表示 } }

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

  • ベストアンサー
  • pyonmae
  • ベストアンサー率64% (40/62)
回答No.2

こんにちは。 > TIOC1A(PE4)に接続するのではなくて、 > PF7などの汎用の入力で行いたいのです。 > そもそも、そういったことはできないのでしょうか? できます。むしろ、手法としてはその方が簡単です。 ただし精度は落ちますし、そもそものサンプルプログラムの意味がほぼ無くなりますが。 その場合、おおまかな流れは以下のようになるかと思います。 ・MTUを初期化する ・MTUのTCNTをクリアする。カウントはストップのまま。 ・PF7が1になるのを待つ ・MTUカウンタをスタートする。 ・PF7が0になるのを待つ ・MTUカウンタをストップする。 ・TCNTの値を読む → これがパルス幅

その他の回答 (1)

  • pyonmae
  • ベストアンサー率64% (40/62)
回答No.1

こんにちは。 サンプルプログラムの仕様は、 ・パルス信号をTIOCA1(PA4)から入力 ・タイマカウンタはクロックの8分周(元のクロック数は不明) ・レジスタにはパルスの立ち下がり→GRA、立ち上がり→GRBに  キャプチャするように設定しているが、実際は立ち上がりを  PA4ポーリング、立ち下りをGRAインプットキャプチャしている。  (パルスのHi期間を測定) ・取得したパルス幅を、1/16してP1(LED?)に表示する。 てな感じだと思います。 このサンプルプログラムを参考にするならば、パルス信号線はTIOCxxに接続されている必要があります。 接続していれば、変更は、H8-3048のITU1を、SH7144のMTUxに置き換えるだけです。 最も楽に変更を終えたいなら、パルス信号線はTIOC1A(PE4)に接続するのが良いです。 TIOC1Aにつないでいれば、  PA4 → PE4  ITU1 → MTU1 と置き換えられますので、両者のデータシートを首っ引きで見比べて、レジスタの 設定を置き換えていけば、動作すると思います。(多分) あまり深く見ていないので分かりませんが、相手がSH7144ですと、 ・PFC ・モジュールスタンバイ 辺りにも注意する必要があるかも知れません。

GACHAPINA
質問者

お礼

ご回答ありがとうございます。 TIOC1A(PE4)に接続するのではなくて、 PF7などの汎用の入力で行いたいのです。 そもそも、そういったことはできないのでしょうか? 素人質問ですみません。

関連するQ&A

  • SH7144で汎用入力のパルス幅を測定したい。

    マイコン初心者です。 SH7144で汎用入力のパルス幅を測定したいです。 どなたか分かる方がいたら教えてください。 下記の様にプログラムしてみたのですが、timは、"0"となってしまいます。 他にも何か設定が必要なのでしょうか? または、汎用入力をトリガにタイマーを使用することはできないのでしょうか? ====================================================== unsigned short tim; // 設定 MTU1.TCR.BYTE = 0x03; // カウンタクリア禁止,内部CLK=PΦ/64 MTU.TSTR.BIT.CST1 = 0; // カウント停止 MTU1.TCNT = 0; // カウントクリア // タイマスタート MTU.TSTR.BIT.CST1 = 1; // カウント開始 // パルス監視(HIGHを測定) while(!PF.DR.BIT.B7); // TRG=H while( PF.DR.BIT.B7); // TRG=L // タイマー停止 MTU.TSTR.BIT.CST1 = 0; // カウント停止 tim = MTU1.TCNT; // カウント値取得 ======================================================

  • AKI-H8/3048Fでのタイマ割り込み

    秋月電子で http://akizukidenshi.com/catalog/items2.php?p=1&q="K-00004" を買いマイコンの勉強をしています。 コンパイル等はGCC Developer Lite、モニタプログラムを使いRAM上で 動作確認をしています。 タイマによる割り込みをしたいと思い、参考書のプログラムを参考に マザーボード上の2つのLEDが交互に光るようにしたいのですが、 肝心のint_imaia0()が全く実行されていません。 #include <3048.h> int c; void int_imia0( void ) { ITU0.TSR.BIT.IMFA = 0; c -= 1; if( c == 0 ){ P5.DR.BYTE = ~ P5.DR.BYTE; c = 10; } } int main( void ) { c = 10; P5.DDR = 0x03; ITU0.TCR.BIT.CCLR = 1; ITU0.TCR.BIT.TPSC = 3; ITU0.GRA = 39999; ITU.TSTR.BIT.STR0 = 1; P5.DR.BYTE = 0x01; EI; while( 1 ){ } } また、割り込みを使わない方法ということで #include <3048.h> int main( void ) { int c = 10; P5.DDR = 0x03; ITU0.TCR.BIT.CCLR = 1; ITU0.TCR.BIT.TPSC = 3; ITU0.GRA = 39999; ITU.TSTR.BIT.STR0 = 1; P5.DR.BYTE = 0x01; while( 1 ){ while( !ITU0.TSR.BIT.IMFA ); c -= 1; if( c == 0 ){ P5.DR.BYTE = ~ P5.DR.BYTE; c = 10; } ITU0.TSR.BIT.IMFA = 0; } } を試したのですが、こちらはLEDが交互に点滅して成功しています。 なのでタイマ自体は動作していると思うのでですが、上のプログラムだと int_imaia0()動作しません。 何がいけないのでしょうか?よろしくお願いします。

  • モータの制御

    //ステッピングモータの回転 //右に2回転、停止、左に1回転、停止これを3回繰り返す //ITUO使用、フラグが立つのを待つ //10msごとにモータに出力 //str_4.c #include <3048f.h> void ioinit(void) { PB.DDR = 0xff; } void ituinit(void) { ITUO.TCR.BIT.CCLR = 1; //カウンタクリア要因 ITUO.TCR.BIT.TPSC = 3; //タイマプリスケーラ 25MHz/8=3.125MHz ITUO.GRA = 31249; //3.125MHz/31250=100Hz、10ms、100pps ITUO.TIER.BIT.IMIEA = 0; //IMFAフラグによる割り込み禁止 } void wait(void) //停止時間 { Long t=200000; while(t--); } int main(void) { int i = 3; //繰り返しカウンタ int p; //回転パルス数 int md = 0x11; //モータ出力データ ioinit(); ituinit(); PB.DR.BYTE = md; wait(); ITU.TSTR.BIT.STR0 = 1; //タイマスタート while(i--){ for(p=0;p<96;p++){ //2回転 PB.DR.BYTE = md; md <<= 1; //右回転 if(md == 0x110) //4回シフトしたかの判断 md = 0x11; //4回シフトで初期値に戻す while(!ITU0.TSR.BIT.IMFA); //フラグが立つのを待つ ITU0.TSR.BIT.IMFA = 0; //フラグクリア } wait(); //少し停止 for(p=50;p>0;p--){ //1回転、1パルス多くした PB.DR.BYTE = md; md >>= 1; //左回転 if(md == 0x08) //4回シフトしたかの判断 md = 0x88; //4回シフトで初期値に戻す while(!ITU0.TSR.BIT.IMFA); //フラグが立つのを待つ ITU0.TSR.BIT.IMFA = 0; //フラグクリア } wait(); } PB.DR.BYTE = 0x00; //モータ励磁OFF while(1); //ここでとまっている } このプログラムのフローチャートがわかりません。

  • H8を利用したPWMのパルス生成について

    最近H8のマイコンを使い始めた者です。 PWMモードの波形を出力するプログラムを作っているのですが、出力波形が出ない事に困っています。 自分が作成したプログラムを以下に示しますので、 詳しい方いましたら、アドバイス頂けたらと思います。 よろしくお願いします。 #include <tlib.h> #include "3069S.h" const unsigned ptn[] = {4000, 16000, 2000, 10000}; unsigned long pos; unsigned long x; int main() { int i=1; pos=0; ITU.TSTR.BIT.STR0=0; //タイマのカウントを停止。 ITU0.TCR.BYTE=0x43; //GRBのコンペアマッチでクリア。1/8クロック ITU0.GRA=10000; //パルス幅を入力(5ms) ITU0.GRB=20000; //周期を入力(10ms) ITU.TMDR.BIT.PWM0=1; //ITU0をPWMモードに設定。 ITU.TSTR.BIT.STR0=1; //タイマのカウントをスタート while(1){ if(ITU.TISRB.BIT.IMFB0){ x=ITU.TISRB.BIT.IMFB0; ITU.TISRB.BIT.IMFB0=0; ITU0.GRA=ptn[pos]; pos++; pos &= 0x03; } } }

  • H8のITUトグル出力で 0出力で停止したい

    ルネサス製H8/3052Fを使用しています。ITUを通常動作で使用して、GRAコンペアマッチでTIOAC端子からトグル出力を行う際にタイマを停止するとTIOACの出力レベルが 0 で停止してほしいのですが、停止した際に 0/1 どちらの状態になるかコントロールできずに困っています。 試しに、「タイマを停止するときにコンペアマッチで0出力を一度させてから停止する」という方法を使ってみたのですが、結果は変わりませんでした。以下、そのソースコードを記載します。どうやったらタイマ停止後に TIOCAの出力レベルを 0 にできるかアドバイスをいただけますようお願いします。 -------------------------------------------- #define ITU4_setBRA(val) ITU4.BRA = val // コンペアマッチによりBRAの値をGRAに自動転送 void ITU4_init(void){ ITU4.TCR.BIT.CCLR = 1; // GRAのコンペアマッチでTCNTをクリア ITU4.TCR.BIT.CKEG = 0; // 立ち上がりエッジでカウント ITU4.TCR.BIT.TPSC = 3; // φ/8 ITU4.TIOR.BIT.IOA = 3; // GRAコンペアマッチでトグル出力 ITU.TFCR.BIT.BFA4 = 1; // BRA4をGRAのバッファレジスタとして使用 ITU4.TCNT = 0; } void ITU4_start(void) { ITU4.TCNT = 0; ITU.TSTR.BIT.STR4 = 1; } void ITU4_stop(void) { int i; // 一度 GRAコンペアマッチで 0 を出力させてから、トグル出力に戻す。 ITU.TSTR.BIT.STR4 = 0; // カウント停止 ITU4.TIOR.BIT.IOA = 1; // GRAコンペアマッチで0出力 ITU4.GRA = 1; ITU4.BRA = 1; ITU.TSTR.BIT.STR4 = 1; // カウント開始 for(i=0; i<32; i++) ; // 無駄時間ループ ITU.TSTR.BIT.STR4 = 0; // カウント停止 ITU4.TIOR.BIT.IOA = 3; // GRAコンペアマッチでトグル出力 }

  • 32×16ドットLEDマトリクス表示装置をCで動かしたい!

    AKI-H8-3048/Fを使って32×16ドットLEDマトリクス表示装置を動かそうとしています。以前投稿して、そのときの意見やいろんなサイトを参考にCでプログラムを作ってみましたが動きません。 ↓が作ったプログラムです。 #include <3048f.h> #include <stdio.h> /* 待ち時間発生初期化 ************************************/ void timer_init(void){ ITU0.TCR.BYTE = 0x23; ITU0.GRA = 0x07d0; ITU.TSTR.BIT.STR0 = 0; return; } /* 待ち時間発生 引数に、必要なミリ秒を指定する***********/ void wait(int msec){ int i; ITU.TSTR.BIT.STR0 = 1; for(i=0;i<msec;i++){ do{ }while(ITU0.TSR.BIT.IMFA == 0); ITU0.TSR.BIT.IMFA = 0; } ITU.TSTR.BIT.STR0 = 0; return; } /* 表示 ********************************************/ void print(void){ int a=0; int sin1[16]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; int sin2[16]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; int sin3[16]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}; while(1){ P1.DR.BIT.B0 =0; wait(100); P1.DR.BIT.B0 =1; wait(100); P1.DR.BIT.B4 =1; for(a=0;a<=16;a++){ P1.DR.BIT.B2 =sin1[a]; P1.DR.BIT.B1 =sin2[a]; P1.DR.BIT.B3 =sin3[a]; } } return; } /* メイン関数 ********************************************/ void main(void){ timer_init(); /* timerの初期化 */ P1.DDR = 0x1f; /* port1出力に設定 */ print(); } 何が違うのかわからないのでご指摘をお願いします。

  • タイマーが動作しません

    H8/3052を使っていろいろ動作させようと考えてます、 タイマー割り込みのところで詰まっていますが、タイマー割り込みを使ってLEDを反転するというプログラムです。 結果、LEDが反転しないつまり、タイマー割り込みが動作してないのではないかと考えています。 うちが使いたいタイマーはウオッチドッグタイマです。イエローで、C言語を使っています。 皆様の知識をお借りしたいです。 //20msごとに割り込み、50回の割り込みでLED点灯反転 #include <3048.h> //3048、3052の内部I/O定義 #include <sysio.h> int c; //割り込み回数、外部変数とする //ITUインターバルタイマ割り込み void int_imia0(void) { ITU0.TSR.BIT.IMFA = 0; //割り込みステータスフラグクリア c-=1; if(c==0){ P5.DR.BYTE = ~P5.DR.BYTE; //LED出力データを反転 c=50; } } int main(void) { P5.DDR = 0xff; ITU0.TCR.BIT.CCLR = 1; //カウンタクリア要因 ITU0.TCR.BIT.TPSC = 3; //タイマプリスケーラ25MHz/8=3.125MHz ITU0.GRA =62499; //3.125MHz/62,500=50Hz、周期20ms ITU0.TIER.BIT.IMIEA = 1; //IMFAフラグによる割り込み許可 ITU.TSTR.BIT.STR0 = 1; //タイマスタート P5.DR.BYTE = 0xff; //LED出力データ初期値 c=50; //割り込み回数 _ei(); //割り込み許可 while (1); //何もしない } 動作できない為、ご指摘よろしくお願いします。

  • 【H8-3052F】タイマ割り込み

    C言語もマイコンも初心者ですので情報が不足していたら笑って指摘してください。 今はルネサスのHigh-performance Embedded Workshop(Version 4.04.01.001)を使用してタイマ割り込みを実現しようとしてますが、タイマが動作しません。 出力結果も繰り返し処理が正常に動いてないように見えます。 原因等わかる方いらっしゃいましたら教えていただけますでしょうか。 可能でしたらソースコードもつけていただけると幸いです。 ---出力結果--- H8/3052F Monitor v1.12 Copyright (C) 1999-2004 CSE Tomakomai NCT 1:ld 1:go 00ffe000 change job wooooooooo! w ---ソースコード--- #include "3052f.h" #include "utility.h" #pragma interrupt ( aaa ) int cnt; extern void initITU( void ); void aaa() { debugString( "aaa!" ); cnt++; } void main(void) { InitializeSCI(); setDebugMode( true ); initITU(); // タイマーを初期化 ITU0.GRA = 20000; // タイマでカウントする値の設定 ITU0.TCNT = 0; // Reset ITU0.TCNT ITU.TSTR.BIT.STR0 = 1; // タイマ スタート debugString( "change job" ); while( 1 ){ if(cnt == 50){ debugString( "here we go!" ); cnt = 0; } else { debugString( "wooooooooo!" ); } } } void initITU() { ITU.TSNC.BIT.SYNC0 = 0; // 他チャンネルとの同期無し(独立動作) ITU.TSNC.BIT.SYNC1 = 0; // 他チャンネルとの同期無し(独立動作) ITU.TSNC.BIT.SYNC2 = 0; // 他チャンネルとの同期無し(独立動作) ITU.TSNC.BIT.SYNC3 = 0; // 他チャンネルとの同期無し(独立動作) ITU.TSNC.BIT.SYNC4 = 0; // 他チャンネルとの同期無し(独立動作) ITU0.TCR.BYTE = 0x03; // クロックの1/8で動作。TCNTのクリア禁止 ITU1.TCR.BYTE = 0x03; // クロックの1/8で動作。TCNTのクリア禁止 ITU2.TCR.BYTE = 0x03; // クロックの1/8で動作。TCNTのクリア禁止 ITU3.TCR.BYTE = 0x03; // クロックの1/8で動作。TCNTのクリア禁止 ITU4.TCR.BYTE = 0x03; // クロックの1/8で動作。TCNTのクリア禁止 ITU0.TIOR.BYTE = 0; // GRの制御。0x00でよい。 ITU1.TIOR.BYTE = 0; // GRの制御。0x00でよい。 ITU2.TIOR.BYTE = 0; // GRの制御。0x00でよい。 ITU3.TIOR.BYTE = 0; // GRの制御。0x00でよい。 ITU4.TIOR.BYTE = 0; // GRの制御。0x00でよい。 ITU0.TIER.BIT.IMIEA = 1; // 全割り込み許可(オーバーフロー/IMFA/IMFB) ITU1.TIER.BIT.IMIEA = 0; // 全割り込み禁止(オーバーフロー/IMFA/IMFB) ITU2.TIER.BIT.IMIEA = 0; // 全割り込み禁止(オーバーフロー/IMFA/IMFB) ITU3.TIER.BIT.IMIEA = 0; // 全割り込み禁止(オーバーフロー/IMFA/IMFB) ITU4.TIER.BIT.IMIEA = 0; // 全割り込み許可(オーバーフロー/IMFA/IMFB) }

  • H8 3052について

    マイコン、電気回路初心者です。 h8 3052で回転計を作製をしたいのですが・・・知識を貸していただきたいです マイコン初心者です。。。 h8 3052で回転計を作製をしたいのですが・・・知識を貸していただけたら幸いです。 回転数を算出の式として次を用いたいと思います(精度はあまり気にしないでください。。。) 回転数[rpm]=60[sec]/1回転に要する時間[sec] リードスイッチとマグネット4つを使い回転数を算出したいと思っています。 リードスイッチが4つカウントしたときの時間(1回転に要する時間)を上の式の分母(t)に入れ演算させたいです。 ITUのタイマー割り込みを使い分母の時間をカウントをしカウントが4のときt=0と考えてました。 しかし、カウントを迎えてもtは永遠に1ずつ足され続け0に戻りません。 プログラムの考え方が違うのでしょうか? 使用環境からロータリーエンコーダ、フォトトランジスタなどが使えません。 チャタリングについては、本からRC積分回路(0.1μFとVccに10KΩ)使い、そこからさらに74HC04通してつかっているのですが・・・見よう見まね状態です。 開発環境はHEWを使っています。 勉強不足だと思いますが、10日くらい悩んでいます。力を貸してください。よろしくお願いします。 僕が立てたプログラムは次の通りです。 vector 12 IRQ0 (リードスイッチ 立下りエッジで割り込み要求) __interrupt(vect=12) void INT_IRQ0(void) { count++; INTC.ISR.BIT.IRQ0F=0; } vector 28 IMIA1 __interrupt(vect=28) void INT_IMIA1(void) { ITU1.TSR.BIT.IMFA = 0; taco_interrput-=1; if(taco_interrput==0) { t++; } taco_interrput=1; } void main() {   set_imask_ccr(1); //割り込み禁止   INTC.ISCR.BIT.IRQ0SC=1; //タコメータ 入力立下りエッジで割り込み発生   INTC.IER.BIT.IRQ0E=1; //IRQ0割り込み許可(タコメータ)        ITU1.TCR.BIT.CCLR=1; //ITU1カウンタクリア要因  ITU1.TCR.BIT.TPSC=3; //ITU1 3.125MHz  ITU1.GRA=3125-1; //ITU1 3.125MHz/3125=1000Hz、周期1ms(0からカウントされるため必ず-1)  ITU1.TIER.BIT.IMIEA = 1; //ITU1 IMFAフラグによる割り込み許可  ITU.TSTR.BIT.STR1=1; //ITU1タイマスタート  taco_interpput=1; //ITU(imia)割り込み回数1 割り込み先で1に戻るので無限  while(1)  {   if(count==4)    {     time=t;     t=0;     count=0;     n=60[sec]/time;    }   if(count>4) //カウントが4より大きくなってしまったとき    {     t=0;    count=0;    }  } } (LCDのプログラムは長いので省きました) LCDの液晶を使い以下のことは確認をしています。 ・カウントが4を迎えたときカウントは0に戻っています。(IRQのカウントのことです) ・カウントを何回与えてもtが0に戻りません。なので演算されてないです。(tは永遠に1ずつ足され続けてます) 回転数の使う範囲は50~200rpmです。 tのカウントを0に戻す記述をどうしたいいのかよろしくお願いします。

  • Tera Termを使ったマイコンとの通信

    H8/3048Fと通信をしようと思い、「Tera Term」を使ってみたのですが、 下のプログラムを実行してもTera Termに何も表示されません(COMの番号はしっかり確認しました) while( 1 ){ ITU0.TCNT = 0; while( ITU0.TCNT < 40000 ); counter++; if( counter > 100 ){ if( P4DR == 0x00 ){ //LEDを点滅させる(確認用) P4DR = 0x10; } else{ P4DR = 0x00; } while( ( SCI0.SSR.BYTE & 0x80 ) == 0 ); SCI0.TDR = 'A'; //Aを送信する SCI0.SSR.BYTE &= ~0x80; counter = 0; } } SCI0の設定は int i; SCI0.SCR.BYTE = 0x00; SCI0.SMR.BYTE = 0x00; SCI0.BRR = 51; for( i = 0 ; i < 1000 ; i++); i = SCI0.SSR.BYTE; SCI0.SSR.BYTE = 0x80; SCI0.SCR.BYTE = 0x30; となっております。 このプログラムを実行すると確認用のLEDは点滅しますが、Tera Termには何も表示されません。 どこか間違っているところなどがあれば教えていただけないでしょうか? ちなみに、使用しているOSはWindows7です。 よろしくお願いします。

専門家に質問してみよう