1. Este site usa cookies. Ao continuar a usar este site está a concordar com o nosso uso de cookies. Saber Mais.

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

Discussão em 'Programação' iniciada por Neojag, 2 de Abril de 2008. (Respostas: 9; Visualizações: 1064)

  1. Neojag

    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!
     
  2. Baderous

    Baderous Banido

    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: 2 de Abril de 2008
  3. Neojag

    Neojag Power Member

    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
     
  4. samouco

    samouco Power Member

    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
     
  5. Neojag

    Neojag Power Member

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

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

    Baderous Banido

    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.
     
  7. Neojag

    Neojag Power Member

    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?
     
  8. Baderous

    Baderous Banido

    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.
     
  9. ScOrpion-boy

    ScOrpion-boy Banido

    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: 2 de Abril de 2008
  10. Neojag

    Neojag Power Member

    Era mesmo isso que eu precisava.
    Obrigadíssimo :D
     
    Última edição: 3 de Abril de 2008

Partilhar esta Página