• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:C18 A/D変換 値の表示)

C18 A/D変換 値の表示

このQ&Aのポイント
  • 加速度センサから取得したデータ(x,y)を基に、傾きを知るためにプログラムを作成しました。
  • x,yの値は正常に表示できたのですが、計算結果outg1が上手く表示できませんでした。
  • アドバイスをお願いします。

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

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

見てみましたが気になるのが1~2つと、間違いが1箇所。 >ADCON2 = 0x36; ADFM=左詰 アクイジション時間=16Tad Tad=Tosc/64 #2の補足のソースコードなら16ビットで処理するので右詰めを指定してください。 あとは、TadのTOSCというのがマニュアルから何Mhzなのか探せなかったので問題ないか自信がありません。アクイジション時間を試しに増やしてもだめでしょうか? どうしても、うまく動かないならとりあえず8ビットで正常に動くようになってから再チャレンジしてみてはどうでしょう?8ビットが成功していたら16ビットもうまく動くはずなんですけどね。 >ADCON1 = 0x32; VREF AN2,AN3を使用。 すべてのアナログピンが有効。 問題ありません。ただし、VREFがAN2,AN3ピンで合っていての場合です。 >右詰でいいと思うのですが… そうです。16ビットなら右詰め。8ビットなら左詰めが正しいです。

-TaKaHiRo-
質問者

お礼

以下のプログラムで10bit精度でのA/D変換ができました。 ありがとうございました。 ------------------------------------------------------------------- int g1, g2, g3, g4; double outg1, outg2; //各レジスタの設定 ADCON1 = 0x32; TRISA = 0x2c; TRISF = 0x7C; ADCON2 = 0xB6; //AN4用 加速度センサA1 ADCON0 = 0x11; ADCON0bits.GO = 1; Delay10TCYx(0); while(ADCON0bits.GO); Delay10TCYx(0); g1 = (((int)ADRESH)<<8) + (int)ADRESL; itoa((int)g1, AN4String); //AN7用 加速度センサA2 ADCON0 = 0x1D; ADCON0bits.GO = 1; Delay10TCYx(0); while(ADCON0bits.GO); Delay10TCYx(0); g2 = (((int)ADRESH)<<8) + (int)ADRESL; itoa((int)g2, AN7String); //加速度センサA 傾き計算 出力 outg1 = atan2((double)g2, (double)g1); outg1 = (outg1*180.0f)/3.1415f; itoa((int)(outg1*100.0f), out_g1String); -------------------------------------------------------------------

その他の回答 (3)

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

>10bit精度で言われた方法で試したのですが、AN7Stirngが0となります。 >また、g1やg2を元に計算した結果も、0とか327567とかが表示されます。 値が変ですね。ちゃんとAD変換されていませんよ。 >(式は outg1 = sin((double)g2/(double)g1); にしました) sinですか?意味が不明なんですが? >気になることがあるのですが、ADCON2のADFM(変換データの格納方法)は、右詰、左詰、どちらにすればよいのでしょうか? >とりあえず、両方とも試したのですが、上の不具合は改善されませんでした。 ちゃんとマニュアルを読んで理解しましょう。 あえて答えを書きませんので、自分で考えてみてください。 後は、PIC18の型番とかクロック周波数とかの詳細の情報を聞いていませんのでADCONの設定が合っているのか判断できません。

-TaKaHiRo-
質問者

補足

>値が変ですね。ちゃんとAD変換されていませんよ。 変換方法に問題はないでしょうか? 8bitの時は、それらしきのが出ていたので… >ちゃんとマニュアルを読んで理解しましょう。 >あえて答えを書きませんので、自分で考えてみてください。 右詰でいいと思うのですが… >後は、PIC18の型番とかクロック周波数とかの詳細の情報を聞いていませんのでADCONの設定が合っているのか判断できません。PIC18F67J60-L/PT(40MHz) 動作クロックは、41.666MHz です。

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

>単に8bitだけ取り出す(精度8bit)場合は、 >g1 = (double)ADRESH; >では駄目なのでしょうか? それでもOKです。精度がほしかったら g1 = (double)( ((int)ADRESH)<<8 + (int)ADRESL ); にすれば良いかと。 それよりも、 int ig1; (中略). ig1 = ((int)ADRESH)<<8 + (int)ADRESL; itoa(ig1, AN7String); (中略) outg1 = atan2((double)ig2,(double)ig1); とした方がプログラム効率が良く、実行速度も上がります。 なるべくdoubleを使わない。double⇔int間の型変換はできるだけ行わないのがPICでのプログラミングのコツです。

-TaKaHiRo-
質問者

補足

10bit精度で言われた方法で試したのですが、AN7Stirngが0となります。 また、g1やg2を元に計算した結果も、0とか327567とかが表示されます。 (式は outg1 = sin((double)g2/(double)g1); にしました) 気になることがあるのですが、ADCON2のADFM(変換データの格納方法)は、 右詰、左詰、どちらにすればよいのでしょうか? とりあえず、両方とも試したのですが、上の不具合は改善されませんでした。 改良後のソースを記載しておきます。 ------------------------------------------------------------------- int g1, g2, g3, g4; double outg1, outg2; //各レジスタの設定 ADCON1 = 0x32; TRISA = 0x2c; TRISF = 0x7C; // ADCON2 = 0xB6; ADCON2 = 0x36; //AN4用 加速度センサA1 ADCON0 = 0x11; ADCON0bits.GO = 1; while(ADCON0bits.GO); Delay10TCYx(0); g1 = ((int)ADRESH)<<8 + (int)ADRESL; itoa(g1, AN4String); // g1 = (double)ADRESH; // uitoa(*((WORD*)(&ADRESH)), AN4String); //AN7用 加速度センサA2 ADCON0 = 0x1D; ADCON0bits.GO = 1; while(ADCON0bits.GO); Delay10TCYx(0); g2 = ((int)ADRESH)<<8 + (int)ADRESL; itoa(g2, AN7String); // g2 = (double)ADRESH; // uitoa(*((WORD*)(&ADRESH)), AN7String); //加速度センサA 傾き計算 出力 outg1 = sin((double)g2/(double)g1); outg1 = (outg1*180.0f)/3.1415f; itoa((int)(outg1*100.0f), out_g1String); -------------------------------------------------------------------

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

ADRESLとADRESHを16bitデータとして読み込んでいますが、エンディアンは大丈夫ですか? MPLAB C18はデータ格納がリトルエンディアンだと説明書に書いてありますけど。 [資料よりコピペ] MPLAB C18 は"little-endian" フォーマットでデータを保存します。若い番地に下位バイトが保存されます。値を「下位を最初に」を基準に保存します。 データを読むときも同様なので、ADRESL,ADRESHの順番で並んでいないと駄目です。 outg1 = atan(g2/g1); これも前のやつ同様にg1が0になったりすると値が信用できませんが大丈夫ですか?atan2が扱えると思うので、atan2を使ってください。 outg1 = atan2(g2,g1); あと書いてないですが、 double outg1; ですよね?

-TaKaHiRo-
質問者

補足

>データを読むときも同様なので、ADRESL,ADRESHの順番で並んでいないと駄目です。 単に8bitだけ取り出す(精度8bit)場合は、   g1 = (double)ADRESH; では駄目なのでしょうか? >あと書いてないですが、 >double outg1; >ですよね? outg1はdoubleです。

関連するQ&A

専門家に質問してみよう