2017-10-13 2 views
0

J'essaie de comprendre s'il existe un moyen simple de modifier plusieurs bits d'un port 8051 à la fois.modifier plusieurs bits à la fois sans opération de démolition - 8051 ports

Je vais ré-expliquer mon dilemme style plus concret.

Mon application a Port 2 divisé pour deux fonctions. Appelons-les FA et FB. FA dépend de la valeur de sortie des trois bits inférieurs, et FB compte sur les 5 bits restants, mais ils peuvent être des E/S. Comme un bit dans FB est un bit de sortie qui contrôle une horloge, je ne veux pas modifier une partie de FB lorsque je modifie FA et vice versa.

Les types de commandes suivantes ne fonctionnent pas pour moi:

mov P2,#07h 
mov P2,#80h 

En effet, ces commandes remplacent les valeurs pour les deux fonctions déclenchant éventuellement une fonction au mauvais moment.

je pouvais sortir avec quelque chose comme ce qui suit:

setb P2.7 
setb P2.6 
clr P2.5 
clr P2.4 
setb P2.3 
setb P2.2 
clr P2.1 
clr P2.0 

Parce que je sais que ces commandes peuvent définir des bits individuels, un par un, sans affecter les bits restants, mais je voudrais essayer de mettre plus un peu à la fois. Je lis à propos de lecture-modification-écriture et l'Internet me dit que le MOV est différent des opérations logiques sur les broches du port, donc je vais essayer de deviner ici si j'ai raison selon mon exemple :

Say pour FB Je veux sortir tous les hauts logiques et pour FA je veux sortir tous les bas logiques excepté ce bit le plus bas = 1. Je veux opérer sur une fonction à la fois.

Je sais cela ne fonctionnera pas, car il met tout à la fois:

mov P2, #0F9h 

Mais de toute façon, je pense en utilisant la logique sur les ports pourrait fonctionner, mais je veux savoir si ma pensée est correcte. Supposons dans les deux cas ci-dessous que P2 a la valeur définie sur # 0A1h via la commande mov, et les broches de P2 sont toutes reliées à la masse.

Est-ce exact ?:

anl P2,#F8h ;value of P2 = #0A1h AND #F8h = #0A0h 
orl P2,#F9h ;value of P2 = #0A0h OR #F9h = #0F9h 
anl P2,#F0h ;value of P2 = #0F9h AND #F0h = #0F0h 

Ou est-ce plus correct ?:

anl P2,#F8h ;value of P2 = #00h AND #F8h = #00h 
orl P2,#F9h ;value of P2 = #00h OR #F9h = #0F9h 
anl P2,#F0h ;value of P2 = #00h AND #F0h = #00h 

Dans le deuxième exemple que j'ai commencé les équations aveC# parce que c'est la 00h valeur P2 produirait si je MOV A, P2 et ensuite voulu la valeur pour A, mais je ne suis pas sûr si cette valeur sera utilisée dans les calculs anl et orl.

Donc globalement, ma question est, puis-je utiliser anl et orl pour modifier seulement certains bits d'un port sans perturber le reste des bits? ou suis-je coincé avec l'utilisation de commandes de manipulation de bits comme setb et clr?

Répondre

1

Tout d'abord, je veux ajouter l'aspect suivant. L'approche impliquant des instructions SETB et CLR nécessitera plus de cycles machine à exécuter, et pourrait être irréalisable dans certains cas (par exemple génération d'horloge, problèmes de synchronisation).

Les ports 8051 sont plutôt primitifs par rapport aux MCU contemporains. Le 'port' a un verrou qui stocke l'état de broche et ce verrou essaye de conditionner la sortie. Cela ne signifie pas nécessairement que le port est à l'état souhaité. Par exemple, si elle est entraînée bas à l'extérieur, le verrou peut être haut mais le port sera bas. C'est exactement comme cela que nous définissons un port comme une entrée.

Lorsque nous déplaçons des données vers un port, nous écrivons dans le verrou, lorsque nous passons du port dans un registre, nous lisons l'état réel quel que soit l'état du verrou. Les opérations de lecture-modification-écriture sont une exception à cela, car elles lisent spécifiquement le verrou, effectuent l'opération souhaitée et réécrivent dans le verrou. Par conséquent, le scénario donné sous "Est-ce correct ?:" est le bon. Si à la place, nous étions à MOV A, P2 et ensuite exécuter P2 P2, # F8h "Ou est-ce plus correct ?:" serait correct. En conséquence, nous pouvons utiliser des opérations logiques pour modifier les ports pour les cas donnés dans cette question.

+0

Je devrais alors être mieux d'utiliser cette approche de codage si je mets ma valeur personnalisée dans le grignotage élevé de R7 et que je veux le faire comme le grignotage élevé de sortie réelle du port 2 tout en laissant le grignotage inférieur du port 2 inchangé: R7, # 70h MOV A, P2 ANL A, # 0Fh ORL A, R7 MOV P2, A'. Suis-je sur la bonne voie? – Mike