H8/3052F 同士の簡単な通信についての問題

このQ&Aのポイント
  • H8(A)側は正しく駆動し、タクトスイッチを押すと、計測を開始するとともに5Vの信号が出力できています。
  • 問題はH8(B)側で、H8(B)のボードの電源を入れた直後から、H8(A)の信号を待たずに計測を開始してしまいます。
  • なぜ、H8(B)は電源を入れたとたんに駆動を開始してしまうのでしょうか?もしお分かりになる方がいらしたら、ご教授願います。
回答を見る
  • ベストアンサー

H8/3052F 同士の簡単な通信についての問題

秋月製マイコンボード(マザーボードも秋月製です)、H8/3052F(以下H8)につきまして質問があります。 なお開発環境にはベストテクノロジーのGDLを使用し、C言語にてプログラムを行ってます。 現在、2枚のH8を連動させて動かすことを試みています。 目的としましてはH8を物理量の計測に使用しています。 私のとった手法は、以下の通りです。 1、H8の、ある汎用ポート同士を1本の信号線で繋ぐ 2、片方のH8(仮にH8(A)とします)のマザーボード付属のタクトスイッチを押す。これを合図にH8(A)は計測を開始し、それと同時にH8(A)の汎用ポートから信号が出力される。 3、もう片方のH8(仮にH8(B)とします)はH8(A)からの出力があるまで待機し、出力を検知すると計測を開始する。 プログラムの内容としましては、以下のようにしました。 ※H8(A)の入力検知用のタクトスイッチは、ポート4のビット4についています。また信号の出力はポート1のビット0です。 ※H8(B)の入力検知用のポートはポート4のビット0です。 ※両ボードともに同一の安定化電源から電源を取っているので、グランドは共有できていると思います。 <H8(A)側のmainプログラム> /*ポート定義****/ P4.DDR = 0; /*ポート4のタクトスイッチを入力に設定。押すと0、何もなしで1*/ P4.PCR.BYTE = 0xff; /*ポート4を全ビットプルアップ。*/ P1.DDR = 0xff; /*P1を出力に設定*/ /*****************/ /*スイッチ入力待機部分*********/ while(P4.DR.BIT.B4); /*タクトスイッチが押されるまで、待機*/ P1.DR.BIT.B0 = 1; /*P1のビット0から5V信号を出力、別のH8(B)に信号を送る*/ /******************************/ (~以下、計測プログラム部へ) <H8(B)側のmainプログラム> /*ポート定義****/ P4.DDR = 0; /*P4端子を入力に設定。信号入力で0、何もなしで1*/ P4.PCR.BYTE = 0xff; /*ポート4を全ビットプルアップ。*/ /*****************/ /*スイッチ入力待機部分*********/ while(P4.DR.BIT.B0); /*P4のビット0にH8(A)からの信号入力があるまで、待機*/ /******************************/ (~以下、計測プログラム部へ) 以上のようなプログラムを組みました。 H8(A)側は正しく駆動し、タクトスイッチを押すと、計測を開始するとともに5Vの信号が出力できています。 問題はH8(B)側で、H8(B)のボードの電源を入れた直後から、H8(A)の信号を待たずに計測を開始してしまいます。 最初はH8(B)のポート4ビット0の初期値に0が入っており,いきなりwhile文を抜けてしまうのかと思いました. そこで,H8(A)からの信号線を外しますと、ずっと計測待機状態に入るのでプログラム的には一応回っているようです。 (私の認識では,ハードウェアマニュアルによればポート4の初期値は全ビット0ですが,MOSプルアップをすることにより,全ビット1に反転する(?)と考えています) 次に,H8(A)側から予期せぬ信号が入力されているのかと思い,テスターで電圧を測ってみました. しかし,タクトスイッチ入力前は0Vで,入力後は5Vが出力されており,見かけ上は問題がなさそうでした. なぜ、H8(B)は電源を入れたとたんに駆動を開始してしまうのでしょうか? もしお分かりになる方がいらしたら、ご教授願います。

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

  • ベストアンサー
  • Ponta00
  • ベストアンサー率75% (3/4)
回答No.1

