• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:2バイトデータのビットシフトについて)

2バイトデータのビットシフトについて

kuma310minの回答

回答No.4

buf と ad は、それぞれ unsigned char buf[6]  (0~255) unsigned int ad   (0~65535) で定義されています。 adに読み込む際、直接(変換なしに)2バイトデータとして読み込めれば、 このような変換は必要ないのでしょうが、考えられる原因として、 ・(ハードウェア的な理由により?)1バイトずつしか読み込めない ・2バイトまとめて読むことは可能だが、データの格納が上位・下位逆になっている があります。 (ちょっと見た感じでは、後者っぽい?) 後者であれば、格納データが、 buf[0] buf[1] ・・・ buf[6] の順に格納されていて、buf[1]が上位・buf[0]が下位の2バイトデータで読みだしたいが、 そのままだと逆になってしまう事が考えられます。 この場合、 ・buf[1] を8ビットシフトして、上位バイトへ ・それにbuf[0]を加算 して、adを 「buf[1]が上位・buf[0]が下位の2バイトデータ」 にしていると思われます。

phuseman
質問者

補足

たとえば、AD変換の結果、 1010 1111 11 (10進:703) という10ビットのデータが得られ、 buf[0]とbuf[1]が逆に格納されると仮定した場合、 ---ソース引用部--- ad = (buf[1] << 8) + buf[0]; ------------------ の演算は、 [A] ビットシフト前 buf[6], buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]. pppp pppp, qqqq qqqq, xxxx xxxx, yyyy yyyy, zzzz zzzz, 1100 0000, 1010 1111. [B] ビットシフトした値 buf[6], buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]. qqqq qqqq, xxxx xxxx, yyyy yyyy, zzzz zzzz, 1100 0000, 1010 1111, 0000 0000. のように、[B] のbuf[1]と、[A]のbuf[0]は同じになってしまう気がするのですが、 間違いがあれば、ご指摘願います。

