2016-12-23 2 views
0

Bonjour, J'écris en C avec un olimexino (arduino). J'utilise le code suivant pour charger 2 registres (ATmega328):atmega: les données du registre sont corrompues par l'opération de division

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); 

puis-je utiliser ceci:

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

à écrire des deux registres au port B. Mais en utilisant les deux registres r20 et r21 crée un problème. Un conflit se produit si je fais une opération de division. par exemple, si une partie de mon programme a une instruction comme "x = x/6" ou "y = x% 9" alors les nombres que je stocke dans ces registres semblent changer. Si je fais une division simple comme "x/4" ou "x% 8", il n'y a pas de problème. mais toute opération plus complexe qu'une simple division par décalage me vole.

Une aide? Merci

Répondre

0

Faites-en une seule déclaration sur plusieurs lignes:

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); 

Ou peut-être encore mieux:

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

Ou que diriez-vous d'une routine:

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

Que vous pouvez appeler comme ceci:

WriteToPort5(16); 
WriteToPort5(0);