1

私はCでPICマイクロプロセッサを使用しています。これは16Fであるため、32ビットを超える整数を保持できません(符号なしint32は使用可能な最大のデータサイズです)

リーダーから、5バイトのIDコードを受け取ります。それを送信するには、BCDに1桁ずつエンコードする必要があります。データサイズよりも大きいため、文字列にスプリントできず、処理できません。操作が定義されていないため、分割できません。

私は可能な解決策を見つけることができません、誰かが以前にこれに対処したことがありますか?

編集:

一連の5バイトで番号を受け取ります。

FF-FF-FF-FF-FF

10進数に変換する必要があります

0123456789012

(13桁、10進数で256 ^ 5の長さ)RS232を介して送信します。2番目の関数(ASCIIを取得して送信します)私はすでにそれを機能させていますが、それを使って何かをする前に、完全な数値の文字列表現が必要です。

4

5 に答える 5

4

32ビット演算があると仮定すると:2 ** 24 = 16777216なので、xを最上位2バイト、yを最下位3として使用します。

  (16777216 * x + y) / 1000 
= (16777000 * x + 216 * x + y) / 1000
= 16777 * x + (216 * x + y) / 1000

最初の項は、オーバーフローなしで32ビットで計算できます(以降x < 2**16)。2番目の項もオーバーフローなしで計算できます(x < 2**16およびy < 2**24)。

これは基本的に2**242桁の値を基にした筆算ですが、除数が1000であることを知って事前に計算された項があります。10の最小の累乗が。よりも大きいため、1000が選択されます2**8

したがって、最初に下位3桁を計算し、という事実を使用し(2**32) % 1000 == 296ます。したがって、今回はxを最上位バイト、yを下位4バイトとします。

((2**32) * x + y) % 1000 = ((2**32) * x) % 1000 + y % 1000 (modulo 1000)
                         = (296 * x) % 1000 + y % 1000     (modulo 1000)
((2**32) * x + y) % 1000 = ((296 * x) % 1000 + y % 1000) % 1000

次に、上記の式を使用して、元の数を1000で割ります。次に、32ビット領域に安全に移動し、通常のループを使用して残りの数字を解き放つことができます。

ところで、私があなたなら結果をチェックします。私はこれをテストしていません。どこかでエラーが発生した可能性があります。PCで64ビット整数の通常の手段を使用して行われたbcd変換の結果と比較するのは簡単です。

于 2009-07-17T15:10:20.043 に答える
1

私がすることは、文字列(BigNumの一種)としてコード化された数値の加算と乗算を実装することです。このようにして、IDの最上位バイトを文字列 "A"にスプリントし、文字列 "4294967296"(256 ^ 4)を掛けて、文字列 "B"を取得し、IDの最下位4バイトをスプリントします。別の文字列「C」、最後に「B」と「C」を追加します。

特にマイクロコントローラーではそれほどセクシーではありませんが、機能します:)

于 2009-07-17T14:45:46.037 に答える
1

PIC16Fにはハードウェアの乗算または除算ユニットがないため、2の累乗で乗算または除算しない限り、プロセッサに負担がかかります。これは、32ビット数でBCDを実行し、除算や乗算を必要としないルーチンです。チャンクで実行することにより、これを5バイトの数値に適合させることができます。

void BCD32(int32u numIn){int8u桁= 0;

while (numIn >= 1000000000)
{
    numIn -= 1000000000;
    digit++;
}    
debug[0] = digit + 48;   
digit = 0;
while (numIn >= 100000000)
{
    numIn -= 100000000;
    digit++;
}    
debug[1] = digit + 48;            
digit = 0;
while (numIn >= 10000000)
{
    numIn -= 10000000;
    digit++;
}    
debug[2] = digit + 48;            
digit = 0;
while (numIn >= 1000000)
{
    numIn -= 1000000;
    digit++;
}    
debug[3] = digit + 48;            
digit = 0;
while (numIn >= 100000)
{
    numIn -= 100000;
    digit++;
}    
debug[4] = digit + 48;            
digit = 0;
while (numIn >= 10000)
{
    numIn -= 10000;
    digit++;
}
debug[5] = digit + 48;        
digit = 0;
while (numIn >= 1000)
{
    numIn -= 1000;
    digit++;
}
debug[6] = digit + 48;    
digit = 0;    
while (numIn >= 100)
{
    numIn -= 100;
    digit++;
}
debug[7] = digit + 48;

digit = 0;
while (numIn >= 10)
{
    numIn -= 10;
    digit++;
}
debug[8] = digit + 48;

digit = 0;
while (numIn >= 1)
{
    numIn -= 1;
    digit++;
}
debug[9] = digit + 48;    
debug[10] = CARRIAGE_RETURN;
debug[11] = NEW_LINE_FEED;
SendUart(12);                           

}

于 2009-07-29T21:06:34.480 に答える
0

いつでも手動で文字列に「sprintf」することができます。データをバイトごとに調べ、個々の文字を追加して数値文字列に変換します。

于 2009-07-17T13:43:47.763 に答える
0

この問題の核心は、10進数に変換する「筆算」の1つです。小学校で学んだ筆算とはまったく異なりますが、2進数を使用すると、筆算ははるかに簡単になります。しかし、それでも多くの作業が必要です。

試す:
http://mathforum.org/library/drmath/view/55951.html

独自のマルチバイト減算およびシフトルーチンを実装する必要があります。

于 2009-07-17T15:00:16.040 に答える