• 締切済み

8個のビットを1バイトとして扱う方法

1バイトをビット扱いする方法は、 union un_p1dr { unsigned char one_byte ; struct { unsigned char b7:1 ; unsigned char b6:1 ; unsigned char b5:1 ; unsigned char b4:1 ; unsigned char b3:1 ; unsigned char b2:1 ; unsigned char b1:1 ; unsigned char b0:1 ; } bit ; } ; #define pt_da_p1dr (*(volatile union un_p1dr *)0xffffd0) と宣言すれば、pt_da_p1dr.bit.b7 = 1 ;の様にビット扱いが出来ます。 この反対を行える宣言方法は、あるでしょうか? つまり、任意の1ビットを8ビット集め、プログラムでバイトにてアクセスしたいのですが・・・・ ARMなどは、ビットの扱いが容易に可能です。しかし、CPUの周辺関係事情より、バイトでのアクセスが 可能なように、ハード割り当てが出来ません。 従って、現在は、プログラムにて、ビットを集め、バイトにして、アクセスしています。 なにか良い宣言方法があれば、ご伝授していただけないでしょうか? 宜しくお願いいたします。

みんなの回答

  • _kappe_
  • ベストアンサー率68% (1524/2218)
回答No.2

「任意の1ビットを8ビット集め、バイトにてアクセス」っていうのは、例の中のb7は0x1000番地の3ビット目に対応、b6は0x1020番地の5ビット目、…みたいに指定して、one_byteに値を代入すると指定した各番地のビットが書き換わるみたいな仕組みが欲しいということでしょうか。 C言語の標準にはそういうものはないので、安心してこれまで通りのやり方を続けてください。

全文を見る
すると、全ての回答が全文表示されます。
回答No.1

普通は、 #define pt_da_p1dr(*(volatile union un_p1dr *)0xffffd0) のあとに、たとえば、 #define aPort pt_da_p1dr.bit.b7 と定義するだけですが。 「プログラムにて、ビットを集め、バイトにして、アクセスしています」の具体的なコードでもあれば、何かわかるかもしれませんが。 ただ、Cのレベルで、ビットアクセスできても、CPUがビット単位でアクセスしているかどうかは、また、別の話ではあります。

ken_japan_ken
質問者

補足

