• 締切済み

h8/3052 GDB-stub上でのプログラムの実行 ITUタイマ割込みの使用について

現在h8/3052でITUタイマを利用して20msecごとに割り込みがかかるようにするプログラムを作成していますが、割り込みに関して動作が確認できません。デバッグ環境を整えるためにターゲットにはあらかじめGDB-stubを書き込んであります。 実際に作成しているプログラムの割込みの部分は、 //割込み処理関数 pragma interrupt void int_imia0(void) //割り込み関数 { extern volatile unsigned int count; count ++; ITU0.TSR.BIT.IMFA = 0; } で割り込みが行われたときの処理を行い。 //メイン関数内 EnableInterrupt(); //割り込み許可 StartITU0(); //タイマスタート while (1){ AD.CSR.BIT.ADST = 1; /*変換スタート*/ while (AD.CSR.BIT.ADF == 0); /*変換終了待ち*/ data[c] = AD.DRA >> 6; /*下位へ6ビット分ずらす*/ data[c] = data[c] & 0x3ff; /*上位6ビットクリア*/ time[c] =(count * 2000000) + (ITU0.TCNT * 32); /*A/D変換処理時間の算出*/ if(time[c]>20000000) { bleak; } } のようにして、ここで20msecごとに割り込みがかかるように設定しています。 で、出力ファイルの //MAPファイル Name Origin Length Attributes vectors 0x00220000 0x00000100 r rom 0x00220100 0x00007f00 xr ram 0x00228000 0x00007000 xrw stack 0x0022f000 0x00001000 rw vectorアドレス ITU0割込みベクタアドレス(0x220060) 0x00220060 0x4 LONG 0x22020a DEFINED (_int_imia0)?<code 340> (_int_imia0):<code 340> (_start) として、外部RAM領域に設定したvectors領域のベクタ領域に割込み関数のアドレスが入るようにしています。 実際に動かすと、割込み関数でブレークポイントを設定しても割り込みがかからずにプログラムが動かなくなってしまいます。(どこかに飛んでいってしまっている。) ここで質問なのですが、GDB-stub上でプログラムを動かす場合に、 ・割り込みがかかった場合のベクタアドレスはGDB-stub側で設定しているベクタアドレス(内部ROM0x000060)に飛ぶようになってしまっているのか。 が、気になっています。

みんなの回答

  • bug_bug
  • ベストアンサー率78% (36/46)
回答No.3

> 仮想ベクタ領域にターゲットプログラムの割り込み関数のアドレスを書き込めばOKということであってるでしょうか。 OKです。 > 一応STUB側の仮想ベクタテーブルに、、、 3052に限らず300HコアにはVBR(ベクターベースレジスタ)がありませんので、モニタプログラムがソフトウェア的に仮想ベクタテーブルを実装してくれています。 ハード仕様に応じてどのエリアがRAM空間かは決まっておりませんのでユーザー個人個人で仮想ベクターテーブルをどこに置いたか、プログラム(B)のビルド時に指定してあげないといけません。 さらにプログラム(A)はモニタデバッグ用(RAM上で動く用)のセクション割付をおこなった上でビルドする必要があります。 本来動かしたい自作プログラムはROM上で動くことを想定していても、デバッグ時には外付けRAM上で動かしますので、すべての関数アドレスやベクタテーブル、静的変数あらゆるものがオフセット(サンプルの場合0x220000)が加算されたアドレスに配置されます。 自作プログラム上での静的変数の参照や関数のコールすべてがオフセット加算されたアドレスを参照しなければならなくなりますので、デバッグ用のセクション割付で対応します。 これに気づいていないと、ISRから別関数をコールしたら、なんかROM領域へジャンプしてるっ!ってことになりかねません。 この辺りが「難易度が全然違う」と記した理由です。 もし動作に問題が残っていたら、開発環境とモニタプログラムの入手元を補足してもらえれば具体的にお話できるかもしれません。

utaibito33
質問者

お礼

ベクタテーブルをSTUBを構築する際に、3052のRAM領域(0xFFFDF10)に設定したので、測定を行うプログラムのコンパイルの際のベクタアドレスをそこの部分に設定してあげたら、動作が確認できました。 ありがとうございます。 まだ、質問があって新しく質問を書きました。(H83052 ITUタイマ機能 時間の測定について)もしわかることがあれば、教えていただきたいです。

  • bug_bug
  • ベストアンサー率78% (36/46)
