3

以下のコードは、C (Arduino) の 8 ビットのバイト配列を 16 ビットの int 配列に変換することになっていますが、部分的にしか機能していないようです。何が間違っているのかわかりません。

バイト配列はリトル エンディアンのバイト順です。int (エンティティごとに 2 バイト) 配列に変換するにはどうすればよいですか?

簡単に言えば、2バイトごとにマージしたいのです。

現在、次の入力 BYTE ARRAY を出力しています{0x10, 0x00, 0x00, 0x00, 0x30, 0x00}。出力 INT ARRAY は次のとおり{1,0,0}です。出力は INT ARRAY is: である必要があります{1,0,3}

以下のコードは、私が現在持っているものです。

Stack Overflow question Convert bytes in a C array as longsの解決策に基づいてこの関数を作成しました。

また、バイト配列から長い(32ビット)配列まで正常に機能する同じコードに基づいたこのソリューションもありますhttp://pastebin.com/TQzyTU2j

/**
* Convert the retrieved bytes into a set of 16 bit ints
**/
int * byteA2IntA(byte * byte_slice, int sizeOfB, int * ret_array){

    //Variable that stores the addressed int to be stored in SRAM
    int currentInt;
    int sizeOfI = sizeOfB / 2;

    if(sizeOfB % 2 != 0) ++sizeOfI;
        for(int i = 0; i < sizeOfB; i+=2){
            currentInt = 0;
            if(byte_slice[i]=='\0') {
                break;
            }
            if(i + 1 < sizeOfB)
                currentInt = (currentInt << 8) + byte_slice[i+1];
            currentInt = (currentInt << 8) + byte_slice[i+0];
            *ret_array = currentInt;
            ret_array++;
        }
        //Pointer to the return array in the parent scope.
        return ret_array;
    }
4

4 に答える 4

2

Vincenzo has a point (or two), you need to be clear what you're trying to do;

Combine two bytes to one 16-bit int, one byte being the MSB and one byte being the LSB

int16 result = (byteMSB << 8) | byteLSB;

Convert an array of bytes into 16-bit

for(i = 0; i < num_of_bytes; i++)
{
    myint16array[i] = mybytearray[i];
}

Copy an array of data into another one

memcpy(dest, src, num_bytes);

That will (probably, platform/compiler dependent) have the same effect as my 1st example.

Also, beware of using ints as that suggests signed values, use uints, safer and probably faster.

于 2012-11-01T13:28:14.683 に答える
2

このコード行の意味は何ですか?

if(i + 1 < sizeOfB) currentInt = (currentInt << 8) + byte_slice[i+1];

ここでcurrentIntは常に00 << 8 = 0です。

bytesまた、あなたがしていることは、(これから呼びましょう)のカップルごとに、次のようにして(これから呼びましょうuint8_t)をパックすることです:intuint16_t

  1. あなたは一番右を取るuint8_t
  2. 左に 8 ポジションシフトします。
  3. 一番左を追加しますuint8_t

これは本当にあなたが望むものですか?

を持っていると仮定するbyte_slice[] = {1, 2}と、値 513 ( ) を持つ 16 ビット整数をパックします2<<8 + 1!

uint16_tまた、呼び出し元が既に関数に提供しているため、配列へのポインターを返す必要はありません。

Joachimが言ったように、関数の戻り値を使用すると、 position でuint16_tはない配列の位置から始まるポインターを取得します[0]

于 2012-11-01T12:01:29.210 に答える
1

ret_array問題は、あなたがそれを増やしてから返すことである可能性が最も高いです。返すと、宛先配列を超えた1つの場所を指します。

関数の開始時にポインターを保存し、代わりにそのポインターを使用します。

于 2012-11-01T11:38:45.990 に答える
1

構造体の使用を検討してください。ただし、これは一種のハックです。

私の頭の上から、それはこのように見えるでしょう。

struct customINT16 {
    byte ByteHigh;
    byte ByteLow;
}

したがって、あなたの場合は次のように記述します。

struct customINT16 myINT16;

myINT16.ByteHigh = BYTEARRAY[0];
myINT16.ByteLow = BYTEARRAY[1];

ただし、ポインターをキャストしてキャストする必要があります。

intpointer = (int*)(&myINT16);
INTARRAY[0] = *intpointer;
于 2012-11-01T19:23:14.437 に答える