すいません。解りづらいので、補足させて頂きます。 ARMの場合、下記の通りポートAの0ビット宣言は、 #define PORTA_0 *((volatile unsigned int*)(0x42668080UL)) と宣言されています。 この様なポートを8ビットにまとめたいのですが・・・ 出力プログラムを組むと下記の様に成ります。 void bit_byte(char data) { if( data & 0x01 ) PORTA_0 = 1 ; //ポートAの0ビットに出力 else PORTA_0 = 0 ;  if( data & 0x02 ) PORTC_5 = 1 ; //ポートCの5ビットに出力 else PORTC_5 = 0 ; if( data & 0x04 ) PORTD_1 = 1 ; //ポートDの1ビットに出力 else PORTD_1 = 0 ; . .(3~6ビットは、省略) . if( data & 0x80 ) PORTA_7 = 1 ; //ポートAの7ビットに出力 else PORTD_7 = 0 ; } void main(void) { bit_byte(0x26) ; //0x26を出力する } このbit_byte関数を、宣言でバイトに各任意のビット指定をし、 下記の様に組めないでしょうか?  abc = 0x26 ; bit_byteの関数は、一見で解かる様に書いたので、 この関数の組み方での指摘は、しないでください。 ご存知でしたら、是非、教えて頂きたいと思います。 宜しくお願いいたします。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • C言語のビットフィールドについて

    はじめまして,今C言語を勉強中なのですが, ビットフィールドの宣言について質問があります。 勉強に使用しているテキストでは, ビットフィールドの宣言にはunsigned int型を使用すると書かれています(下記例参照)。 ここで質問は,unsigned charなどの型は推奨されない理由があるのか,ということです。 実際にunsigned char型で実行してもプログラムは動きますし,そちらのほうが語長も短くて済むのでいいような気がします。 テキストの書き方だと,他の型について言及していなかったので,なにか理由かあるのか,それとも特に問題ないのか,疑問に思っています。 わかる方いましたら,回答いただけると嬉しいです。 (ex) struct{ unsigned int bit0:1; unsigned int bit1:1; : unsigned int bit7:1; }bits;

  • 配列のビット設定方法

    以下のようにビットを設定する場合、どのようにすればよいのでしょうか? 効率よく設定したいのですが・・・。 // bit // 23 - 21:week1 // 20 - 18:week2 // 17 - 15:week3 // 14 - 12:week4 // 11 - 9:week5 // 8 - 6:week6 // 5 - 3:week7 // 2 - 0:week8 unsigned char week[3]; 上記の変数にこの変数の内容を設定する // 以下の変数の範囲は 0~7 unsigned char week1; unsigned char week2; unsigned char week3; unsigned char week4; unsigned char week5; unsigned char week6; unsigned char week7; unsigned char week8; ---------------- week[0] = ( week1 << 5 ) & ( week2 << 2 ) & ( week3 >> 1 )  ・ ・ ・ 上記のような感じで設定できると思うのですが、もっと効率的に方法はないでしょうか? 配列の数が多くなると面倒ですので。。。 よろしくお願いします。

  • 共用体のアドレスを取得したい

    SH7047のプログラムです。 何をしたいのかと言うと、P_PORTD.PDDRL.BIT.PD4DR等を関数の中で変化させたいのです。 うまく行かない理由はおそらく「P_PORTD.PDDRL.BIT.PD4DRのアドレスは渡すことが出来ない」だとおもいます。 まぁそれも当然な話だと思うのですが、どうにかならないでしょうか? 個人的には「unsigned short* port」→「bit* port」の様に出来れば理想的なのですが。 何か良い方法を教えてください。よろしくお願いします。 #define P_PORTD (*(volatile struct st_portd *)0xFFFF83A2)/* PORTD Address */ struct st_portd { /* struct PORTD */ union { /* PDDRL */ unsigned short WORD; /* Word Access */ struct { /* Bit Access */ unsigned short :7; /* */ unsigned short PD8DR:1; /* PD8DR */ unsigned short PD7DR:1; /* PD7DR */ unsigned short PD6DR:1; /* PD6DR */ unsigned short PD5DR:1; /* PD5DR */ unsigned short PD4DR:1; /* PD4DR */ unsigned short PD3DR:1; /* PD3DR */ unsigned short PD2DR:1; /* PD2DR */ unsigned short PD1DR:1; /* PD1DR */ unsigned short PD0DR:1; /* PD0DR */ } BIT; /* */ } PDDRL; /* */ }; /* */ void main(void) { output(&P_PORTD.PDDRL.BIT.PD4DR,0xff); output(&P_PORTD.PDDRL.BIT.PD5DR,0xff); output(&P_PORTE.PEDRL.BIT.PE12DR,0xff); } void output(unsigned short* port,int data) { P_PORTE.PEIORL.WORD = 0x3fff; P_PORTE.PEDRL.WORD = data & 0xff; *port = 1; *port = 0; P_PORTE.PEIORL.WORD = 0x3f00; }

  • 表示パターンを作りたいです。

    7セグメント表示(1A~G・2A~G)とその他のマーク(T1・T2)を表示する液晶の表示パターンを作りたいのですが、ポートのアドレス内のビット配置が 1A・1B・1C・1D・T1・1E・1F・1G とセグメントとその他のマークが混在していたり、 2A・2B・2C・2D・ー・ー・ー・ー ー・ー・ー・ー・T2・2E・2F・2G と、さらに2つのアドレスにまたがって配置されていたりします。 各アドレスとポートはヘッダで union tag_IOPORT { unsigned char byPORT; struct { unsigned char B7:1; unsigned char B6:1; unsigned char B5:1; unsigned char B4:1; unsigned char B3:1; unsigned char B2:1; unsigned char B1:1; unsigned char B0:1; } BIT; }; #define IOPORT1_addr (*(volatile union tag_IOPORT *)0xffff) #define port1 IOPORT1_addr.byPORT #define 1A IOPORT1_addr.BIT.B7 #define 1B IOPORT1_addr.BIT.B6 #define 1C IOPORT1_addr.BIT.B5 #define 1D IOPORT1_addr.BIT.B4 #define T1 IOPORT1_addr.BIT.B3 #define 1E IOPORT1_addr.BIT.B2 #define 1F IOPORT1_addr.BIT.B1 #define 1G IOPORT1_addr.BIT.B0 という感じで#defineで宣言してあって、バイト単位でもビット単位でも操作出来るようにしてあります。 そこで、セグメントとマークを ・セグメント1 ・セグメント2 ・マーク などのそれぞれのグループごとにまとめて操作する方法はないでしょうか? イメージとしては disp_T[4][2]={{0,0},{0,1},{1,0},{1,1}} というような表示パターンの配列を作って代入すればマークの表示が出来るような感じにしたいのですが、代入する先を作れば良いかわかりません。 イメージ通りに作る事は可能なのか、どう作れば良いのか、他に良い方法など教えてください。 わかりにくい文章かもしれませんがお願いします。

  • ビット演算について

    いつもお世話になります。 ビット演算について教えて下さい。 unsigned char buf1[1]=0x5a unsigned char buf1[2]=0x04 unsigned char buf1[3]=0x38 5a0438(16)を3バイトの値を12ビットずつの整数で得るにはどうしたらいいのでしょうか? 2進数表記では、 5A | 04 | 38 01011010 | 00000100 | 00111000 12ビットずつとは、 010110100000 010000111000 と区分し、10進数の整数値で得たいです。どのようにすればよいでしょうか? また、0x5Aなどの16進数を2進数のビットで考えるときに、 01011010を下位4ビットを10進数整数を得るにはどうしたらよいのでしょうか? 上記2点、どうぞよろしくお願い致します。

  • C言語のビットフィールドで分からないところがありま

    union UNION { struct { unsigned int a :(32-8-5); // この部分 unsigned int b :8; unsigned int c :5; }BIT; }; 上記の「この部分」と書いてある行の意味を教えてください よろしくお願いします

  • C言語で確保できるビットの桁数

    C言語でビット単位でデータ操作する際に、確保できるビットの桁数はたとえば以下のような例の場合 unsigned char bit; 1バイト(=8ビット)なので8桁ということは勉強しました。 ここで、たとえば計算でビットの桁数を100桁用意したい場合 以下のように32*4桁という風に分ける方法しかないのでしょうか? unsigned int bit[4]; できれば一つの変数で済ませたいのですが、何か良い方法をご存知の方いらっしゃいましたらよろしくお願いします。

  • 第7ビットが0の4バイト分計算

    お世話になります。ID3v2の仕様で、タグ部分のサイズを表す数字が 「第7ビットがすべて0になるようにエンコードされた4バイトのデータ であり、第7ビットは無視するため全部で28ビット」 なので、例をあげると、 0x00000201 → 257(普通は513) となります。これをファイルから読み込む時、どのようにして読み込んだらいいでしょうか。 1バイトずつcharに入れて、128の重み(普通は256)を付けて計算したら良いかと思いましたが、試しに //cに1バイト読み込んだと仮定 char c = 0xAC; unsigned int i = 0; i += c; とすると、iが -84 になってしまいました。(172になって欲しかった) 聞きたいことは以下の2つです。 1.第7ビットを無視するデータを4バイト分読み込んで、整数にするにはどうしたらいいのか 2.もしくは、ファイルから1バイトずつ読み込んで整数にするにはどうすればいいのか です。何か分かり難い文章ですが、よろしくお願いしますm(__)m

  • いつからビットからバイトに?

    いつもお世話になっております。 最近のメモリやストレージの容量はバイト(byte)で 表されますが、昔はビット(bit)が一般的だったと思います。 PC88や98、windows95時代からメモリやHDDの 数値のインフレ具合を見ていましたが、 バイトに切り替わったタイミングで、同じ性能なら 数字は8分の1になると思います。 しかしそんな時期があった気がしません。 あ、もちろんプロセッサの事じゃないですよ? 1バイト=8ビットというのは意外にも2008年になるまで 正式に定義されてなかったようですがその辺りでしょうか? もう少し前からバイトが一般になってた気がしますが...。 それともフロッピーディスク時代に 私が100MBのHDDをいち早く手に入れてイキってた時、 既にMBのBはバイトだったのでしょうか? 少なくともファミコンソフトの容量は「大容量4メガビット!」 とか謳ってたと思うのですが...。 ずっと勘違いしてたのなら恥ずかしいです。

  • ビットデータの取得方法について

    32    24 23  16 15    87    0 +--------+--------+--------+--------+ |11000111 |11000111 |11000000 |00000000 | +--------+--------+--------+--------+ ↑のようなビット情報から 24-34bitの1byteにデータa 22-23bitの2bitにデータb 16-21bitの6bitにデータc 14-15bitの2bitにデータd がつめられている場合 データa,b,c,dを参照するためにCで (1)シフト演算で参照する方法 (2)構造体のビットフィールドで参照する方法 をご教授いただけないでしょうか?