2012-11-02 14 views
5

Voglio manipolare alcuni bit di un registro direttamente utilizzando il suo indirizzo fisico. Tuttavia non sono riuscito a trovare un modo per farlo. Ho visto alcuni post sull'impostazione delle maschere di bit, ma le trovo troppo confuse.Come modificare un bit di registro a 32 bit specifici senza modificare altri bit?

miei registri indirizzo fisico è: 0x4A10005C

voglio di manipolare la sua parte, che era tra i 18-16 bit. Voglio impostare 0x3 all'interno di quei bit.

Sarò davvero felice se voi ragazzi potete fornire una risposta o un modo per farlo. Grazie.

+0

senza capire come funzionano le operazioni bit e cose come le maschere di bit potrebbe essere davvero difficile manipolare i bit ... – codewarrior

+0

Che cosa ti confonde le maschere di bit? – Mike

+0

Vi sono 2 modi per accedere alle informazioni a livello di bit Operatori BITWISE e Struttura bit a bit in c –

risposta

5

Si può solo definire un puntatore al registro e quindi utilizzare le normali operazioni di C bit per bit di manipolare i singoli bit:

volatile uint32_t * const my_register = (uint32_t *) 0x4A10005C; 
           // set up a pointer to the register 

uint32_t val = *my_register; // read register 

val &= ~(0x7 << 16);   // clear bits 16..18 

val |= (0x3 << 16);   // set bits 16..18 to 0x03 (i.e. set bits 16 and 17) 

*my_register = val;   // write register 

(È possibile che questo presuppone che si sta parlando di tre bit all'interno del registro, bit 16 , 17 e 18, e che si desidera impostare il bit 18 a zero e bit 16 e 17 a 1.)

+1

Si dovrebbe anche cancellare quei bit con '& ~ (maschera)' altrimenti non funzionerà sempre eccetto per tutti i bit-set-a-uno valori come '0x7'. Quello che ha 18 è stato '1'? –

+0

@Hristo: grazie - penso che potresti aver perso la mia modifica precedente. –

+0

Sì, era come una condizione di competizione dei dati :) –

0
structure r32 { 
unsigned int bit0 :1; 
unsigned int bit1 :1; 
unsigned int bit2 :1; 
unsigned int bit3 :1; 
unsigned int bit4 :1; 
unsigned int bit5 :1; 
. 
. 
. 
unsigned int bit31 :1; 
} 

nel vostro principale

structure r32 *p; 
volatile uint32_t * const my_register = (uint32_t *) 0x4A10005C; 

p = (structure r32 *) my_register; 

e poi per accedere al bit 5 per esempio

p->bit4 = 0; 
+1

Anche se questo può funzionare nella maggior parte dei casi (supponendo che l'ordine dei bit sia corretto, che potrebbe non essere), non ci sono garanzie circa l'ordine o il posizionamento dei campi di bit in C. –

5

bit maschere sono abbastanza facili da capire in modo Corriamo attraverso quel primo:

diciamo vostro registro a 32 bit contiene un certo valore in questo momento io arbitrariamente scegliere 0xF48C6219

presumo di sapere come convertire esadecimale a binario, se non ... diciamo solo che usare una calcolatrice o Google (piuttosto che andare nella parte fondamentale di quel troppo). Così il nostro valore esadecimale può essere rappresentato in binario come:

+-- bit 31       +-- bit 0 
|          | 
v          v 
1111 0100 1000 1100 0110 0010 0001 1001 
       ^^      
       | | 
       +-+-- bits you want to set, 16-18 

logica booleana ci dice che:
1) nulla in OR (|) con 1 si dà un valore di 1. O "imposta" il bit.
2) qualsiasi cosa AND'd (&) con 0 fornisce un valore di 0. O "cancella" il bit.

Quindi, se volessimo cancellare i bit 16-18 è possibile e con una maschera come: numero

di base: 1111 0100 1000 1100 0110 0010 0001 1001 == 0xF48C6219
maschera numero: 1111 1111 1111 1000 1111 1111 1111 1111 == 0xFFF8FFF

1111 0100 1000 1100 0110 0010 0001 1001 
& 1111 1111 1111 1000 1111 1111 1111 1111 
------------------------------------------ 
    1111 0100 1000 1000 0110 0010 0001 1001 

Ora lattina o con qualsiasi cosa si vuole impostare lì:

nuovo numero di maschera: 0000 0000 0000 0011 0000 0000 0000 0000 == 0x00030000

1111 0100 1000 1000 0110 0010 0001 1001 
| 0000 0000 0000 0011 0000 0000 0000 0000 
----------------------------------------- 
    1111 0100 1000 1011 0110 0010 0001 1001 

Così nel codice:

#define CLEAR_MASK 0x70000 //70000 is shorter to write, so just do this and flip it 
#define SET_3_MASK 0x30000 

volatile uint32_t * const reg = (uint32_t *) 0x4A10005C;//set a pointer to the register 
*reg &= ~CLEAR_MASK; //~ filps the bits 
*reg |= SET_3_MASK; 

È possibile eseguire trucchi con i bit di spostamento e così via, ma questa è la base delle maschere di bit e del loro funzionamento. Spero che sia d'aiuto.

+0

grazie per i commenti e le relative spiegazioni. mi aiuterà molto in ulteriori sviluppi. – denizt

+0

Nice Formatting Mike. :) – Whoami

0

Mi capita sempre di fare riferimento a this website mentre eseguo il bit che sta giocando.

+0

La risposta solo per collegamento è [non una buona risposta] (https://meta.stackexchange.com/q/8231/230282) –

Problemi correlati