H8(A)で以下のように操作すると、P10にはHigh(5V)が出力されますよね? >P1.DR.BIT.B0 = 1; /*P1のビット0から5V信号を出力、別のH8(B)に信号を送る*/ それをH8(B)で待っているとのことですが、以下の条件ではH/Lが逆ではないでしょうか? >while(P4.DR.BIT.B0); /*P4のビット0にH8(A)からの信号入力があるまで、待機*/ H8(A)がHighを出力するまで待ちたいのであれば、H8(B)は以下の条件で待たなければいけないと思います。 while( 0 == P4.DR.BIT.B0 ); /*P4のビット0にH8(A)からの信号入力(High)があるまで、待機*/ H8(A)側のポートが0V(Low)に引っ張っているため、while(P4.DR.BIT.B0); のループを抜けてしまうのではないかと。 条件を変更して確認してみてください。 あと、老婆心ながら以下の2点、アドバイスさせていただきますね。 (1)双方のH8が、お互いの準備が整ったかどうかを待ってから計測を開始したほうが良い。 (2)タクトスイッチの入力処理は、チャタリング除去の処理を行なった方が良い。

yaboo_us
質問者

お礼

お返事が遅れまして申し訳ありません. 大変,丁寧な助言をしてくださいまして,ありがとうございます. ご指摘の通り while( 0 == P4.DR.BIT.B0 ); と訂正しましたところ,正常に動きました. また,アドバイスも大変参考になりました. この2点についても,考慮させていただきます.