回答No.2

あてずっぽうですが、よくあるミスとして 各レジスタはしっかり設定したつもりだったけどITU0の割り込み優先度が初期値0のままでマスクされており、実は割り込みが発生してなかったなんてことはないでしょか?(IPRA2) 以下、駄文です。 一般的にモニタプログラムを利用する場合、デバッグ対象である作成プログラム(A)とは別に、コアとなるプログラム(B)を先にターゲットのROM上へ書き込む必要があります。 プログラム(B)は多くの場合、雛形が用意されていますので、それぞれのターゲットのハード仕様に応じて適切な設定値の変更を利用者個人個人で行い、ビルドする必要があります。 (RAM上に展開するデバック対象プログラムの各セクションのアドレス指定が必要。ベクタテーブルの設定もここに含まれる) ■割り込み発生後の流れ (1)3052はベクタテーブル固定で、プログラム(B)に記述された割り込みベクタがまず参照されます。 (2)プログラム(B)はRAM上にあるプログラム(A)のベクタテーブルを参照した上でISRをコールするようにコーディングされています。 (簡単に表現するなら、2段ジャンプするようなものです) 以上よりモニタプログラム環境構築で気をつける点べき点は、 (1)プログラム(B)を適切なマッピング情報を設定した上でビルドする (設定すべきマッピング情報はプログラム(A)がRAM上に展開された状態を想定) (2)モニタプログラム環境からプログラム(A)を想定しているRAM上に書き込む 加えて3052のタイマ割り込みを利用する上で気をつけるべき点は (1)ハードウェアマニュアルを参照し適切なITU関連レジスタ設定を行う (2)該当ITUの割り込み優先度を設定する(割り込みコントローラの設定) (3)CPUのCCR割り込みマスクを解除する(アセンブラ記述、又は開発環境のライブラリを利用) (4)タイマそのものをスタートさせる(タイマスタートレジスタの設定) サンプルとして提示頂いたコードではモニタプログラム環境に問題があるのか、タイマ割り込みを利用するためのレジスタ設定などチップの駆動方法に問題があるのか、ちょっと切り分けができないですね。 モニタプログラム環境の構築が初めてであれば、メーカー保証のROMへの書き込み回数を気にせず自作プログラムでCPUを直接駆動し、スタートアップ処理や割り込み駆動に問題がないことを動作確認した上でデバッグ環境構築にトライした方がスムーズに進むと思いますよ。(難易度が全然違う為)

utaibito33
質問者

お礼

親切な回答ありがとうございます。 STUB(モニタ)側で設定されている2段ジャンプの2段目に設定されている仮想ベクタ領域にターゲットプログラムの割り込み関数のアドレスを書き込めばOKということであってるでしょうか。 一応STUB側の仮想ベクタテーブルにターゲットプログラムの割り込み関数のアドレスを書き込むように設定したら、割り込みがかかるようになりました。

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.1

H8は専門外なんですが、ターゲットのプログラムのベクタテーブルのアドレスの設定が行われていないようなのですが大丈夫なんでしょうか? H8知らないので勘違いなら申し訳ない。

