2017-04-07 1 views
-1

Je programme le 8051 depuis environ deux mois et je suis un peu novice en langage C. Je travaille actuellement avec la mémoire flash pour la lire, l'écrire, l'effacer et l'analyser. Je travaille sur la phase d'écriture pour le moment et l'une des tâches que je dois faire est de spécifier un emplacement d'adresse et remplir cet emplacement avec des données puis incrémenter à l'emplacement suivant et le remplir avec des données complémentaires. Donc, et ainsi de suite jusqu'à ce que j'atteigne la fin. Mon dilemme est que j'ai 18 bits d'adresse à jouer avec et actuellement trois octets alloués pour ces 18 bits. Y at-il de toute façon que je puisse combiner ces 18 bits en un int ou unsigned int et que j'ajoute comme ça? Ou est ma seule option pour incrémenter le premier octet, puis lorsque cet octet roule sur 0x00 incrémenter l'octet suivant et lorsque celui-ci survole, incrémenter le suivant?C - Incrément de 18 bits en C 8051

J'ai actuellement:

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

Avez-vous des champs de bits disponibles? OK, donc le 8051 a été presque effacé sur la limite CT et a moins de RAM qu'un poisson rouge plat, mais si vous pouvez utiliser 18 bits sur 24 pour un bitfield int var, cela pourrait le faire ... – ThingyWotsit

+0

Votre incrément semble défectueux , si P6 et P7 commencent à 255 par exemple, vous finissez avec P6 et p7 = 1 quand les deux doivent rester à zéro. La boucle n'est pas nécessaire - les "carry tests" doivent être imbriqués. – Clifford

+0

Il serait également préférable d'incrémenter la variable d'adresse et de l'assigner au port plutôt que de l'assigner au port et d'incrémenter les valeurs du port. – Clifford

Répondre

0

Y at-il de toute façon que je pouvais combiner ces 18 bits dans un int ou unsigned int et l'incrément comme ça?

Bien sûr. En supposant que int et unsigned int sont au moins 18 bits de large sur votre système, vous pouvez le faire:

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; 

Le << et >> sont des opérateurs de décalage au niveau du bit et le & binaire est le bit « et » opérateur.

Il serait toutefois un peu plus sûr et plus portable de ne pas faire de suppositions sur les tailles de vos types. Pour éviter cela, inclure stdint.h et utiliser le type uint_least32_t au lieu de unsigned int:

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

// ... 
+0

Donc vous dites de créer une nouvelle variable et de faire des opérations sur les bits afin de créer la variable de 18 bits dont j'ai besoin pour incrémenter. Pourriez-vous expliquer pourquoi vous mettez le +1 à la fin de la première ligne? Je pense que cela devrait venir après et pas dans l'initialisation droite? Les trois lignes suivantes ne font que redéfinir les variables d'origine mais pourquoi l'opérateur "et" bit à bit? –

+0

Vous avez besoin d'un emplacement pour stocker l'adresse assemblée, car vous devrez y accéder plusieurs fois pour extraire les trois octets d'intérêt.Cela nécessite une variable. J'ai effectué le +1 dans l'initialiseur principalement pour la brièveté, et j'ai nommé la variable d'une manière destinée à être cohérente avec cette initialisation. Le +1 aurait pu être fait par la suite; c'est juste un choix stylistique. Lors de la lecture des octets mis à jour, les bits '&' bit à bit sur les bits indésirables. Si les variables d'octets individuelles ont un type 8 bits non signé, un tel masquage est inutile, mais inoffensif. –

+0

D'accord, je comprends maintenant. Je vous remercie beaucoup pour votre aide. –

1

address est uint32_t:

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

Cependant, il ne sait pas pourquoi la fonction est appelée inc_address mais affecte également P5 avec ~data_byte, qui prétend probablement le bus de données? Il fait quelque chose de plus que d'incrémenter une adresse, semble-t-il, est ainsi nommé de façon médiocre et confuse. Je suggère également que la fonction devrait prendre l'adresse et les données en tant que paramètres plutôt que global data.