関連するQ&A

  • エラーが出てしまいます。

    このプログラムはPIC16F88でYMZ294を使って「かえるの歌」を流すプログラムですが、間違ってるところを教えてください。 http://www8.plala.or.jp/InHisTime/LABO-028/ymz294.c ソフトはmikroC PRO for PIC (v.4.15.0.0) です。 実際にURL先のプログラムをコピーしてmikroCに貼り付けて ビルドさせると下の欄にエラーが表示されます。

  • 配列をnビットシフトする

    題名の通り配列をnビットシフトする方法を教えてください。 char buf[3] = { 0x30,0xf0,0x80 }というデータで n=3 だった場合 欲しいデータはbuf[3] = { 0x06,0x1e,0x10 }です。 { 0x30, 0xf0, 0x80 } →{ 0x06, 0x1e, 0x10 } [ 00110000,11110000,10000000 ]→[ 00000110,00011110,00010000 ] ご教授お願いします。

  • PICのシリアル通信のWIN_APIプログラムについて

    PICとPCとのシリアル通信の WIN_APIプログラムについてどなたかご存知の方は教えてください. 現状,API関数を用いて,シリアル通信をできるようにプログラムを作成したのですが,送信はできるのですが,受信データが"C0"をPICから送付しているのに,"FFFFFFFC0"と受信されてしまいます. 先の"FFFFFFF"をとるにはどうしたらいいでしょうか? 現状:受信プログラム // シリアルポートに対する書き込み(PICに送信命令) WriteFile(hCom, w_com_Buf,lstrlen(w_com_Buf), &n, 0 ); // シリアルポートに対する読み込み ReadFile(hCom, s_com_Buf,1, &n, 0 ); mikroC上のUSARTターミナルでは送受信は適正で, 上記のプログラマで 送信はPIC側で受信していることは7SEGを使って確認しています. しかし,PC側では, s_com_Buf[0]には,"C0"が入ったり,"FFFFFFC0"が入ったりします. PICは現状,多チャンネルAD変換をしているため, 送信に対する受信データのやり取りができなくて困っています. どなたか先生教えてください.

  • PIC12F683からパソコンへのシリアル通信

    PIC12F683 を使って、簡単な電圧ロガーを作ろうとしているのですが、 パソコンへの送信が正常に行われません、わかる方がおられたらどこが悪いのかご指摘願います。 PICの書き込み、PICからのデータ受信に用いているパソコン(のマザーボード)は、G45GCMX-S2です。 参考にさせていただいているサイトは、 http://www8.plala.or.jp/InHisTime/page005.html#PIC-002 なのですが、上記サイトのソースプログラム http://www8.plala.or.jp/InHisTime/PIC-001/DataLogger2.c には何の手も加えず、動作させております。 また、PIC->PCへの接続端子の接続が正常である事も、テスターで確認しております。 (回路から、PCのCOM1(DSUB-9pin)へ接続。) コンパイル(MikroC 8.88)、hexの書き込み(RCDライタ)までうまくいくのですが、 ブレッドボードに組んで、電源を入れてもGP5の電圧に変化が無い、という状況です。 (LEDを点滅させるプログラムを書き込んだ場合は問題なく動作しています。) 実際の各端子は Vdd 1pin : 5V GP5 2pin : open (※ この端子の電圧に変化が無い) GP4 3pin : open GP3 4pin : 5V CPP1 5pin : open AN1 6pin CH1 : open AN0 7pin CH0 : open Vss 8pin : GND となっています。テスターで測ると 2pinは2.3Vで一定、 レベル変換用のトランジスタのコレクタは3.4V一定です。 念のためレベル変換回路 (http://www8.plala.or.jp/InHisTime/img2022.jpg の右上、C1815の部分。) 単体の動作確認はしています。 ハイパーターミナルその他のソフトで通信しようと試みたのですが、 反応が無いため、ピンの電圧を測ってみたところ、パソコンへの送信出力ピンの電圧が 変化していないので、これは正常じゃないのでは無いか?と思い、 詳しい方のアドバイスをいただこうと投稿しました。 上記のソースであれば、1秒ごとに出力電圧に反応があるかと思いますが、無反応です。 説明がややこしくなりましたが、わかる方がおられましたらよろしくお願いします。

  • ビット演算を学びたい

    a &= 2; a |= 2; a ^= 2; a ~= 2; a <<=2; a >>=2; みたいな感じでビット演算が使われているソースを 良く見るのですが、いまいちビット演算で何をしているのかが 分かりません。 参考書などには文字通りビットをいじるような旨のことが書いてあります。 (こちらにも同じようなことが http://www9.plala.or.jp/sgwr-t/c/sec14.html) こういうので何となくは分かるのですが、 実際にこれを何に使えるか、実践ではどのように使うのかが なかなか見えてきません。 このビット演算を私のような者でも実際のプログラムで使いこなせるように なれるようなサイトや書籍の提示、あるいはサンプルのプログラムなどで ご指導いただけたらと思います。

  • EEPROMをPICで使用する方法について

    PIC16F87XでEEPROM(24LC256)の利用を実験しているのですが、EEPROMへ連続してデータを続書き込みする場合、完了時に一定の時間ウェイトする必要があるようです。 データシートにWrite cycle time(byte or page) Tsp = 5msトありますが、この5ms秒のウェイトとは、次回の書き込みまでに、AD変換など他の処理が、5ms以上時間がかかるれば、問題ないということでしょうか? それとも、この間は、他の処理は行ってはいけないということでしょうか? どのカテゴリに質問していいのかわからないので、とりあえずこのカテゴリに質問させていただきます。 PICの処理に詳しい方いらっしゃいましたら、よろしくお願いします。 ちなみに、開発は、CCS-Cを使用しています。

  • pic32mxのデータ幅

    初めてPIC32MXでプログラムを走らせようとしています。 MPLAB X IDEとXC32を使っています。 PIC18F等の8ビットCPUの経験はあります。 PIC32MXはアドレス幅32ビットデータ幅32ビットだと思ってプログラムを作り始めました。 デバックするところになって分からないことが出てきました。 XC32におけるint型のデータ幅は32ビット、unsigned char型は8ビットです。 プログラムで変数を定義するとunsigned char型は偶数アドレス、奇数アドレスそれぞで定義されます。 int型の配列を定義すると、偶数番地アドレスを先頭として4バイト単位で割り当てられます。 これは、PIC32MXがバイトアドレッシングCPUで4バイトアライメントということだと思います。(違ったらご指摘下さい。) 実際MPLAB X IDEでデータメモリを参照すると1アドレス1バイトデータで表示されます。 質問は、 PIC32MXは32ビットアドレス空間(実際に持っているROM、RMAサイズは別として) のCPUではあるが、メモリ幅は、8ビットというのではないだろうか? というものです。PIC32MXの内部レジスタ関連は32ビットなので32ビットCPUだとは思いますが、データシートにある「 32 ビットのネイティブデータ幅」という意味がわかりません。 実際のメモリ空間は、アドレス範囲 x 8ビットということでいいのでしょうか。 御教授いただけましたら幸いです。

  • MplabのRead_EEPROM

    Mplab8.92+PICkit3でPICのプログラムをしています。 ポート入力をPIC内蔵のEEPROMに書込むようなプログラムを作り ターゲットボード上で動作させた後、PICをボードから抜き取り Mplab上でReadしViewメニューのEEPROMで見ると ポートの入力とは異なる値になっています。 (ボードの入力はプルアップした上で固定してあります。) しかし、A社のプログラマーでReadすると ポート入力がEEPROMに正しく書込まれています。 (A社のプログラマーはサポートのデバイスが少ないので 現実的には使えないのですが。) 色々試してみると プログラムとして、「PIC内蔵EEPROMデータメモリに初期値として書込んだデータ」は 正しく、書込み、読取できましたが ボード上で動作しないと確定しないようなデータ (ポートの入力、カウント回数・・・等) は、正しく書込まれている (プログラムの動作から確認すると) けれどもMplab上のReadでは正しく表示されませんでした。 MplabのReadとはこういうものなのでしょうか? (私の推測ではMplabのRead-View-EEPROMはCPUを実機で 動作させることなくパソコン上でシュミレーションするための もののように思えてきたのですが・・・) それとも、何か設定すれば可能になるならば 教えてください。 私の場合Mplabを使う場合 シュミレーションとかは使いません。 コンパイルしてCPUに書込み(Program)するだけです。

  • 不揮発メモリ(EEPROM)内蔵のワンチップマイ…

    不揮発メモリ(EEPROM)内蔵のワンチップマイコンについて http://mori.nc-net.or.jp/EokpControl?&tid=154077&event=QE0004 に非常に奇妙な質問と回答がありました。 回答が締め切られたため、別話題として質問にしてみました。 不揮発メモリのEEPROMには書きこみ回数に寿命制限があります。 このため、ワンチップマイコンにEEPROMを内蔵すると、書きこみ回数の 寿命制限を越えたときから、マイコンは正常に動作できなくなる問題 があります。 従って、EEPROM書きこみ回数制限を越えても、CPUが動作できるように、 不揮発情報をCPU外部のNVRAM RAMに持たせるという考え方がH8ではとられ ていると思われます。 一方PICマイコンで内蔵EEPROMを使用するには当然、その書きこみ回数が 書きこみ制限回数を越えないような応用に使わないと、PICマイコンは EEPROM書きこみ回数の上限値を越えたときから恒久故障に至ります。 そうしたマイコンそれぞれの設計思想を理解せずして、PICマイコンが良い とか、H8が悪いみたいな結論は、マイコンとその応用の仕方の考え方の 理解が全くできていないと思いますよ。 H8が悪くてPICが良い? http://mori.nc-net.or.jp/EokpControl?&tid=154077&event=QE0004

  • PIC16F1827のEEPROMへの書込み

    PCM V5.0(PIC用CCS社コンパイラ)を Mplab8.92に組込み、PICkit3を使ってプログラムしています。 PIC16F1827のEEPROMへの書込みがうまくいきません。 RAは入力ポートで固定してあります。 RBは出力ポートでLEDが接続してあります。 テストプログラムは一回のみの動作です。 実機で動作させると RAは固定してあるので当然(4)でLEDが点灯しますが、 実機からCPUを抜き取りMplab上でReadすると EEPROMのアドレス0,1,2は異なるデータであり 動作させるたびに違うデータが書込まれています。 しかし (1) a0=35h (2) a1=a6h (3) a2=93h と定数にすると EEPROMのアドレス0,1,2は正しいデータが 書込まれています。 Q1. a0,a1,a2をポート入力とする場合は CPU自体に何か設定する必要があるのでしょうか? それともプログラムに工夫が必要なのでしょうか? いままで使っていたPIC16F88では このようなことはなかったと思うのですが・・・。 ----- テストプログラム ----- a0 = RA; //(1) write_eeprom (0,a0); a1 = RA; //(2) write_eeprom (1,a1); a2 = RA; //(3) write_eeprom (2,a2); if (a0 == a1 && a1==a2) //(4) RB =255; else RB =0;