Atribuição de valores a variáveis em C

Neojag

Power Member
Já programo C para PCs há uns anos (se bem que os meus conhecimentos não são particularmente elevados). Entretanto comecei a programar para microcontroladores e deparo-me várias vezes com a necessidade de configurar apenas certos bits de um registo de 8 bits. Tenho utilizado uma sintaxe do tipo

meh &= 0xF0 //Limpa os últimos quatro bits e deixa os primeiros inalterados
meh |= 0x13 //Deixa os primeiros inalterados e configura os últimos quatro para 0011

Entretanto em código já feito tenho-me deparado com uma sintaxe que nunca vi (por exemplo, para ler os pinos de uma determinada porta de um ATMega). Do género:

btnState = ~PINB & (1<<3);
DDRB |= 1<<DDB4;

Alguém me pode explicar que diabo é que isto faz?
Obrigado!
 
btnState = ~PINB & (1<<3);
DDRB |= 1<<DDB4;

Os nomes PINB, DDRB e DDB4 suponho que sejam coisas próprias do ATMega.
Agora o resto:

~ => complemento de bits
& => E de bits
<< => deslocar 1 bit para a esquerda

btnState = ~PINB & (1<<3);

Isto guarda na variável btnState o resultado de:

1: 1<<3 = 1*2^3 = 8 (depois tens de meter em binário)
2: ~PINB = invertes os bits
3: faz o AND entre o resultado do ponto 1 e 2.

Penso que é isto.
 
Última edição:
Obrigado, já clarificaste alguma coisa.
Tenho ideia que isto é usado para ler pinos individuais (bits individuais de um determinado registo de 8 bits), mas ainda não consegui perceber exactamente como :S
 
meh |= 0x13 //Deixa os primeiros inalterados e configura os últimos quatro para 0011

Aqui estás engado...

0x13 = 00010011

e no OR bits a 0 mantem o valor existente os 1 altera

0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1

Logo no teu exemplo se meh = 00110101

meh |= 0x13 = 00110111


Espero ter sido esclarecedor

Cumps
samouco
 
Er, queria escrever 0 em vez de 1, enganei-me ;)

Ainda não percebi exactamente o efeito do << aí :S

Exemplo:

Tens um número em binário: 0001
Fazes: 0001<<1
E dá: 0010
Ou seja deslocaste um bit para a esquerda, o que corresponde a multiplicar por 2. Como neste caso o valor que estava à direita do sina << era 1, fizeste uma multiplicação por 2^1. Se tivesse 2, era 2^2.
 
Hum, estou a perceber. Então no caso btnState = ~PINB & (1<<3); ele inverte todos os bits de PINB e de seguida põe-nos todos a zero excepto o quarto, que fica o que está, certo?
 
Hum, estou a perceber. Então no caso btnState = ~PINB & (1<<3); ele inverte todos os bits de PINB e de seguida põe-nos todos a zero excepto o quarto, que fica o que está, certo?

O "meter todos a zero" eu não sei porque não sei o que significa o PINB, mas tudo depende do resultado de fazer & dos bits.
 
Uma explicação rápida, sem mtas teorias:

PORTC|=(1 << 4); coloca o pino 4 da porta C a 1 e não mexe nas outras

PORTC&=~(1 << 4); coloca o pino 4 da porta C a 0 e não mexe nas outras

que são as mais usadas :P


Basicamente é um método rápido de aplicar máscaras.

Assim o melhor tutorial que encotrei na net quando andava a estudar isto:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=37871

Por passos:
btnState = ~PINB & (1<<3);

Considerando:
PINB= 0b01110111
~PINB=0b10001000

0x01<<3 == 0b00001000 (faz-se shift left do valor 0b0000 0001, 3 casas)

0b10001000
&
0b00001000
=
0b00001000

Por palavras inverte-se o resultado obtido da porta B do micro, faz "set" do bit 3 do btnState se o pino 3 da porta B for 1;
 
Última edição:
Back
Topo