2016-12-23 11 views
0

こんにちは私はolimexino(arduino)でCで書いています。私は2つのレジスタ(atmega328)をロードするには、次のコードを使用しています:ポートBへの2つのレジスタからの書き込みにatmega:レジスタのデータが除算演算によって破損する

asm ("out 0x05, r21 \n"); //write '0' to portB 
asm ("out 0x05, r20 \n"); //write '10000' to portB 

しかし、二つのレジスタのR20を使用して:

asm (
"ldi r20, 0 \n" //load register r20 with 0 
"ldi r21, 16 \n" //load register r21 with 16 
: : : "r20","r21" //compiler directive to reserve the two registers); 

はその後、私はこれを使用しますr21が問題を作り出します。分割操作を行うと競合が発生します。例えば、私のプログラムのどこかの部分に "x = x/6"や "y = x%9"のようなステートメントがあれば、それらのレジスタに格納されている数字は変わるようです。 "x/4"や "x%8"のような単純な除算を行うと問題はありません。シンプルなシフト・ディビジョンよりも複雑な操作は私をねじ込みます。

助けが必要ですか?おかげで

答えて

0

単一、複数行のステートメントとして、それを実行します。

asm (
"ldi r20, 0 \n" //load register r20 with 0 
"ldi r21, 16 \n" //load register r21 with 16 
"out 0x05, r21 \n" //write '0' to portB 
"out 0x05, r20 \n" //write '10000' to portB 
: : : "r20","r21" //compiler directive to reserve the two registers); 

それとも、さらに良い:

asm (
    "out %0, %1 \n" 
    "out %0, %2 \n" 
    : : "i"(5), "r"(16), "r"(0)); 

またはどのようにルーチンについて:

void WriteToPort5(unsigned char b) 
{ 
    asm ("out 0x05, %0" 
    : : "r"(b)); 
} 

あなたはこのように呼び出すことができます:

WriteToPort5(16); 
WriteToPort5(0);