関連するQ&A

  • 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()動作しません。 何がいけないのでしょうか?よろしくお願いします。

  • H83052 ITUタイマ機能 時間の測定について

    現在h8/3052でITUタイマを利用して1msecごとに割り込みがかかるようにしてそのときにセンサで測定した値をA/D変換させるプログラムを作成しました。モニタプログラムのGDB-STUBをROM領域に書き込んでおりますので、GDBで実際にデバッグを行ってみました。 その結果、毎回の割り込みごとのA/D変換終了時のタイマカウントの値をその時の時間としてみているのですが、その時間間隔が正確に1msecではなく、タイマのカウントが最大で3クロック分くらいずれが生じてしまう結果になってしまいました。 タイマカウンタには、誤差は全くないと思いますので、他の原因として考えられるのはプログラムの部分でしょうか?A/D変換の変換開始のタイミングや、終了待ちの関係でしょうか。 その誤差の部分についてわかることがありましたら、ご回答よろしくお願いします。 必要であれば、プログラム内容も載せたほうがよろしいでしょうか。

  • H8を使ってモータを、正逆回転するプログラムについてです。 よろしくお

    H8を使ってモータを、正逆回転するプログラムについてです。 よろしくお願いします。 H8(3067F.h)を使って2.5Vを基準として、2.5Vより上5.0まで正転し、2.5V以下0Vなら逆転、2.5Vなら静止するプログラムを作成したいのですが正逆回転のところで困っています。 #include <3067F.h> #pragma interrupt(adi) void initITU(void); void initITU1(void); void initAD(void); void initPA(void); main() { initPA(); initAD(); initITU(); initITU1(); /* Initalize ITU ch1 */ ITU.TSTR.BIT.STR1 = 1; /* Start ITU ch1 */ AD.CSR.BIT.ADST = 1; /* A/D変換 start */ while(1){ ; } } void initPA(void){ PADDR = 0xff; /* PortA 出力モード */ PADR.BYTE = 0x00; /* PA Clear */ } void initAD(void){ AD.CR.BIT.TRGE = 0; /* AD変換外部トリガ開始禁止 */ AD.CSR.BYTE = 0x00; /* ADCSR初期化, ch0のみ */ AD.CSR.BIT.ADIE = 1; /* AD変換終了後割り込み */ AD.CSR.BIT.CKS = 0; /* AD変換時間 : 135ステート */ AD.CSR.BIT.SCAN = 0; /* 単一モード */ } void initITU(void) { ITU.TSTR.BYTE = 0x00; ITU.TSNC.BYTE = 0x00; ITU.TISRA.BYTE = 0x00; /* Disable Interruption */ ITU.TISRB.BYTE = 0x00; /* Disable Interruption */ ITU.TISRC.BYTE = 0x00; /* Disable Interruption */ } void initITU1(void) { ITU.TMDR.BIT.PWM1 = 1; /* CH1 PWM mode */ ITU1.TCR.BYTE = 0x20; /* clear GRA comparematch,1/clock */ ITU1.GRA = 0; /* A/D変換器の保証bitは上位8bit */ ITU1.GRB = 0; ITU1.TIOR.BYTE = 0X00; /* prohibit GRA&GRB'output of comparematch */ } void adi(void) { AD.CSR.BIT.ADST = 0; /* A/D変換停止 */ if(AD.DRA && 0x80) /* open */ { PADR.BIT.B1 = 1; PADR.BIT.B2 = 0; ITU1.GRB = (AD.DRA >> 8); } else{ (AD.DRA - 0x80) = 0 /* close */ PADR.BIT.B1 = 1; PADR.BIT.B2 = 0; ITU1.GRB = (AD.DRA >> 8); } AD.CSR.BIT.ADF = 0; AD.CSR.BIT.ADST = 1; /* A/D変換開始 */ }  プログラムは、このようになっています。 AD変換停止後のif文のあたりでコンパイルできなくなるのですがどうしたらいいでしょうか? お願いします。

  • 【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/OSを用いた割り込みで困っています。

    SH2-7045Fを用いて、MTUのTGRAとTNCTのコンペアマッチで割り込みを発生させたいのですが、かなり困っています。まず、MTUのTGRAの割り込みが発生したときの、割り込み関数の割り込み定義を、H8/OSにかいてあった、int_registでやっているのですが、これでいいのですか?あと、開発環境は、秋月でSH2を買ったときについてくるgccを使っていいるのですが、この中には割り込みマスクの設定の関数がないというのを知り、適当にインターネットから拾ったアセンブリ言語で書かれたようなもの(setIntmask())を書いているのですが、プログラムを動かしたとき割り込みを1度しか受け付けないでプログラムがおわらないで、なにかしています。教えてくださいお願いします。

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

    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 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に戻す記述をどうしたいいのかよろしくお願いします。

  • AKI-H83048で割り込みを使用してLEDを点滅させたいのですが、、、、

    はじめまして、組み込みソフト超初心者です。 割り込みタイマを使用してLEDを特定時間点滅させる、ということを行いたいのですが、コンパイルができず、頓挫しております。どなたか、アドバイス頂けませんでしょうか。 ・開発環境はAKI-H8 3048 ・割り込みを使用してLEDを点滅させるということを目的にCでソースをコーディングしています。 ・巷の参考書など参考にしてmain、割込関数、コーディングしました。 ・コンパイラはAKI-H8マイコンキットについてきた専用CコンパイラCC38Hを使用しています。(統合開発環境はありません) 上記の条件でコンパイルすると、interruptがイリーガルとエラーが出ます エラーの出ているコードは #pragma interrupt itu0_int(vect=24) の部分です。 参考書で、interruptはコンパイラによって使用できないようなことも読んだのですが、どうすればコンパイルできるのでしょうか、また、何が足りないのでしょうか なにぶん初心者なもので、正直質問の的が絞れていないのかも解らないのですが、とにかくまず動かしたいと思い質問させて頂きました。 同じ開発環境の方が居られましたら有難いです。 何とぞよろしくお願い致します。

  • Linux環境でC++のGDBを途中から実行したい

    初歩的な質問で申し訳ないのですが、 現在LinuxでGDBの勉強をしています。 LinuxでC++で組んだプログラムを実行する際に 1.gdb a.out 2. run でmainから起動し、<調べたいクラス>::<関数>にbreakpoint設定を行ってから cで飛ばしていたのですが、 起動時、またはrun時に調べたいクラスの関数からはじめるということは可能なのでしょうか? 拙い文章で申し訳ありませんがご存知の方ご教授お願いいたします。

  • H8/3048、AD/DA変換プログラムについて。

    H8/3048、AD/DA変換について質問です。 ポート7のAN0・AN1を入力に使い、DA0・DA1で出力される変換プログラムを作成して実験したところ AN0→DA0への変換は出力されたのですが、AN1→DA1への変換が出力できません。なぜ出力されないのかわかりません。 どうしたらいいか教えてください、お願いします。 AN0がDA1でも出力されているかと思いましたが違いました。 #include <no_float.h> #include <stdio.h> #include <machine.h> #include "h8_3048.h" void init (void); double get_ad0 (void); double get_ad1 (void); void out_da0 (double); void out_da1 (double); void wait (void); int main (void) { double ad0,ad1; int d; init(); //初期化 // set_ccr(0x00); //全体の割り込み許可 //AD DA変換----------- while(1){ ad0=get_ad0(); ad1=get_ad1(); for(d=0;d<1000;d++); out_da0(ad0); out_da1(ad1); } return 0; } void init(void) { /* ポートの入出力設定 */ P1DDR = 0xff; P2DDR = 0xff; P3DDR = 0xff; P4DDR = 0xff; P5DDR = 0xff; P6DDR = 0xf0; // CPU基板上のDIP SW P8DDR = 0xff; P9DDR = 0xf7; PADDR = 0xff; // LED基板 PBDDR = 0xff; // A/Dの初期設定(単一モード) AD_CSR = 0x00; // A/Dの初期設定(スキャンモード使用AN0-AN1) // AD_CSR = 0x11; //ITU0 1ms毎の割り込み ITU0_TCR = 0x20; ITU0_GRA = 24575; ITU0_IER = 0x01; ITU_STR = 0x01; // D/Aの初期設定 DA_CR=0xc0; //DA0E1,DA0E0:1 D/Aアウトプットネーブル DAE:0 ch0,1 独立制御 } double get_ad0(void) { int i; double ad; AD_CSR |=0x20; //ADST:1 AD開始 while(!(AD_CSR & 0x80)); //ADF:1 エンドフラグをチェック AD_CSR &=0x7f; i=AD_DRA>>6;// i=0-1023 ad=i*5.0/1024.0; // 0-1024 を 0-5vに変換 return ad; } double get_ad1(void) { int i; double ad; AD_CSR |=0x20; //ADST:1 AD開始 while(!(AD_CSR & 0x80)); //ADF:1 エンドフラグをチェック AD_CSR &=0x7f; i=AD_DRB>>6; //i=0-1024 ad=i*5.0/1024.0; // 0-1024 を 0-5vに変換 return ad; } void out_da0(double d) { DA_DR0=(int)(d*255/5.0); } void out_da1(double d) { DA_DR1=(int)(d*255/5.0); } void wait(void) { long Loop=200000; while(Loop--); }