関連するQ&A

  • H8 3664Fのプログラム

    タクトスイッチのチャタリングを回避し、奇数回めのONで LEDの交互点灯を(タイマを使って) やろうとしていますが、なかなかうまくいきません。 入門者でお恥ずかしいですが、下記コードの誤りをご指摘頂けませんでしょうか? 宜しくお願い致します。 以下、コード。 #include <3664.h> //プロトタイプ宣言 void main(void); int SW_Read(void); // 入力SWの状態読み込み 関数 void wait(int); // nミリ秒待つウエイト 関数 void wait1ms(void); // 1ミリ秒待つウエイト 関数 void IOinit(void); // I/O の初期化 関数 void main(void) { if (SW_Read()==1) { IO.PDR8.BIT.B0 = 1; // ポート8のビット0を出力ON IO.PDR8.BIT.B1 = 0; // ポート8のビット1を出力OFF DI; // 割り込み禁止 TA.TMA.BYTE = 0x0A; // タイマーA、低速発信・0.25sec設定(タイマーのカウント開始) IRR1.BIT.IRRTA = 0; // タイマーA 検知フラグをゼロクリア IENR1.BIT.IENTA =1; // 割り込み許可 EI; // 割り込み許可 } else { } while(1) { } } /////////////////// I/Oの初期化 void IOinit(void) { IO.PCR8 = 0x03; // ポートコントロールレジスタ: ポート8のビット0・1を出力に設定 // その他のビットは入力に設定 IO.PDR8.BIT.B0 = 0; // ポート8のビット0を出力OFF IO.PDR8.BIT.B1 = 0; // ポート8のビット1を出力OFF IO.PCR1 = 0x00; // ポートコントロールレジスタ: ポート1を全ビット0とし、入力に設定 } /////////////////// タイマーA関数 void int_timera (void) // タイマーA関数 { IO.PDR8.BIT.B0 = ~IO.PDR8.BIT.B0; // ポート8のビット0を反転して出力(赤)LED用 IO.PDR8.BIT.B1 = ~IO.PDR8.BIT.B1; // ポート8のビット1を反転して出力(緑)LED用 IRR1.BIT.IRRTA = 0; // タイマーA検知フラグをゼロクリア } /////////////////// スイッチの状態読み込み int SW_Read(void) { int sw1; //スイッチ状態読み込み1回目 int sw2; //スイッチ状態読み込み2回目 int val; //スイッチの状態判定値の入力値 int memval; //入力信号の全回の値 int numcnt; //奇数偶数判定ループ用カウンタ while(1) //モニタリング { sw1 = IO.PDR1.BIT.B7; // スイッチの状態読み込み1回目 wait(10); // 10mS待つ sw2 = IO.PDR1.BIT.B7; // スイッチの状態読み込み2回目 memval=val; //現行のスイッチ状態判定値をメモリに入れ替える if(sw1==1 & sw2==1) // スイッチ読み込み1回目と2回目共にONだったら { //スイッチ状態判定を<押した>と見なして、 val=1; } else { val=0; } if(memval==0 & val==1) //パルスの前後状態を比較し、新規に立ち上がりONであれば、 { numcnt=++numcnt; if(numcnt%2!=0) //ループカウンタが奇数だったら { return(1); // 1を返す } else { } } else { } } } //////////////////// nミリ秒待つウェイト関数 void wait(int time) { int i; // ループカウンタ for(i = 0 ; i < time ; i++) // time回数分ループ wait1ms(); // 1ミリ秒のウェイト関数を呼び出す } //////////////////// 1ミリ秒待つウェイト関数 void wait1ms(void) { int i; // ループカウンタ for(i = 0 ; i < 2662 ; i++); // 1ミリ秒の間ループする } 以上、宜しくお願い申し上げます。

  • H8/3052F/IRQを使った割り込み

    こんにちは。 H8/3052F C言語でプログラミングしています。 H8をはじめて約半年がたった者です。 ITUを使ったサーボ制御やAD変換など、いろいろ勉強してきました。 しかしながらまだまだ未熟な者です。 今回割り込みに挑戦しています。 IRQ0を使いスイッチ入力があるとLED点滅パターン変更のプログラムに成功し、ITUと組み合わせてサーボを割り込みで制御できるまで勉強、実験していました。 最終的に成功し、しばらく動かしていたのですが、割り込みがきかなくなってしまいました。 IRQ0が駄目なのか?と仮定してIRQ1でプログラミングし、試したところ無事割り込みできました。 しかしIRQ1も割り込みが急にできなくなってしまいました。 書き込みし直しても直りません。 回路として、本などを参考にIRQ0のポート→マイクロスイッチ→GND という形で接続しています。 もしかしたらIRQ0の時はスイッチがB接点でしばらく繋がったままだったかもしれません。 また、この回路だと動作も少し不安定?なようです。 上記の回路で間違いはありませんか? 一応プログラムを載せておきます。 もし間違いがあったらお願いします。 #include <3048.h> void wait (void) { long t=200000; while (t--); } void int_irq0(void) { int c=3; INTC.ISR.BIT.IRQ0F = 0 while(c--){ P5.DR.BYTE = 0x5; wait(); P5.DR.BYTE = 0xa; wait(); INTC.ISR.BIT.IRQ0F = 0; } } int main(void) { DI; INTC.ISCR.BIT.IRQ0SC = 0; INTC.IER.BIT.IRQ0E = 1; P5.DDR = 0xff; EI; while (1) { P5.DR.BYTE = 0xff; //点灯 wait (); //待ち P5.DR.BYTE = 0; //消灯 wait(); //待ち } } 以上よろしくお願いします。

  • H8/3048 マイコンボードについて

    初心者の質問ですみません。 今、H8/3048のマイコンを使っていろいろやってみようと思っています。 マザーボードにP1の出力をLEDで表示できるような回路を組み、スイッチを押すとLEDを光らせるようなプログラムを作成し、実際に光らせることはできたのですが、A/D変換機能が使えません。 プログラムはネット上のサンプルプログラムを参考にしたので間違ってはいないと思うのですが、うまく変換されません。 入力電圧はきちんとAN0に入ってますし、ICやソケット部も拡大鏡で確認しましたがショートしている様子もありません。 これは故障してしまったのでしょうか? 何かの拍子に何処かがショートしてAD変換機能のみが壊れるというような事はあるのでしょうか? 非常に困っています。 どなたか回答よろしくお願いいたします。 ちなみにこのようなプログラムです。 #include <3048.h> void main(void){ int ad_data; P1.DDR = 0xff; P4.DDR = 0x00; P4.PCR.BYTE = 0xff; AD.ADDRA = 0; P1.DR.BYTE = 0xff; AD.ADCSR.BYTE = 0x33; while(AD.ADCSR.BIT.ADF == 0){} while(1){ if(P4.DR.BIT.B4 == 0){ ad_data = AD.ADDRA>>8; } P1.DR.BYTE = ad_data & 0xFF; } }

  • フローチャートについて

    H8マイコンでスイッチS1(PORT4-4)が押された場合は、LED1(PORT5-0)、スイッチS2(PORT4-5)が押された場合は、LED2(PORT5-1)、スイッチS3(PORT4-6)が押された場合は、LED3(PORT5-2)、スイッチS4(PORT4-7)が押された場合は、LED4(PORT5-3)が、それぞれ点灯するようなプログラムをつくりました。 #define P4DDR (* (volatile unsigned char *) 0xfffc5) #define P4DR (* (volatile unsigned char *) 0xfffc7) #define P4PCR (* (volatile unsigned char *) 0xfffda) #define P5DDR (* (volatile unsigned char *) 0xfffc8) #define P5DR (* (volatile unsigned char *) 0xfffca) int main(void) { unsigned char sw,ssw; P4DDR = 0x00; /* P4全ビットを入力に設定 */ P4PCR = 0xff; /* P4 MOSプルアップをONにする */ P5DDR = 0xff; /* P5全ビットを出力に設定 */ while (1) { sw = ~P4DR; /* 入力を反転 */ ssw = sw >> 4; /* swを4ビット右にシフトしたものをsswに代入 */ P5DR = ssw; /* sswをP5に出力 */ } return 0; } というプログラムを作ったのですが、フローチャートがどのようになるのかがわからないです。またプログラムが間違っていたら教えてください。

  • H8/3664FのAD変換について

    初めまして。 現在大学でH8/3664FでのAD変換を行っているのですが、 AD変換とその値に対する出力への動作が上手くいきません。 分かる方、ご教授お願いいたします。 現状は、1.7V程度の信号をADコンバータ端子(AN1)に入力しています。 AD変換を行い、条件として1V以上のときは出力に設定した 端子(P11)から5V出力しダイオードを光らせようと思っています。 プログラムは以下のように組んでいます。 おかしいところがあればご指摘お願いします。 void main(void){ IO.PMR1.BYTE=0x00; /* ポート1入出力ポート*/ IO.PCR1=0xff; /* ポート1出力*/ /*AD変換の初期設定*/ AD.CSR.BIT.ADST=0; /*AD変換機能停止*/ AD.CSR.BIT.SCAN=1; /*スキャンモード*/ AD.CSR.BIT.CKS=1; /*高速変換*/ TW.TCRW.BIT.CCLR=1; /* TCNTがGRAでクリア */ TW.TCRW.BIT.CKS=3; /* クロックφ/8 */ TW.GRA=40000; /* パルスの周期20ミリ秒 */ TW.TMRW.BIT.CTS=1; /* カウントスタート */ while(1){ /* 20ミリ秒間のカウントは約8880となる. */ if(TW.TSRW.BIT.IMFA==1){ TW.TSRW.BIT.IMFA=0; AD.CSR.BIT.ADST=1; /*AD変換機能開始*/ while(AD.CSR.BIT.ADF==0){}; /*AD変換終了待ち*/ AD.CSR.BIT.ADF=0; /*変換終了フラグクリア*/ AD.CSR.BIT.ADST=0; /*AD変換機能停止*/ x0=(int)(AD.DRA>>6); /*x0に値を格納*/ if(x0>100){/*1V以上の場合*/ IO.PDR1.BIT.B2=1; }else{ IO.PDR1.BIT.B2=0; }

  • H8/3048F IRQポートを使った外部割込みについて

    秋月電子のH8/3048Fマイコンボードを購入し、C言語による組み込みプログラムの演習を行っていて、マイコンボードのIRQ端子を使った外部割込みを実装しようとしてつまずいてしまいました。 メインループでLED点灯などの処理を行い、タクトスイッチの押下があったら別の処理を割り込ませ、またもとの処理に戻るという外部割込み処理を行いたいのですが、うまくいきません。 今おきている問題としては、 (1)電源の投入して、メインの処理(LED点灯)が行われる前になぜか一度IRQ割り込みが発生し、別処理が行われ、その後メインの処理を行う。 (2)IRQポートには立下り割り込み処理を行いたいので、プルダウン抵抗回路を組み、通常状態では、 IRQポート→チャタリング防止用のシュミットトリガ74LS19(NOT回路が含まれている)→10KΩの抵抗器→GND という回路でHIGH状態からタクトスイッチによる押下が行われたら、 0.1μFのコンデンサ→+5V という回路につながり、LOWになって、立下りエッジが検出され、割り込み処理が行われるはずだが、タクトスイッチを押下してもなかなか反応せず、5~6回押さないと割り込みが行われない。 (3)割り込み処理実行後、元の処理に戻らない。(このとき、タクトスイッチ押下による割り込み処理は再度受け付けてくれる) の3点です。 C言語関連のH8マイコンの教材は無く、Web上の情報でしか勉強していないので、必要な知識が欠けているかもしれませんが、どなたかお知恵を貸していただけないでしょうか? 当方のH8/3048Fによるプログラミング暦は1ヶ月ほどで、LEDの制御、外部スイッチ入力による処理等基本的なことは出来ていると思います。 メイン処理と割り込み処理のソースコードを載せておきます。 void int_irq0() //割り込み処理関数 { /* lcd_init(); lcd_locate(0,0); lcd_print("ワリコンダYO!"); wait(500); lcd_locate(0,0); lcd_print("モトニモドルYO!"); */ P5.DR.BIT.B0 = 1; wait(300); P5.DR.BIT.B0 = 0; wait(300); INTC.ISR.BIT.IRQ0F = 0; //ISRフラグをクリアする } void main(void){ //char moji[16] = "AKI-H8"; unsigned int rand_seed = 100; P1.DDR = 0x00; P5.DDR = 0xff; PB.DDR = 0xff; INTC.ISCR.BYTE = 0; INTC.ISCR.BIT.IRQ0SC = 1; //立下りエッジで割り込み検出 INTC.IER.BIT.IRQ0E = 1; EI; srand(rand_seed); timer_init(); /* タイマーの初期化 */ lcd_init(); /* 液晶表示器の初期化 */ lcd_locate(0,0); /* カーソル位置の指定 */ lcd_print("スイッチオセ!"); /* 文字列の表示 */ while(1){ //disp_data(); led_randset(); wait(100); led_allclr(); wait(10); } /* 無限ループ */ }

  • H8-3048F

    H8-3048Fで 信号の立ち上がりから立下りまでの 時間を計測するというのは可能でしょうか? 可能であれば、ぜひそのプログラムの構成のようなものを 教えていただきたいです。 お願いします。

  • AVRマイコンでのアップダウンカウンターについて

    以下のプログラムはポートDの6番にタクトスイッチを付けてカウントアップさせるプログラムですが、 ポートDの5番にもう1つタクトスイッチを付けてカウントダウンさせたいのですがどのようにプログラムを 追加したら良いでしょうか? 変更前 #include <avr/io.h> int main( void ) { volatile uint16_t i; uint8_t cnt,s0,s1; cnt=0x0;    /* カウント値の初期値=0 */ s1=0b01000000; /* 最初は押されていない状態をセット */ DDRB=0xff; /* PortBをすべて出力に設定する PortDはデフォルトで入力設定 */ PORTD=0b01000000; /* 入力設定になっているポートにHを書くとプルアップされる */ for (;;) { /* 無限ループ */ PORTB=cnt; /* カウント値ををPortBに出力 */ s0=s1; /* 前回のデータを保存して */ s1=(PIND & 0b01000000); /* ポートBと01000000のandをとるとB6の0/1だけがs1に代入される */ if(s0>s1){ /* 前回=64(off) 今回=0(on)のときswが押されたと判断 */ cnt++; /* カウントをインクリメント */ } } } よろしくお願いします。

  • H8/3052について

    こんにちは。 現在秋月書店のH8/3052のマイコンを使ってイエローのC言語で 声の周波数を調べるという卒研をやっています。 声の周波数を調べるためにA/D変換を使ってやろうと思っていますが、 エラーが出ました。その前に周波数を調べられるかそうかはまだわかりませんが・・・。エラーの内容は 未定義のシンボルです DDR でした、 あと、周波数を調べるため、A/D変換するためのポートはP7でよろしいでしょうか? 皆さんのご指摘お願いいたします。 プログラムの一部を載せます。 #include <3048F.H> #define E_SIG 0x20 #define RS_SIG 0x10 void ioinit(void) { P7.DDR = 0xff; //ポート3を全ビット出力に設定 } void adinit(void) { AD.CSR.BIT.ADF = 0; //ADFフラグクリア AD.CSR.BIT.SCAN = 0; //単一モード選択 AD.CSR.BIT.CKS = 1; //クロックセレクト AD.CSR.BIT.CH = 0; //チャネルセレクト AN0単一モード } です。よろしくお願いします。

  • PIC アセンブラ ポートB 内部プルアップ抵抗の使い方

    PIC16F877Aを使っています。 プログラムを作り始めてかなりたってから ポートBにプルアップ用の抵抗があることを知りました。 それで使い方とか調べてみたんですが ポートBで内部プルアップを使う場合は RBを全部入力設定にしないといけない的な事を 書いてるページがありました。 これって、そうしないとPICが壊れてしまうって事でしょうか? RB0~RB3にタクトスイッチ(入力) RB4~RB7に7セグのカソード(出力) として入出力を混ぜて使いたいのですが スイッチ用にポートBをプルアップ抵抗ONにしても問題ないでしょうか?