Comecei a ler o guia de programação para comunicar com os módulos e tenho algumas duvidas.
#define DDR_IN 0
#define DDR_OUT 1
#define PORT_SEL PORTB
#define PIN_SEL PINB
#define DDR_SEL DDRB
(...)
Suponho que tenha a ver com configuraçõs do SPI mas para que é que ele faz varias vezes PORT_SEL, PORT SDO, PORT_SDI e lhes atribui PORTb?
É como estares a dizer que o pino SEL está no porto X, o pino SDO está no porto Y, etc. Por acaso, neste caso, todos estes pinos são no mesmo porto (PORTB), mas podia não ser. Desta forma, usando as constantes, podes facilmente mudar a localização de um pino, alterando apenas a respectiva constante e deixando o resto do código inalterado.
Ou por exemplo isto: #define SEL_OUTPUT() DDR_SEL |= (1<<RFXX_SEL)
#define HI_SEL() PORT_SEL|= (1<<RFXX_SEL)
#define LOW_SEL() PORT_SEL&=~(1<<RFXX_SEL)
#define SDI_OUTPUT() DDR_SDI |= (1<<RFXX_SDI)
#define HI_SDI() PORT_SDI|= (1<<RFXX_SDI)
#define LOW_SDI() PORT_SDI&=~(1<<RFXX_SDI)
o que faz?
Constantes como por exemplo RFXX_SEL têm o nº (ou indice) do bit. Quando fazes 1 << RFXX_SEL estás a criar uma "máscara" (um valor) em que apenas o bit índice RFXX_SEL activo (= 1). Por exemplo, se RFXX_SEL for 2 (que por acaso
até é), 1 << RFXX_SEL = 1 << 2 = 100b (em binário) = 4 (decimal).
As macros que têm o pipe | (ou-lógico bit-a-bit) estão a colocar no registo respectivo um bit a 1, as que usam o & (e-lógico bit-a-bit) estão a zerar um bit.
Examplos:
#define DDR_SEL DDRB // o registo DDRB define se cada bit do porto B é um input ou output
#define RFXX_SEL 2
#define SEL_OUTPUT() DDR_SEL |= (1<<RFXX_SEL)
SEL_OUTPUT() -> coloca a 1 o bit índice 2 do registo DDRB
Como? Vamos ver os passos que dá o compilador na interpretação do código:
SEL_OUTPUT()
DDR_SEL |= (1 << RFXX_SEL)
DDRB = DDRB | (1 << RFXX_SEL)
DDRB = DDRB | (1 << 2)
DDRB = DDRB | 4
DDRB = DDRB | 100b (note-se o "b" que indica que o nº esta no formato binário)
Portanto, fazendo um OR (OU) do registo DDRB com o valor 100b (binário) resulta sempre num valor em que o bit 2 fica a 1 e os restantes ficam inalterados.
No caso das macros com o & (AND, ou em pt, E), o que se faz é um AND com a máscara invertida. Isto resulta sempre em zerar o bit porque a máscara invertida é um valor em que todos os bits são 1 excepto o nosso bit de interesse (como o RFXX_SEL). Fazendo um AND com outro valor (neste caso, o valor do registo), resulta em que o nosso bit fica a zero e todos os outros ficam inalterados.
Tenho a certeza que a net tá cheia de tutoriais sobre isto, façam uma pesquisazita.