• Welcome to LusoRobótica - Robótica em Português.
 

pergunta muito simples: operações

Started by LuísR.A., 12 de March de 2013, 19:40

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

LuísR.A.

primeiro de tudo, se isto não se chamam operações corrijam-me  :P

o meu maior problema com programação, agora que tento aprender a programar no Code Composer, é as operações (|=, ^=,=~, etc...)
a maior parte delas chego la mas há uma que não me faz sentido.

é esta:

(P1IN & 0x08) == 0x08 )

isto vem de: if (P1IN & 0x08) == 0x08 ) {

não entendo porque não é exatamente igual a: if (P1IN|=0x08){
não seria "se o byte P1IN fosse xxxx1xxx, então...

Tiva MCU é que é.

Tutoriais Tiva+codigos exemplo:
https://sites.google.com/site/luiselectronicprojects/

senso

Lê isto:
http://lusorobotica.com/index.php?topic=2838.msg29942#msg29942

O que estás a fazer é aplicar uma máscara em cima da leitura dos pinos, para isolar um valor, e ver se esse valor é um, existem várias maneiras de o fazer, nesse caso é mais facil passar para binário:

(P1IN & 0x08) == 0x08 )

isto vem de: if (P1IN & 0x08) == 0x08 ) {

0x08 = 0b00001000
Ao fazeres o AND(&) todos os valores sem ser o quarto(bit3) são colocados a zero, a isso chama-se uma máscara, depois comparas para ver se o seu valor é 1
Avr fanboy

LuísR.A.

#2
então "limpo" o byte todo sem alterar o bit3 ao fazer (P1IN & 0x08). P1IN é o registo e a seguir ao AND(&) escolho que bites que não quero tocar, que neste caso é so um (mesmo sem lado pratico isolar mais que 1 bit é so para entender).
e como todos os bytes estão a zero e o bit3 a variar é possivel fazer uma leitura apenas desse bit. as leituras possiveis serão 0000 1000 ou
0000 0000.

vou ver esse link

edit:
a máscara não altera realmente o registo P1IN certo?
apenas criar um resultado (P1IN & 0x08) e compara neste caso com 0x08?

pelo que percebi no teu tutorial, qualquer que seja os valores em P1IN o resultado é sempre igual a 0x08 ou 0. (agora queria meter o raciocinio mas acho que está certo e dá muito trabalho)  :P

parece muito bom o tutorial. é ja a leitura das férias. bom trabalho nesse  :D
Tiva MCU é que é.

Tutoriais Tiva+codigos exemplo:
https://sites.google.com/site/luiselectronicprojects/


Njay

#4
if (P1IN|=0x08){

é quase igual a

P1IN = P1IN | 0x08;
if (P1IN != 0) {


:)

LuísR.A.

Quote from: Njay on 13 de March de 2013, 04:22
if (P1IN|=0x08){

é quase igual a

P1IN = P1IN | 0x08;
if (P1IN != 0) {


:)


O "P1IN=P1IN | 0x08;" não dá sempre P1IN=xxx1 xxxx ? nunca dá bit3=0 pois não? isso explicava porque nunca saia do "if"  :P
Tiva MCU é que é.

Tutoriais Tiva+codigos exemplo:
https://sites.google.com/site/luiselectronicprojects/

Njay

#6
Quote from: LuísR.A. on 13 de March de 2013, 09:31
Quote from: Njay on 13 de March de 2013, 04:22
if (P1IN|=0x08){

é quase igual a

P1IN = P1IN | 0x08;
if (P1IN != 0) {


:)

O "P1IN=P1IN | 0x08;" não dá sempre P1IN=xxx1 xxxx ?
Njay: Njay: Dá!

nunca dá bit3=0 pois não?
Njay: Claro que não! O "ou" que tás a fazer é coloca o bit3 sempre a 1!

isso explicava porque nunca saia do "if"  :P
Njay: Como o resultado é sempre 1 (em C/C++ qualquer número diferente de zero é "true" e zero é "false"), a execução entra sempre no if.


O teu if (P1IN|=0x08){ é uma coisa "perigosa" do ponto de vista de programação, porque estás a fazer uma atribuição (P1IN = P1IN | 0x08;) na condição do if. Para quem tem pouca experiência é "lenha para se queimar", pois é preciso perceber as verdadeiras implicações disto; em geral os compiladores dão avisos acerca disto (que tu deves ter visto mas como não entendeste e ele compilou à mesma, ignoraste ;)). Regra geral: não usar atribuições na condição do if!!! Se calhar o que querias fazer era saber se o bit3 está activo ou não, e isso faz-se por exemplo assim:

(...)
[ ver correcção num post mais à frente ]

LuísR.A.

#7
epa estou confuso  ;D

vou ter de ler isso tudo e pesquisar melhor. hoje estou bue ao relentinho

vou tentar ver se percebi mas sou mesmo verde nisto:


o  if (P1IN | 0x08 != 0) { não se verifica sempre?
porque o resultado de (P1IN | 0x08) não deverá dar P1IN que "entrou" na conta com a excepção do bit3 que é sempre igual a 1 no resultado? logo o resultado nunca é 0

e neste: if (P1IN | 0x08 == 0x08) {
se algum dos bits for 1, com a exceção/excepção (credo como se escrever agora?) do bit3,  o resultado não será sempre diferente de 0x08?
por exemplo. 0000 1000|0001 0000 = 0001 1000, que é diferente de 0x08

neste: if (P1IN | 0x08) {
independentemente do valor de P1IN como é uma operação "ou" com 0x08, o resultado será no minimo 0x08 que é sempre !=0
logo esta condição é sempre verificada?


os outros tenho de ver melhor que ainda não vi bem os "sifth" ou que é. os "<<"



ja agora. obrigado pela aula hehe  :D
Tiva MCU é que é.

Tutoriais Tiva+codigos exemplo:
https://sites.google.com/site/luiselectronicprojects/

andElectrons

Quote from: LuísR.A. on 13 de March de 2013, 20:25
os outros tenho de ver melhor que ainda não vi bem os "sifth" ou que é. os "<<"

shift left é facil perceber

1 << 0 = 00000001b = 001d = 01h
1 << 1 = 00000010b = 002d = 02h
1 << 2 = 00000100b = 004d = 04h
1 << 3 = 00001000b = 008d = 08h
1 << 4 = 00010000b = 016d = 10h
1 << 5 = 00100000b = 032d = 20h
1 << 6 = 01000000b = 064d = 40h
1 << 7 = 10000000b = 128d = 80h

dito isto podes fazer:

( 1 << 2 ) | ( 1 << 1 ) | ( 1 << 0 )  = 4d + 2d + 1d = 7d

imagina que tens a variável/port/etc PIN1

se quiseres ligar o bit 3 fazes:

PIN1 |= (1 << 3);

para desligar o bit 3:

PIN1 &= ~(1 << 3);

para fazer togle ao bit 3 ( ligar se ligado, desligar se ligado ):

PIN1 ^= (1 << 3)


O ~ significa negação por isso ~(1<<3) é o mesmo que 11110111b

O ^ significa XOR ( Ou Exclusivo ) por isso se antes estiver 1 passa a 0 e vice versa.


É claro que dá para fazer combinações por isso, para ligar por exemplo bit 2 e 4 seria

PIN1 |= (1 << 2) + (1 << 4);

ou

PIN1 |= (1 << 2) + (1 << 4);


repara que cada shift left é uma multiplicação por 2 elevado a 0, 1, 2, 4, 5, 6 e 7

por exemplo 1 << 0 é igual 1 x 2 elevado a 0 ( 2 elevado a 0 é 1 por isso 1 x 1 = 1, 1 << 0 = 1 )



Njay

#9
Oh Luis, tens toda a razão em estar confuso, desculpa lá eu é que fiz aí uma baita confusão. Com a história dos "ou" ("|") desatei a meter | em todo o lado mas tá mal. Para verificar se um bit está 1 temos que usar é o "e" (and) lógico e não o "ou". O mais estranho é que quando escrevi o post ainda nem tinha bebido nada :) (na verdade só curto água e sumos).
Sendo assim, deixa-me re-formular, só muda a operação lógica:

---------------------------
Se calhar o que querias fazer era saber se o bit3 está activo ou não, e isso faz-se por exemplo assim:

  if (P1IN & 0x08 == 0x08) {

Como o "ou" lógico "isola" o valor do bit3, o resultado de P1IN | 0x08 é 0 ou 0x08. Outra forma que vai dar no mesmo é

  if (P1IN & 0x08 != 0) {

ou ainda

  if (P1IN & 0x08) {    (lembrar que qq coisa diferente de zero é "true" e zero é "false")

ou mesmo ainda, porque fica mais fácil de ler e é mais explicito acerca do que se quer fazer:

  if (P1IN & (1 << 3)) {

Mas melhor até agora é (e se trabalhasses para mim era no minimo como tinhas que fazer :) ):

  enum {
      eXptoEnabled = 1 << 3,
  } EP1InputPinMapping;
  ...

  if (P1IN & eXptoEnabled) {

---------------------------

Já agora, o "ou exclusivo" ("^") é igual ao "ou" mas quando ambos os bits dos operandos são 1 o resultado é zero (o que o Electrons escreveu descreve a negação :)). Portanto,
  0b^0b = 0b
  0b^1b = 1b
  1b^0b = 1b
  1b^1b = 0b
  0x08^0x08 = 0
  0101b ^ 1111b = 1010b
  etc.

LuísR.A.

Quote from: andElectrons on 13 de March de 2013, 22:13


1 << 0 = 00000001b = 001d = 01h
1 << 1 = 00000010b = 002d = 02h
1 << 2 = 00000100b = 004d = 04h
1 << 3 = 00001000b = 008d = 08h
1 << 4 = 00010000b = 016d = 10h
1 << 5 = 00100000b = 032d = 20h
1 << 6 = 01000000b = 064d = 40h
1 << 7 = 10000000b = 128d = 80h

dito isto podes fazer:

( 1 << 2 ) | ( 1 << 1 ) | ( 1 << 0 )  = 4d + 2d + 1d = 7d


isso de 128d, 7d e 80h são que números?
com isto dos operadores é que comecei a aprender hexadecimal e binario por isso tb é algo novo para mim  :P
Tiva MCU é que é.

Tutoriais Tiva+codigos exemplo:
https://sites.google.com/site/luiselectronicprojects/

andElectrons

Quote from: LuísR.A. on 14 de March de 2013, 11:26
isso de 128d, 7d e 80h são que números?
com isto dos operadores é que comecei a aprender hexadecimal e binario por isso tb é algo novo para mim  :P

com d significa decimal e h hexadecimal

pensava q estava a ajudar pondo os valores em hexadecimal mas afinal confundi-te mais


percebes agora?

Njay

Já agora, isto não tem a ver especificamente com Assembly, é melhor mudar este tópico para "Software e Programação".

LuísR.A.

ja entendi. ajudas-te assim se isso me aparecer ja sei.


meti aqui porque estava a trabalhar com C assembly e não sabia bem onde meter.
consigo eu mudar o local ou tem de ser um admin?
Tiva MCU é que é.

Tutoriais Tiva+codigos exemplo:
https://sites.google.com/site/luiselectronicprojects/

andElectrons

Quote from: Njay on 14 de March de 2013, 02:26
Já agora, o "ou exclusivo" ("^") é igual ao "ou" mas quando ambos os bits dos operandos são 1 o resultado é zero (o que o Electrons escreveu descreve a negação :)). Portanto,
  0b^0b = 0b
  0b^1b = 1b
  1b^0b = 1b
  1b^1b = 0b
  0x08^0x08 = 0
  0101b ^ 1111b = 1010b
  etc.


Pensa antes assim:

queres ligar se estiver desligado ou desligar se estiver ligado


Invés de teres de fazer isto:


if ( pin1 & 0x80 == 0x80 )
{
  pin1 &= ~0x80; // desliga
}
else
{
  pin1 |= 0x80 // liga
}


podes fazer unicamente:

pin1 ^= 0x80;


que é mais fácil de ler para o programador e mais MUITO + rápido de executar para o processador


é para isto que se usa o ^ ( XOR )