LusoRobótica - Robótica em Português
Software => Assembly => Tópico iniciado por: LuísR.A. em 12 de Março de 2013, 19:40
-
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...
-
Lê isto:
http://lusorobotica.com/index.php?topic=2838.msg29942#msg29942 (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
-
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
-
Pesquisa por bitwise operations.
https://www.google.pt/search?q=c+binary+operators&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a#hl=en&client=firefox-a&hs=4Bu&rls=org.mozilla:en-US%3Aofficial&sclient=psy-ab&q=c+bitwise+operators&oq=c+bitwise+operators&gs_l=serp.3..0l2j0i7j0.21892.24580.0.24713.10.9.1.0.0.1.183.1007.6j3.9.0.les%3B..0.0...1c.1.5.psy-ab.gvltT7SpWrg&pbx=1&bav=on.2,or.r_cp.r_qf.&bvm=bv.43287494,d.ZGU&fp=dfffdf54bf29c0c5&biw=1680&bih=910 (https://www.google.pt/search?q=c+binary+operators&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a#hl=en&client=firefox-a&hs=4Bu&rls=org.mozilla:en-US%3Aofficial&sclient=psy-ab&q=c+bitwise+operators&oq=c+bitwise+operators&gs_l=serp.3..0l2j0i7j0.21892.24580.0.24713.10.9.1.0.0.1.183.1007.6j3.9.0.les%3B..0.0...1c.1.5.psy-ab.gvltT7SpWrg&pbx=1&bav=on.2,or.r_cp.r_qf.&bvm=bv.43287494,d.ZGU&fp=dfffdf54bf29c0c5&biw=1680&bih=910)
-
if (P1IN|=0x08){
é quase igual a
P1IN = P1IN | 0x08;
if (P1IN != 0) {
:)
-
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
-
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 ]
-
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
-
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 )
-
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.
-
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
-
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?
-
Já agora, isto não tem a ver especificamente com Assembly, é melhor mudar este tópico para "Software e Programação".
-
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?
-
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 )
-
Só me refiro a esta frase que escreveste:
O ^ significa XOR ( Ou Exclusivo ) por isso se antes estiver 1 passa a 0 e vice versa.
Dizer que "se antes estiver a 1 passa a 0 e vice-versa" não diz o que realmente faz o xor, parece que estás a descrever a negação.
-
Dizer que "se antes estiver a 1 passa a 0 e vice-versa" não diz o que realmente faz o xor, parece que estás a descrever a negação.
Ok got it, mas:
A XOR 1 = NOT A
A | A XOR 1 | NOT A
0 1 1
1 0 0
8)
-
Nunca disse o contrário :)
-
O xor dá para fazer coisas mt engraçadas :)