2017-04-07 3 views
-1

私は約2ヶ月間8051をプログラミングしており、C言語の初心者は多少です。私は現在、フラッシュメモリを読み書きし、消去し、分析するためにフラッシュメモリを使っています。私は現時点で書き込みフェーズに取り組んでおり、必要な作業の1つはアドレスの場所を指定し、その場所にデータを埋め込み、次の場所にインクリメントして補完的なデータで埋めることです。私が最後に達するまで、そうしていきます。C - C言語で18ビットを増やす8051

私のジレンマは遊ぶべき18のアドレスビットを持っていて、現在これらの18ビットのために3バイトが割り当てられています。とにかく、これらの18ビットをintまたはunsigned intに組み込み、それを増やすことはできますか?または、最初のバイトをインクリメントする唯一のオプションです。次に、そのバイトが0x00に次のバイトをインクリメントしてロールオーバーすると、次のバイトがインクリメントされます。

私は現在持っている:

void inc_address(void) 
{ 
    P6=address_byte1; 
    P7=address_byte2; 
    P2=address_byte3; 
    P5=data_byte; 

    while(1) 
    { 
     P6++; 
     if(P6==0x00){P7++;} 
     else if(P7==0x00){P2++;} 
     else if(P2 < 0x94){break;} //hex 9 is for values dealing with flash chip 
     P5=~data_byte; 
    } 
} 
+0

ビットフィールドはありますか?そう、8051は、CT境界でほとんど拭き取られ、平らな金魚よりもRAMが少なくなりましたが、ビットフィールドint varに24ビットのうち18ビットを使用できる場合は、それが可能です... – ThingyWotsit

+0

あなたのインクリメントは欠陥があります例えば、P6とP7が255で始まっている場合は、P6とP7 = 1の両方がゼロのままでなければなりません。ループは必要ありません。キャリーテストは入れ子にする必要があります。 – Clifford

+0

アドレス変数をインクリメントしてポートに割り当て、ポート値をインクリメントするのではなく、アドレス変数をポートに割り当てる方がはるかに優れています。 – Clifford

答えて

0

は、私はそのようなintまたはunsigned int型 と増分にそれらの18ビットを組み合わせることができることをとにかくありますか?

確かに。 intunsigned intがシステムに広い少なくとも18ビットであると仮定すると、あなたはこれを行うことができます。

unsigned int next_address = (hi_byte << 16) + (mid_byte << 8) + low_byte + 1; 
hi_byte = next_address >> 16; 
mid_byte = (next_address >> 8) & 0xff; 
low_byte = next_address & 0xff; 

<<>>は、ビット単位のシフト演算子であり、バイナリ&はビット単位「と」演算子です。

しかし、あなたのタイプのサイズについては仮定しないほうが少し安全でポータブルです。 、それを避けるstdint.hを含めると、タイプuint_least32_tの代わりunsigned int使用するには:addressuint32_tある

uint_least32_t next_address = ((uint_least32_t) hi_byte << 16) 
     + ((uint_least32_t) mid_byte << 8) 
     + (uint_least32_t) low_byte 
     + 1; 

// ... 
+0

それで、新しい変数を作成し、それにビット単位の操作をして、インクリメントするために必要な18ビットの変数を作成すると言っています。最初の行の最後に+1を置く理由を説明できますか?私はそれが後に来て初期化の権利ではないと思いますか?次の3行は、元の変数を再定義するだけですが、なぜビット単位の "and"演算子ですか? –

+0

組み立てられたアドレスを格納する場所が必要です。なぜなら、3バイトの関心を引き出すためには、複数回アクセスする必要があるからです。それには変数が必要です。ほとんどの場合、イニシャライザで+1を行いましたが、その初期化と一貫性を持たせた方法で変数の名前を付けました。その代わりに+1が行われた可能性があります。それは単なる文体の選択です。更新されたバイトを読み出すとき、ビット単位の '&'は不要なビットをマスクします。個々のバイト変数が符号なし8ビット型の場合、このようなマスキングは不要ですが、無害です。 –

+0

さて、私は今理解しています。手伝ってくれてどうもありがとう。 –

1

:関数がinc_addressと呼ばれている理由、それは明らかではないが

void inc_address(void) 
{ 
    // Increment address 
    address = (address + 1) & 0x0003ffff ; 

    // Assert address A0 to A15 
    P6 = (address & 0xff) 
    P7 = (address >> 8) & 0xff 

    // Set least significant two bits of P2 to A16,A17 
    // without modifying other bits in P2 
    P2 &= 0xFC ;     // xxxxxx00 
    P2 |= (address >> 16) & 0x03 ; // xxxxxxAA 

    // Set data 
    P5 = ~data_byte ; 
} 

をもとP5を割り当て~data_byte、おそらくデータバスをアサートしていますか?これは、見かけ上のアドレスをインクリメントする以上の何かをしているので、あまりにも紛らわしく混乱しています。私は、関数が住所とデータをパラメータとしてglobal dataではなく取るべきであることも示唆しています。