2009-11-27 11 views
2

J'utilise un IC, DS1620 pour lire des données sérielles de 1 bit arrivant sur une seule ligne. J'ai besoin de lire ces données en utilisant l'un des ports du microcontrôleur ARM (LPC2378). Les ports ARM sont en 32 bits. Comment puis-je obtenir cette valeur dans une variable 1 bit?Comment tirer profit de la 15ème broche du port 32bit dans ARM?

Editer: En d'autres termes, j'ai besoin d'une référence directe à une broche de port.

Répondre

5

il n'y a pas 1 variables de bits, mais vous pouvez isoler un peu particulier par exemple:

uint32_t original_value = whatever(); 
uint32_t bit15 = (original_value >> 15) & 1; /*bit15 now contains either a 1 or a 0 representing the 15th bit */ 

Note: Je ne sais pas si vous compter le nombre de bits à partir de 0 ou 1, de sorte que le >> 15 peut être éteint par un, mais vous avez l'idée.

L'autre option est d'utiliser des champs de bits, mais qui devient malpropre et l'OMI ne vaut pas à moins que chaque bit de la valeur est utile d'une certaine façon. Si vous voulez juste un ou deux bits, le déplacement et le masquage est la voie à suivre. Dans l'ensemble, ce article peut vous être utile.

+1

Une autre question - Comment obtenir microcontrôleur ARM valeur du port dans une variable de 32 bits dans la première place? –

+0

bien c'est quelque chose qui est spécifique au processeur. Un x86 utiliserait un assemblage ou un compilateur intrinsèque pour exécuter une instruction 'in' ou' out' pour lire et écrire des ports d'E/S. –

+0

Sur un ARM, le port d'E/S est probablement juste mappé à un emplacement de mémoire particulier - "registres mappés en mémoire". Bonne lecture des manuels du LPC2378. Il existe probablement un fichier d'en-tête C qui fournit des noms pour tous ces registres. –

1

Il est simple si vous pouvez accéder au registre du port directement (je n'ai pas d'expérience avec ARM), juste au niveau du bit avec le masque binaire qui correspond au bit que vous voulez:

var = (PORT_REGISTER & 0x00008000); 

maintenant var contient soit 0 si le 15ème bit est '0' ou 0x00008000 si le 15ème bit est '1'.

En outre, vous pouvez changer si vous voulez avoir « 0 » ou « 1 »:

var = ((PORT_REGISTER & 0x00008000) >> 15); 
+1

Une forme plus lisible de 0x00008000 est '(1 << 15)' que l'assembleur ou le compilateur calculera pendant le temps de traduction, pas pendant l'exécution. –

0

Le fichier d'en-tête (s) qui viennent avec votre compilateur contient des déclarations pour tous de microcontrôleur registres, et les bits dans ces registres.

Dans cet article spécifique, supposons que le registre d'entrée de port est appelé PORTA, et le bit que vous voulez a un masque défini pour lui appelé PORTA15.

ensuite de lire l'état de cette broche:

PinIsSet = (PORTA & PORTA15) == PORTA15; 

ou de manière équivalente, en utilisant le ternary operator:

PinIsSet = (PORTA & PORTA15) ? 1 : 0; 

En tant que point de vue général, reportez-vous au manuel de référence pour ce que tous les registres et bits font. Aussi, regardez quelques exemples. (This page on the Keil website contient les deux, et il y a beaucoup d'autres exemples sur le web.)

0

En LPC2378 (comme l'autre famille de microcontrôleurs LPC2xxxx), ports E/S sont dans la mémoire système, vous devez donc déclarer certaines variables comme ceci:

#define DALLAS_PIN (*(volatile unsigned long int *)(0xE0028000)) /* Port 0 data register */ 
#define DALLAS_DDR (*(volatile unsigned long int *)(0xE0028008)) /* Port 0 data direction reg */ 
#define DALLAS_PIN (1<<15) 

S'il vous plaît noter que 0xE0028000 est l'adresse le registre de données de port0 et 0xE0028008 est l'adresse de registre de direction de données pour port0. Vous devez modifier cela en fonction du port et du bit utilisé dans votre application. Après cela, dans votre fonction de code, le code ou des macros pour écrire 1, écrire 0 et lire doit être quelque chose comme ceci:

#define set_dqout() (DALLAS_DDR&=~DALLAS_PIN) /* Let the pull-up force one, putting I/O pin in input mode */ 
#define reset_dqout() (DALLAS_DDR|=DALLAS_PIN,DALLAS_PORT&=~DALLAS_PIN) /* force zero putting the I/O in output mode and writing zero on it */ 
#define read_dqin() (DALLAS_DDR&=~DALLAS_PIN,((DALLAS_PORT & DALLAS_PIN)!= 0)) /* put i/o in input mode and test the state of the i/o pin */ 

J'espère que cela peut aider.

Cordialement!

0

Si vous testez des bits, il est bon de garder à l'esprit l'ordre d'évaluation de l'opérateur C, par ex.

if(port & 0x80 && whatever()) 

peut entraîner un comportement inattendu, que vous venez d'écrire

if(port & (0x80 && whatever())) 

mais ment probablement

if((port & 0x80) && whatever())