da
xyz » 5 nov 2012, 20:41
belva87 ha scritto:(1 << 6) che se non ho capito male mette a 1 il bit numero 6 del byte a cui sono interessato, giusto?
E' un numero con il bit 6 a uno e tutti gli altri a 0 e come dice [user]gohan[/user] hai anche sbagliato la sua rappresentazione esadecimale.
belva87 ha scritto:REGISTRO DI INTERESSE = (1 << BIT DI INTERESSE)
Cioè sposta il valore logico 1 dentro la posizione del bit di interesse... giusto?
No, non hai ancora capito, in quel caso se il registro è a 8 bit, scrivi tutti gli 8 bit non intervieni solo sul bit che vuoi impostare.
Devi usare l'operatore OR (è la base delle operazioni sui bit):
REGISTRO |= (1 << BIT DI INTERESSE)
equivale a:
REGISTRO = REGISTRO | (1 << BIT DI INTERESSE)
belva87 ha scritto:Facendo un esempio più preciso scrivere: PORTA = (1 << PINA0); fa scorrere 1 fino alla posizione del bit PINA0, facente parte del registro a 8 bit che si chiama PORTA.
Non fai scorrere nulla è una semplice assegnazione.
belva87 ha scritto:Ditemi se sto prendendo cantonate per favore...
Non sai manipolare le operazioni booleane tra i bit.
Facciamo un esempio concreto.
Il compilatore GCC è in grado di capire quando utilizzare le istruzioni assembler per impostare un unico bit, molto veloci, oppure utilizzare un registro intermedio per calcolare il valore da scrivere nel registro.
Codice in C senza uso di nessuna macro o funzione:
- Codice: Seleziona tutto
#define __AVR_ATmega8__
#include <avr/io.h>
void main()
{
PORTB |= (1 << PIN4);
PORTB |= (1 << PIN6) | (1 << PIN3);
PORTD &= ~(1 << PIN2);
PORTD &= ~((1 << PIN7) | (1 << PIN6) | _BV(PIN5) | _BV(PIN6));
}
Compiliamo il sorgente con il GCC per AVR ma fermiamo la compilazione alla sola generazione del codice assembler:
- Codice: Seleziona tutto
$> avr-gcc -O2 -S source.c
il codice assembler generato con l'aggiunta nei commenti le righe in C:
- Codice: Seleziona tutto
// PORTB |= (1 << PIN4);
sbi 0x18,4
// PORTB |= (1 << PIN6) | (1 << PIN3);
in r24,0x18
ori r24,lo8(72)
out 0x18,r24
// PORTD &= ~(1 << PIN2);
cbi 0x12,2
// PORTD &= ~((1 << PIN7) | (1 << PIN6) | _BV(PIN5) | _BV(PIN6));
in r24,0x12
andi r24,lo8(31)
out 0x12,r24
Il compilatore sceglie ogni volta l'istruzione migliore visto che esiste l'istruzione per assegnare o cancellare un bit di un registro con una sola istruzione, altrimenti se i bit sono più di uno esegue l'operazione classica con OR per impostare i bit o AND per cancellare i bit.